您的位置:首页 > Web前端 > JavaScript

编写良好javascript,css,html的方法技巧(持续更新……)

2015-08-06 13:35 686 查看
在平时的网站开发过程中,常常会不经意get到一些编写代码的小方法和小技巧,在此整理收录,方便查阅,内容持续更新,主要分为javascript,css,html部分欢迎收藏

Javascript编写技巧

1.注意标识符提升陷阱

var a = 1;
function fn() {
if (!a) {
var a = 2;//2
}
console.log(a);
}
fn();


var a = 1;
function fn() {
a = 2;
return;
function a() {}
}
fn();
console.log(a); //1


var a = "1";
function fn() {
var b = a;
var a = "2";
var c = a;
function a() {}
console.log(b); //function a();
console.log(c); //2
}
fn();
console.log(a); //1


通过上面三个例子可以感受到,js不存在块级变量(除了es6的let外),变量的定义会提前,不存在块级变量,如var,function的等对象的定义,定义都会被提升到首位执行。

2.特性检测而非浏览器检测

一般来说基于用户客户端执行不同动作的判断不应该是通过判断浏览器版本来实现,我们一般是通过一些特性检测的方式来实现,如JQ源码中的on/bind等绑定方法的实现便是通过
addEventListener/attachEvent
的特性检测来实现的

if ( elem.addEventListener ){
elem.addEventListener( type, eventHandle, false );
}


3.使用!!和+进行类型转换

javascript是一门弱类型的语言,通常我们在编写javascript代码时往往会用到许多类型转换的东西,对于string,number等基础类型,==和===是有区别的,对于Array,Object等高级类型,==和===是没有区别的,这时我们就可以通过javascript的类型转换技巧来实现判断

var str="100",num=100;
console.log(str===num);//false
console.log((+str)===num);//true
console.log(typeof(+str));//number +可以把字符串转化为number型
console.log(typeof(!!str))//boolea !!可以将任一个对象转化为boolea型


4.“[ ]“方括号记法

如果使用”.”号,属性名是硬代码,不能在执行时改变。如果使用”[ ]“方括号,属性名是一个通过计算属性名而来的字符串。 如果你有 “value1″, “value2″, 和 “value3″这样的属性,你可以通过定义一个变量i=1来动态访问你需要的属性,只需

MyObject["value"+i]


5.避免 ‘eval’

eval()功能是一个在执行期中执行任意代码的方法,因此在执行环境中会改变作用域(jshint中不建议使用)

改变局部作用域

var foo = 1;
function test() {
var foo = 2;
eval('foo = 3');
return foo;
}
console.log(test()); // 3
console.log(foo); // 1


改变全局作用域

var foo = 1;
function test() {
var foo = 2;
window.eval('foo = 3');
return foo;
}
console.log(test()); // 2
console.log(foo); // 3


eval可以用来解析json数据(一般使用JSON.parse),如

eval("(" + json + ")");


eval存在安全问题,因为它可以执行传给它的任何字符串,所以永远不要传入字符串或者来历不明和不受信任源的参数。

6.避免 ‘with’

Javascript 中的 with 通常作为一个延长作用域链的方法,作用就是就是引用对象,并对该对象上的属性进行操作,其作用是可以省略重复书写该对象名称,起到简化书写的作用。

* with代码块中,javascript引擎对变量的处理方式是:先查找是不是该对象的属性,如果是,则停止。如果不是继续查找是不是局部变量。

* 就算在with语句中使用 var 运算符重新定义变量(该变量是with引用对象的属性),如果该属性是可写属性,那么也会给对象的属性赋值。

* 如果你想通过with语句,对引用对象添加多个属性,并为每个属性赋值,这是不可能的!也就是说,要赋值的只能是对象已经存在并且可以写入的属性(不能是只读属性)。

通过下面的两个例子可以感受一下

var o={href:"sssss"};
var href="1111";
function buildUrl(){
var qs="?";
with(o){
href="2222";
var url=href+qs;
}
retu
4000
rn url;
}
var result=buildUrl();
console.log(result);//2222?
console.log(href);//1111


var o={};
var href="1111";
function buildUrl(){
var qs="?";
with(o){
href="2222";
var url=href+qs;
}
return url;
}
var result=buildUrl();
console.log(result);//2222?
console.log(href);//2222


为啥要避免呢~主要是容易造成作用域链混乱,毕竟javascript中本来就没有块级作用域的定义,故容易造成一些问题。

7.避免乱用全局命名空间

一般很少需要全部变量和函数。全局使用将可能导致 Javascript 源文件文档冲突,和代码中止。因此,一个好的做法是在一个全局命名空间内采用函数性的封装。

如通过闭包定义:

var NameSpace = window.NameSpace || {};
NameSpace.Hello = (function() {
var name = 'world';
var sayHello = function(_name) {
return 'Hello ' + (_name || name);
};
return {
sayHello: sayHello
};
}());


不通过闭包:

var NameSpace = window.NameSpace || {};
NameSpace.Hello = new function() {
var self = this;
var name = 'world';
self.sayHello = function(_name) {
return 'Hello ' + (_name || name);
};
};


8.获取浏览器版本信息判断移动端版本信息

var browser={
versions:function(){
var u = navigator.userAgent, app = navigator.appVersion;
return {//移动终端浏览器版本信息
trident: u.indexOf('Trident') > -1, //IE内核
presto: u.indexOf('Presto') > -1, //opera内核
webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐内核
mobile: !!u.match(/AppleWebKit.*Mobile.*/)||!!u.match(/AppleWebKit/), //是否为移动终端
ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端
android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android终端或者uc浏览器
iPhone: u.indexOf('iPhone') > -1 || u.indexOf('Mac') > -1, //是否为iPhone或者QQHD浏览器
iPad: u.indexOf('iPad') > -1, //是否iPad
webApp: u.indexOf('Safari') == -1 //是否web应该程序,没有头部与底部
};
}(),
language:(navigator.browserLanguage || navigator.language).toLowerCase()
}


9.使用局部变量缓存变化的值或者全局变量

//差的实践
var query = window.location.href.substring(window.location.href.indexOf("?"));
//最佳实践
var url = window.location.href;
var query = url.substring(url.indexOf("?"));


历遍元素时

//差的实践
for(var i=0;i<data.length;i++){
visit(data[i]);
}
//最佳实践
for(var i=data.length;i>0;i--){
visit(data[i]);
}


10.操作页面DOM结构操作大量元素时,尽量用innerHTML,而不要用createElement()和appendChild()

字符串拼接比每次dom操作资源消耗低并且使用innerHTML,会创建一个HTML解析器,然后使用内部的DOM调用来创建DOM结构而不是使用js内部的dom结构操作,效率更佳

11.减少重排、重绘优化性能

浏览器下载完页面中的所有组件—-HTML标记,Js,CSS,图片等之后会解析并生成两个内部数据结构:

DOM树 ——– 表示页面结构

渲染树 ——– 表示DOM节点如何显示

当DOM的变化影响了元素的几何属性(宽和高),浏览器需要重新计算元素的几何属性,同样其他元素的几何属性和位置也会因此受到影响。

重排:浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。

重绘:完成重排后,浏览器会重新绘制受影响的部分到屏幕中。

重排何时发生:

添加或删除可见的DOM元素

元素位置的改变

元素尺寸改变

内容改变

页面渲染器初始化

浏览器窗口尺寸的改变

有效避免过多的重排能提高页面性能和用户体验

技巧1:平时我们在用js对DOM进行操作时,常常会遇到要操作页面样式的情况,很多新手程序员常常喜欢在操作样式时直接对元素某一个样式进行修改,如在JQuery中使用
.css()
的语法修改样式,这样往往会引起页面的多次重排,有的浏览器进行了优化,在一般不会立即执行这些结果,会等到足够多的dom操作,或者一定时间之后再一起处理重排,但这样做还会是造成程序的高耦合,所以一般应该采用添加样式的方式来改变页面样式提高性能。

技巧2:在对某些需要操作大量DOM的节点先隐藏后进行操作,操作完再显示出来,这样发生的重排次数只会是两次

技巧3:每次获取offsettop、offsetleft、offsetwidth,srcolltop、clientleft等一些属性,浏览器都要重排(为了精确定位元素位置),遇到需要重复用到的值可以用局部变量缓存起来,减少这些属性的获取也是优化性能的一个好的实践

12.function表达式和function语句的区别

观察如下的两段代码

var a=10;
console.log(a);//10
function a1(){
a=2;
}
a1();
console.log(a);//4
function a1(){
a=4;
}
a1();
console.log(a);//4


var a=10;
console.log(a);//10
var a1=function(){
a=2;
}
a1();
console.log(a);//2
var a1=function(){
a=4;
}
a1();
console.log(a);//4


javascript语言中的function语句在解析时会发生被提升的情况。这意味着不管function被放置在哪里,它都会被移动到被定义时所在的作用域顶层,这放宽了函数必须先声明后使用的要求,但这将会导致混乱。在if语句中使 function语句也是被禁止的。结果表明大多数浏览器都允许在if语句里使用function语句,但它们在解析时的处理上各不相同,这就造成了移植性问题。因此我们推荐使用var表达式犹豫声明方式创建函数。

CSS编写技巧

1.掌握Sass或者Less来开发你网页的css样式

sass和less引入了css编程的概念,学会他们能大大加快你css编写的速度以及可靠性

sass学习地址

less学习地址

2.引入CSS reset(CSS 重设)

CSS reset的优势是避免了浏览器的不兼容,并且能对你网页上的dom元素样式进行初始化,让你能够随心所欲的使用各类标签而不必担心默认样式问题,可以到网上搜阅别人写好的reset函数,当然也可以自己定义

例如:

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}


3.CSS网格布局以及flex布局

尽管兼容性相对较差,但对于开发快速原型以及对兼容性要求不高的产品开发效率是杠杠的

CSS Grid 介绍

CSS Flex 介绍

4.巧妙利用checkbox和radio的checked属性

css的伪元素操作是网页开发的一个利器,巧妙利用不仅能加快网页开发速度,而且经常能把一些复杂的功能简单化,像下面这个例子便是利用了伪元素做的一个动画开关

See the Pen doezLX by Simplefatty (@Dreaking) on CodePen.

5.避免css样式的嵌套地狱

我们平时在书写css代码的时候有时为了选择某个dom操作样式往往会用嵌套的方式来增强样式的约束力,如

<div class='demo'>
<p id='demo'></p>
</div>


此时的选择器约束性是 p < div p < .demo p < #demo

OOCSS建议避免在页面中用
ID
来控制样式,因此我们更多的会用
class
的方式来控制,但这种时候应该尽量避免样式的嵌套低于,特别是在书写LESS或SASS代码时,许多程序员可能因为代码习惯轻易的便会将css嵌套上数层甚至更多,从效能和维护的角度考虑,一般css嵌套应该控制在2-3层最佳,如果要控制较深层的样式建议给要控制的Dom加入一个新的样式控制.

HTML编写技巧

1.学会Zen Coding 和HAML语法

现代IDE都会自带一些自动补全功能,这能大幅提升我们代码的编写速度,但还可以更快,通过Zen Coding 和HAML语法,sublime,idea等诸多IDE都会自带zencoding语法,你可以迅速的创建DOM元素

ul>li.list*50
按下tab键能快速创建50个li元素:

<ul>
<li class="list"></li>
……
<li class="list"></li>
</ul>


2.编写经常显示隐藏的元素(会造成浏览器重绘)时使用绝对定位来布局

DOM结构的优化会给页面带来性能上的优化,减少页面重绘也是要时刻的优化点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript css html