多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] ## 前言 我们在一些陈旧或者传统mvc的项目中还是会经常使用jq,但是由于对jq api或者核心思想不熟悉,导致我们的某些写法并不是特别好,这里会摘录一些并给出大家更好的写法建议。 ## 选择元素 ### 选择器使用 尽量使用综合查询效率最高的,一般id以及元素选择是最高效的,其实是class,最差的是属性选择器以及伪类选择器。 所以最终建议如果dom较多的话,最优先使用id选择器固定最小范围。 ### 循环筛选目标元素耗时 如果你有需要判定某列表中的元素是否具有某特点,尽量用选择器去实现,不要用循环 ~~~javascript //不建议 $("li").each(function(index){ if($(this).hasClass("active")){ } }) //建议,注意这里用到了同时筛选的语法,可以同时符合li以及.active原则 $("li.active") ~~~ ### 相关元素比全局查询效率高 ~~~javascript //不建议 $(".list li") $(".list") //建议 var $li=$(".list li") $li $li.parent() ~~~ ## jq的链式操作 ### 理解链式操作的原理 首先我们知道jq对原生对象是有一次封装的,两者支持的方法以及属性调用是完全不同的,一个属于原生语法,一个属于jq-api。并且两者可以互相转换,这里提下两者转换的语法,虽然比较冷门,但作为常识要清楚。 ~~~javascript //从jq对象转为原生对象 var oriDom=$("sel")[0] var oriDom=$("sel").get(0) //从原生对象转为jq对象 var oriDom=document.getElmentById("sel") var $dom=$(oriDom) ~~~ 那么重点来了,jq是如何支持链式操作的呢?原理也很简单,在任何一个jq方法结束其操作之后都会重新返回其jq对象。我们找到源码部分:jq的show(),hide()方法,可以看到其最后会把原生对象重新返回。 ~~~javascript function showHide( elements, show ) { //功能代码 return elements; } jQuery.fn.extend( { show: function() { return showHide( this, true ); }, hide: function() { return showHide( this ); } } ~~~ ### 基于链式思想的写法建议 - 同一操作对象的多个方法并列 ~~~javascript //不建议 $(target).addClass('class1') $(target).html('文本内容') //建议,不超过四个操作写在同一行,超过四个可以考虑每四个换行 $(target).addClass('class1').html('文本内容') ~~~ - 相关元素的操作,经典场景:过滤tab元素添加active,其他元素去除active ~~~javascript //不建议,一者写麻烦,二者前面为全量移除样式当前元素可能不需要 $(".tab").removeClass('active') $(this).addClass('active') //建议,使用siblings() $(this).addClass('active').siblings().removeClass("active") ~~~ - 同一元素相关元素的操作。可以使用end返回上一级 ~~~javascript //不建议,、 $(".target").prev().removeClass('active') $(".target").next().addClass('active') //建议,使用siblings() $(".target").prev().removeClass('active').end().next().addClass('active') ~~~ ## 认识漏洞 ### 选择多元素操作 ~~~javascript //不建议 $(".demo1").addClass('class1') $(".demo2").addClass('class1') //建议,同一类操作可以同时筛选并进行 $(".demo1,.demo2").addClass('class1') ~~~ ### 添加与移除样式 ~~~javascript //不建议 $(".demo1").addClass('class1').addClass('class2') //建议,添加以及移除样式可以支持多个,空格隔开即可 $(".demo1").addClass('class1 class2').removeClass("class1 class2") ~~~ ### 数据存储与使用 我们都知道jq封装了针对数据使用的.data(key,value)方法,也知道其有工具方法$.data(ele,key,value),建议使用工具函数因为其定义在原生对象原型链,操作效率更高 ~~~javascript //不建议 $(target).data(key,value) //建议 $.data($(target),key,value) ~~~ ## 合理使用缓存 ~~~javascript //不建议 $(".demo1").addClass('class1') $(".demo1").click(fn) //建议,超过两次就可以考虑定为变量,除非这个元素在方法进行时会发生变化需要重新获取 var $demo1=$(".demo1") ~~~ ## 多次操作dom合并 ~~~javascript //不建议 $(".demo1").append('<div></div>') $(".demo1").append('<div></div>') //js操作进行很快,dom部分逻辑完成后一次赋值 var htmlStr="<div></div><div></div>" $(".demo1").append(htmlStr) ~~~ ## 关于事件 ### 事件委托 我们知道元素的时间会向上冒泡成为父元素的事件,在大多数人针对列表项的事件可能是同时绑定子元素事件。 ~~~javascript //不建议 $("ul li").click(fn) //针对父元素绑定一次即可 $("ul").on("click","li",fn) ~~~ ### 事件触发 如果需要触发多个其他事件,建议写成trigger(),尤其是某些全局性、常用的工具函数事件建议这样写。 ~~~javascript //不建议 $("li").click(function(){ fn1(), fn2() }) //建议,注意这里用到了同时筛选的语法,可以同时符合li以及.active原则 $("li").click(function(){ $.trigger("FN1") }) $(document).on("FN1",function(){ fn1() }) ~~~ ### 绑定多个事件类型 ~~~javascript //不建议 $(target).click(fn) $(target).focus(fn) //建议 $(target).on("click focus",fn) ~~~ ### 合成事件 某类事件其相关事件可以直接定义在其后,这类的有hover与toogle,鼠标的移入与移出等 ~~~javascript //建议 $(target).toogle(func1,func2,func3,…) $(target).hover(enter,leave) ~~~ ## 参考文档 - 《锋利的jQuery 第二版》