CQ-CSER

计算机爱好者

JQuery Tips

Posted on | 十二月 22, 2009 | No Comments

关于$()包装集你不知道的

包装集总是面向集合的

     我想这个理解起来很简单,被$()包装的JQuery对象总是以集合的形式出现.就算包装集中只有一个对象.

<div id="a"></div>
<div id="b"></div>
    <script type="text/javascript">
        $("div").html("hi");

    </script>

    上面被选择的两个DIV的内容都会被改变为”hi”

包装集内元素的顺序

     在被JQuery包装的元素中,包装集中所包含的内部顺序是按照HTML流从先向后排列的,而不是选择顺序:

<div id="a">here is a</div>
<div id="b">here is b</div>
    <script type="text/javascript">
        var Se = $("#b,#a");
        alert(Se.get(0).innerHTML);
        alert(Se.get(1).innerHTML);

    </script>

   上面代码可以看到,虽然是b先被选择,但是在执行alert的时候会先弹出”here is a”继而是“here is b”

JQuery对象和DOM的转化

      首先,是DOM转化成JQuery对象,这个很容易,只需包含在$()里面即可.但有一点注意的是,再被JQuery包装的元素的事件内,this总是指向当前对象:

<div id="a">here is a</div>
<div id="b">here is b</div>
    <script type="text/javascript">
        $("div").click(function() {
            alert(this.id);//this Ö¸Ïòµ±Ç°µÄDOM
        });

    </script>

     将JQuery包装集中的元素转为DOM对于JQuery来说也是很简单的事,大多数情况都使用JQuery的get方法

<div id="a">here is a</div>
<div id="b">here is b</div>
    <script type="text/javascript">
        var Jq = $("div");
        alert(Jq.get(0).id); //alert "a"
        alert(Jq.get()[0].id); //alert "a" as well
        alert(Jq[0].id);//alert "a"

    </script>

     从面可以看出,通过get方法加索引作为参数,会返回索引值的DOM对象,而不加参数会返回JQuery包装集中的整个数组

     还有一种简便方法是直接在JQuery包装集后面加数组符号,可以把上面的Jq[0]看做Jq.get(0)的简便方式:-)

检查当前JQuery包装集中的元素个数

       在很多时候,需要检查在JQuery包装集中的元素个数,我们可以直接通过包装集的length属性(这个属性在VS当中是不提示的)

div id="a">here is a</div>
<div id="b">here is b</div>
    <script type="text/javascript">
        var Jq = $("div");
        alert($("Div").length);//alert "2"

    </script>

      这个属性还可以直接用于检测当前的包装集是否为空

<div id="a">here is a</div>
<div id="b">here is b</div>
    <script type="text/javascript">
        if ($("div").length) {
            alert("Not Empty");
        }
        if ($("div").get(0)) {
            alert("Not Empty");
        }

    </script>

     上面两个alert都会被执行,第二个方式通过检测当前包装集中第一个元素是否为空来确定包装集为空. 

包装集在某些特定情况下也“不总是面向集合”

       刚才不是号称总是面向集合吗,咋又变了?其实的确是面向集合,但在使用JQuery的某些方法进行提取时,就不是这样了,比如下面代码:

<div id="a" >here is a</div>
<div id="b">here is b</div>
    <script type="text/javascript">
        alert($("div").attr("id"));

    </script>

     上面代码只会alert第一个div的id.那在这种情况下咋办呢?对,用JQuery的Each方法,each方法会遍历包装集中的每一个元素:

<div id="a" >here is a</div>
<div id="b">here is b</div>
    <script type="text/javascript">
        $("div").each(function() {
            alert($(this).attr("id"));
        });

    </script>

     上面代码会执行两个alert:-)

JQuery包装集内的元素在一开始的选定后,还可以通过一系列JQuery提供的方法对包装集内的元素进行扩充,修改,筛选,删除

find()方法 VS filter()方法

这两个方法是比较容易搞混的.

filter方法表示的是对当前内部的元素进行筛选,这个接受两种参数,一个返回bool的function,或者是JQuery的选择表达式,包装集内的元素只会小于等于当前包装集内的元素,并且含有的元素属于原来包装集内元素的子集:

<div id="one">the one</div>
<div id="two"><p>the two</p></div>
<div id="three"><p>the three</p></div>
    <script type="text/javascript">
        alert($("div").filter(":not(:first):not(:last)").html()); //out put<p>the two</p>
        alert($("div").filter(function() { return this.id == "two"; }).html());//output <p>the two</p> as well

    </script>

而find方法却是在当前元素内(子元素)部进行查找,并返回新的包装集,这意味着包装集可能会增加:

<div id="one">the one</div>
<div id="two"><p>the two</p><p></p><p></p></div>
<div id="three"><p>the three</p></div>
    <script type="text/javascript">
        alert($("div").find("p").text()); //alert "the twothe three"
        alert($("div").find("p").length); //alert 4 instead of original 3
    </script>

从上面可以看出新包装集内的元素增加了

 

parents()方法  VS closest()方法

这两个方法都是由当前元素向上查找所匹配的元素,不同之处如下:

    <div id="wrapper">
        <div id="two">
            <p id="p1">
                the two</p>
        </div>
        </div>
    <script type="text/javascript">
        alert($("#p1").parents("div").length); //alert 2 include <div id="two"> and <div id="wrapper">
        alert($("#p1").closest("div").length); //alert 1 and only include <div id="two">
        alert($("#p1").parents("p").length);  //alert 0 because it does not include current element
        alert($("#p1").closest("p").length);  //alert 1 because it contain itself <p id="p1">
    </script>

对于parents方法来说,会将当前元素向上的所有匹配元素加入新的包装集并返回,而closest方法只会包含离当前元素最近的元素,所以使用closest方法后当前包装集内的元素只能为1个或者0个

而parents方法并不包括当前包装集内的元素,而closest方法会包含当前包装集内的元素

直系子元素 VS 所有子元素

使用children可以返回直系子元素,而用find加通配符的方法可以返回除了文本节点之外的所有子元素:

    <div id="wrapper">
        text node here
        <div id="two">
            <p id="p1">
                the two</p>
        </div>
        </div>
    <script type="text/javascript">
        alert($("#wrapper").children().length);//alert 1 because only direct children included
        alert($("#wrapper").find("*").length); //alert 2 because all desendants included
        alert($("#wrapper").find(">*").length);//alert 1 because only direct children included
    </script>

可以看出children方法只会含有当前元素的直系子元素,而使用find(“>*也会产生同样的效果”).若想采纳所有的直系子元素直接在find内传”*”通配符

回到过去的end()方法以及andself()方法

上述所有的方法,以及比如add(),next(),nextAll(),prev()等对包装集内元素进行改变的方法都可以使用end()方法来进行返回:

    <div id="wrapper">
        text node here
        <div id="two">
            <p id="p1">
                the two</p>
        </div>
        </div>
    <script type="text/javascript">
        alert($("#wrapper").find(">*").end().get(0).id);//alert "wrapper" instead of "two" because of end() method has been used
    </script>

end()方法总是和最近的一个和包装集改变的方法相抵消,而抵消其他方法:

    <div id="wrapper">
        text node here
        <div id="two">
            <p id="p1">
                the two</p>
        </div>
        </div>
    <script type="text/javascript">
        alert($("#wrapper").find("#p1").html("new value").end().get(0).id);//alert wrapper because end method
        alert($("#p1").text())//alert new value bacause the html method in previous has not been cancelled
    </script>

如果需要在改变包装集内元素的情况下还需要包含原始的包装集内元素,使用andself方法:

    <div id="wrapper">
        text node here
        <div id="two">
            <p id="p1">
                the two</p>
        </div>
        </div>
    <script type="text/javascript">
        var $a = $("#wrapper").find("#two").andSelf();
        alert($a[0].id);//alert two first
        alert($a[1].id);//alert wrapper after that
    </script>

我们会发现首先alert two,因为two先被选择

如今咱祖国已经崛起了..电脑的配置也是直线上升.可是js的性能问题依然不可小觑..尤其在万恶的IE中..js引擎速度本来就慢..如果JS如果再写不好,客户端多开几个窗口假死肯定是家常便饭了.废话不说了,下面说说js性能提升的一些小Tips.

在选择时,最好以ID选择符作为开头

我想这个很好理解,因为JQuery内部使用document.getElementByID方法进行ID选择,这种方法比其他所有对DOM选择的方法更快,所以以$(“#”)开头是最好的,比如:

<div id="a">
   <div class="b">
      <div class="c">
          <div class="d"></div>
      </div>
   </div>
</div>
    <script type="text/javascript">
        $(".b .c .d")//slow one
        $("#a .b .c .d")//fast one
    </script>

 

提供$()的上下文

在使用$()选择页面元素时,提供选择的范围可以减少选择的时间,换句话说,让选择器只在页面的一小片范围内筛选而不是整个页面当然会减少筛选时间,通过在$()函数内提供第二个参数作为上下文可以实现这一点

    <div id="test">
       <div class="inner">hi</div>
    </div>
    <script type="text/javascript">
        alert($(".inner", document.getElementById("test")).text());//increase the speed by provide context
        alert($(".inner").text());//traverse all the element so that is slower than above
    </script>

当然,在jquery定义(或者js函数)事件内,可以通过this来指代上下文:

    <div id="test">
       <div class="inner">hi</div>
    </div>
    <script type="text/javascript">
        $("#test").click(function() {
            var text = $(".inner", this).text(); //this means $("#test")
            alert(text);//alert hi
        });
    </script>

当然,上面的例子也可以写成下面两种方式:

    <div id="test">
       <div class="inner">hi</div>
    </div>
    <script type="text/javascript">
        alert($("#test .inner").text()); //method 1
        alert($("#test").find(".inner").text());//method 2 and it was best one
    </script>

其中利用find方法是所有方法中效率最高的

 

当然,如果你是通过id选择符,也就是$(“#..”)来选择,不需要提供上下文参数.这对速度没有影响

 

 

将经常用的JQuery包装好的元素进行保存

如题,这点比较重要,因为使用$()对页面元素进行选择是需要耗费时间的.而保存为变量进行使用时,可以避免这种浪费,比如:

    <ul>
    <li>one</li>
    <li>two</li>
    <li>three</li>
    <li>four</li>
    <li>five</li>
    </ul>
    <script type="text/javascript">
        for (i = 0; i < $("ul li").length; i++) {//very bad,select $("ul li") so many times,waste a lot of time
            alert($("ul li")[i].innerHTML);//same here,very bad
        }
        var $li = $("ul li");
        for (i = 0; i < $li.length; i++) {//good one,only selct $("ul li") once
            alert($li[i].innerHTML); //same here,good
        }
    </script>

从代码可以看到,避免多次重复选择可以提高性能:-)

 

尽量少用选择符

JQuery的选择器是面向数组的,所以在条件允许的情况下尽量少用选择器,比如:

<div id="Div0"></div>
<div id="Div1"></div>
<div id="Div2"></div>
    <script type="text/javascript">
        $("#Div0").slideDown("slow");
        $("#Div1").slideDown("slow");
        $("#Div2").slideDown("slow");//slow

        $("Div0,Div1,Div2").slideDown("slow");//fast
    </script>

可以看出,使用选择器并用逗号将被选择的元素分开,并选择多个元素不仅让代码更加简洁,并且通过减少创建JQuery的实例所以在性能上也稍胜一筹!

 

在循环次数很多时避免使用$().each,而使用for循环

使用$().each方法让在进行循环时,会让编程更加轻松,少量的循环在使用$().each时对性能的影响可以忽略不计,但是当这个数字很大的时候,对性能的影响便开始变得可观了.

这个数字,我查了下资料,据说是1000以下可以使用$().each方法,而这个数字如果继续增加,则应该使用for循环语句。

 

尽量减少对DOM的操作

在页面中对DOM操作是比较消耗的(比如在页面插入或删除一段文字),把这个改动降至最小是保持性能的最佳实践!比如:

    <ul id="test">
    </ul>
    <script type="text/javascript">
        var $list = $("#test");
        for (i = 1; i < 101; i++) {
            $list.append("<li>Item" + i + "</li>");
        } //very bad,change dom 100 times

        var listItem = "";
        for (j = 1; j < 101; j++) {
            listItem += "<li>Item" + j + "</li>";
        }
        $list.html(listItem);
        //good practice,only modify dom once

    </script>

可以看出,第一个例子对DOM修改100次,而第二个只对DOM修改1次,这上面的性能差距是显而易见的。

 

可以屏蔽JQuery的动画效果

在某些情况下,如果,可以关闭JQuery动画,能对性能进行一定提升,屏蔽的方法是:

    <script type="text/javascript">
        jQuery.fx.off = true;
    </script>

 

如果参数可以是JS对象,尽量使用对象

很对JQuery插件,或者JQuery的css和attr方法都接受键/值 或 js键/值对象 对作为参数,传递键值对象可以减少JQuery对象的创建,比如:

<div></div>
    <script type="text/javascript">
        $("div").css("display", "block");
        $("div").css("background-color", "blue")
        //slow,because it create more Jquery object

        $("div").css({ "display": "block", "background-color": "blue" });
        //fast,only create one object
    </script>

 

当然也可以使用连缀的方式:

<div></div>
    <script type="text/javascript">
        $("div").css("display", "block").css("background-color", "blue");

    </script

但是这种方式的性能不如上面那种.需要使用两个方法,并且需要多生成临时对象.

 

相关文章:

  1. 10 JQUERY 设计技巧
  2. Prototype And jquery
  3. Hosting IFRAMEs using the JQuery UI Tabs plug-in
  4. 10 tips to make more money fromWP
  5. jquery学习笔记3

评论|Comments

留言|Leave a Reply





  • Archives

  • SUNSHINE

  • About

    本博客采用创作共用版权协议,要求署名、非商业用途和保持一致. 转载本博客内容也遵循“署名-非商业用途-保持一致”的创作共用协议.

    订阅

    Search

    Admin