zoukankan      html  css  js  c++  java
  • javascript的dom选择器

    querySelector 和 querySelectorAll 方法是 W3C Selectors API 规范中定义的。他们的作用是根据 CSS 选择器规范,便捷定位文档中指定元素。

    目前几乎主流浏览器均支持了他们。包括 IE8(含) 以上版本、 Firefox、 Chrome、Safari、Opera。

    querySelector 和 querySelectorAll 在规范中定义了如下接口:

    module dom { [Supplemental, NoInterfaceObject] interface NodeSelector { Element querySelector(in DOMString selectors); NodeList querySelectorAll(in DOMString selectors); }; Document implements NodeSelector; DocumentFragment implements NodeSelector; Element implements NodeSelector; };

    从接口定义可以看到Document、DocumentFragment、Element都实现了NodeSelector接口。即这三种类型的元素都拥有者两个方法。querySelector和querySelectorAll的参数须是符合 css selector 的字符串。不同的是querySelector返回的是一个对象,querySelectorAll返回的一个集合(NodeList)。

    在css中對特定的元素設置樣式離不開選擇符的使用,現在一些大的 javascript 框架 也常用選擇符來獲取特定的元素,如jQuery。W3c規範定義了兩個新的方法(querySelector 和 querySelectorAll) 來獲取元素節點,這兩個方法都接受選擇符作為自己的參數。Nicholas在他的《High Performance JavaScript》一書中對這兩個方法作了簡要介紹,並對其性能作了比較,與傳統獲取元素節點的方法相比,其性能明顯偏優。讓我們從下面這個例子說 起。

    <table id="score">
      <thead>
        <tr>
          <th>Test</th>
          <th>Result
              </th>
              </tr>
              </thead>
      <tfoot>
        <tr>
          <th>Average   </th>
          <td>82%
              </td>
    </tr>
    </tfoot>
      <tbody>
        <tr>
          <td>A</td>
          <td>87%</td>
            </tr>
       <tr>
          <td>A</td>
          <td>87%</td>
            </tr>
            <tr>
          <td>A</td>
          <td>87%</td>
            </tr>
            …
            </tbody>
    </table>
    

     

    上面的1000行表格中,要獲取每行包含成績的單元格,傳統意義上,我們使用以下的方法:

    var table = document.getElementById("score");
    var groups = table.tBodies;
    var rows = null;
    var cells = [];
    
    for (var i = 0; i < groups.length; i++) {
      rows = groups[i].rows;
      for (var j = 0; j < rows.length; j++) {
        cells.push(rows[j].cells[1]);
      }
    }
    

    使用w3c提供的新方法,僅一行代碼即可完成任務,而且速度很快。

    var cells = document.querySelectorAll("#score>tbody>tr>td:nth-of-type(2)");
    

    我們可以使用《javascript設計模式》一書中提供的一個「方法性能分析器」來比較這兩個方法的性能,方法如下:

    var MethodProfiler = function(component) {
      this.component = component;
      this.timers = {};
      this.log = document.createElement("ul");
      var body = document.body;
      body.insertBefore(this.log,body.firstChild);
      for(var key in this.component) {
        // Ensure that the property is a function.
        if(typeof this.component[key] !== 'function') {
          continue;
        }
        // Add the method.
        var that = this;
        (function(methodName) {
          that[methodName] = function() {
            that.startTimer(methodName);
            var returnValue = that.component[methodName].apply(that.component,
              arguments);
            that.displayTime(methodName, that.getElapsedTime(methodName));
            return returnValue;
          };
        })(key); }
    };
    MethodProfiler.prototype = {
      startTimer: function(methodName) {
        this.timers[methodName] = (new Date()).getTime();
      },
      getElapsedTime: function(methodName) {
        return (new Date()).getTime() - this.timers[methodName];
      },
      displayTime: function(methodName, time) {
            var li = document.createElement("li");
            var text = document.createTextNode(methodName + ': ' + time + ' ms');
        li.appendChild(text);
            this.log.appendChild(li);
      }
    };
    

    然後將這兩個方法寫入一個對象之中,並用性能分析器對它們進行比較.

    var obj = {
            getElementByTradition:function(){
                    var table = document.getElementById("score");
                    var groups = table.tBodies;
                    var cells = [];
    
                    for (var i = 0; i < groups.length; i++) {
                      rows = groups[i].rows;
                      for (var j = 0; j < rows.length; j++) {                    cells.push(rows[j].cells[1]);             }             }       },      querySelectorAll:function(){                    var cells = document.querySelectorAll("#score>tbody>tr>td:nth-of-type(2)");
                    }
    }
    var obj = new MethodProfiler(obj);
    obj.getElementByTradition();
    obj.querySelectorAll();
    

    查看示例,我們很清楚的看到,新的方法不僅使用簡單,而且性能明顯優於我們傳統的方法。注意,儘管IE8已經支持這些方法,但是IE8並不支持nth-of-type()選擇器(詳情可參考Compatibility table: CSS3 Selectors),所以在IE8中會拋出錯誤信息。

    當調用document.querySelectorAll()方法時,將返回節點數種的第一個元素節點,如果沒有匹配的節點,將返回null,如:

    <div id="fooid=">
          <p class="id"="warningid=">This is a sample warning</p>
          <p class="id"="errorid=">This is a sample error</p>
     </div>
     <div id=id="barid=">
          <p>...</p>
     </div>
    

    使用上面的html,調用以下方法將返回id屬性為foo的元素。

    var obj = document.querySelector("#foo, #bar");
    alert(obj.innerHTML);//foo
    

    如果去掉id屬性為foo的元素,調用上面的方法將返回:bar。該方法按照參數中傳遞的選擇符進行查找,如果找到則終止並返回該元素,否則返回null。

    調用document.querySelectorAll()方法將按順序返回包含在節點樹中所有匹配的元素,如:

    var res = document.querySelectorAll("p.warning, p.error");
    

    上面的res中將選澤文檔中class為「error」或「warning」的所有p元素。

  • 相关阅读:
    用于Web开发的8 个最好的跨平台编辑器
    javascript之数组操作
    15 个最佳的 jQuery 表格插件
    使用Backbone构建精美应用的7条建议
    linux内核内存分配(一、基本概念)
    redhat的systemd版本list
    Linux内核crash/Oops异常定位分析方法
    systemd bug: bz1437114 core:execute: fix fork() fail handling in exec_spawn()
    Use gdb attach pid and debug it
    Build rpm example:zram
  • 原文地址:https://www.cnblogs.com/zhepama/p/3110132.html
Copyright © 2011-2022 走看看