【问题标题】:How to run getElementsByTagName on children of an element only?如何仅在元素的子级上运行 getElementsByTagName?
【发布时间】:2013-03-22 23:15:36
【问题描述】:

我无法让选择器正常工作。

我有这个 HTML:

<div.wrapper>
    <div.ui-controlgroup-controls>
        <form>
            <div.ui-btn></div>
        </form>
        <div.ui-btn></div>
        <div.ui-btn></div>
        <div.ui-btn></div>
        <div.ui-btn></div>
    </div>
</div>

我正在尝试选择 div 标签,它们是 ui-controlgroup-controls 的子标签 - 这意味着排除表单内的内容。

这就是我正在尝试的:

// el is my div.wrapper element
el.children[0].getElementsByTagName("div");

但这不起作用,因为表单内的 div 最终会出现在选择中。

问题
不想使用 jQuery 时如何正确选择元素?

【问题讨论】:

    标签: javascript selection children getelementsbytagname


    【解决方案1】:
    <your-element>.querySelectorAll(":scope > div");
    

    :scope 是代表父元素的伪类。 IE中不支持,但是有shim

    【讨论】:

      【解决方案2】:

      对于支持querySelectorAll的浏览器:

      var divs = el.children[0].querySelectorAll("div");
      

      对于支持在NodeList上使用slice的浏览器(例如不是IE,至少不是IE

      var slice = Function.call.bind(Array.prototype.slice);
      
      var divs = slice(el.children[0].children).filter(function(node) { 
                     return node.tagName === "DIV"
                 });
      

      对于两者都不支持的浏览器:

      var nodes = el.children[0].children;
      var divs = [];
      
      for (var l = nodes.length, node; node = nodes[--l];) {
        if (node.tagName === "DIV")
          divs.push(node);
      }
      

      【讨论】:

      • 感谢您的选择
      【解决方案3】:

      一种方法是遍历生成的节点列表并检查父节点:

      var nodes = el.children[0].getElementsByTagName("div");
      nodes = Array.prototype.slice.call(nodes);
      nodes = nodes.filter(function(v, i){
          return v.parentElement === el.children[0]; 
      });
      

      这里是这种方法的演示:http://jsfiddle.net/WLhY2/

      一种更简单(尽管效率较低)的方法是使用querySelectorAll 使用选择器表达式检索相关节点:

      var divs = document.querySelectorAll('div.ui-controlgroup-controls > div')
      

      【讨论】:

      • 好主意。等待更复杂的解决方案。否则你会得到点头!谢谢!
      【解决方案4】:

      在大多数浏览器中,您可以这样做:

      el.querySelectorAll(".ui-controlgroup-controls > div")
      

      但是,如果您想避免嵌套更深的 ".ui-controlgroup-controls",这可能会导致误报。

      如果是这种情况,只需迭代 .children,并构建嵌套 div 的集合。

      var divs = [];
      
      for (var i = 0, len = el.children.length; i < len; i++) {
          if (el.children[i].classname === "ui-controlgroup-controls") {
              for (var j = 0, lenj = el.children[i].children.length; j <, lenj; j++) {
                  if (el.children[i].children[j].nodeName === "DIV") {
                      divs.push(el.children[i].children[j])
                  }
              }
          }
      }
      

      如果知道你只有一个ui-controlgroup-controls元素,那么你可以去掉外层循环,直接使用children[0]

      var divs = [];
      
      for (var j = 0, lenj = el.children[0].children.length; j <, lenj; j++) 
          if (el.children[0].children[j].nodeName === "DIV") 
              divs.push(el.children[o].children[j])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-11-01
        • 2023-02-20
        • 2016-05-01
        • 1970-01-01
        • 2021-08-24
        • 2011-05-26
        • 1970-01-01
        相关资源
        最近更新 更多