【问题标题】:How to traverse DOM to find the last ancestor with specific attribute in Javascript?如何遍历DOM以在Javascript中找到具有特定属性的最后一个祖先?
【发布时间】:2019-09-27 01:29:19
【问题描述】:

这是我的示例 HTML:

<div id="parent1" data-attribute="parent">
  <div id="child2" data-attribute="child">
    <div id="grandchild4" data-attribute="child">
    </div>
  </div>
</div>
<div id="parent2" data-attribute="parent">
  <div id="child3" data-attribute="child">
    <div id="grandchild1" data-attribute="parent">
      <div id="item1"></div>
    </div>
  </div>
  <div id="child4" data-attribute="parent">
    <div id="grandchild2" data-attribute="child">
      <div id="grandchild3" data-attribute="parent">
        <div id="item2" data-attribute="child">
          <div id="sub1" data-attribute="child">
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

如果我正在执行查询选择的当前元素是sub1,我如何找到data-attribute="parent" 的最后一个祖先?在这种情况下,预期结果应该是parent2

我知道closest() 将返回第一个匹配项,即grandchild3,但是是否有一个选择器可以找到最终的祖先?通过id 查询不是选项,因为我的 id 是动态创建的。

【问题讨论】:

    标签: javascript html typescript


    【解决方案1】:

    首先,要找到所有的祖先,你可以结合[data-attribute="parent"][id^="parent"]这两个条件。 More on wildcard selectors

    $('div[id^="parent"][data-attribute="parent"]')
    

    现在,一旦你有了所有的祖先,last() 应该给你直接的。请在下面找到sn-p

    console.log($('div[id^="parent"][data-attribute="parent"]').last().attr('id'))
    <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
    
    <div id="parent1" data-attribute="parent">
      <div id="child2" data-attribute="child">
        <div id="grandchild4" data-attribute="child">
          grandchild4
        </div>
      </div>
    </div>
    <div id="parent2" data-attribute="parent">
      <div id="child3" data-attribute="child">
        <div id="grandchild1" data-attribute="parent">
          grandchild1
          <div id="item1">item1</div>
        </div>
      </div>
      <div id="child4" data-attribute="parent">
        <div id="grandchild2" data-attribute="child">
          <div id="grandchild3" data-attribute="parent">
            grandchild3
            <div id="item2" data-attribute="child">
              item2
              <div id="sub1" data-attribute="child">
                sub1
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    【讨论】:

      【解决方案2】:

      您可以编写一个 XPath 表达式和evaluate

      const element = document.querySelector('#sub1');
      const xpath = 'ancestor::*[@data-attribute="parent"][last()]';
      const result = document.evaluate(xpath, element, null, 
                         XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue;
      
      console.log(result);
      <div id="parent1" data-attribute="parent">
        <div id="child2" data-attribute="child">
          <div id="grandchild4" data-attribute="child">
          </div>
        </div>
      </div>
      <div id="parent2" data-attribute="parent">
        <div id="child3" data-attribute="child">
          <div id="grandchild1" data-attribute="parent">
            <div id="item1"></div>
          </div>
        </div>
        <div id="child4" data-attribute="parent">
          <div id="grandchild2" data-attribute="child">
            <div id="grandchild3" data-attribute="parent">
              <div id="item2" data-attribute="child">
                <div id="sub1" data-attribute="child">
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      【讨论】:

        【解决方案3】:

        没错???

        document.getElementById("sub1").addEventListener("click", function(){
        
          let ancester = this.parentElement;
          let flag = ancester.getAttribute("data-attribute");
        
          while(flag !== "parent") {
            ancester = ancester.parentElement;
            flag = ancester.getAttribute("data-attribute");
          }
        
          console.log(ancester);
        });
        

        【讨论】:

          【解决方案4】:

          您可以创建自己的closest 版本,它将为您提供所需类型的最后一个祖先。如果您使用的是 jQuery:

          $.fn.extend({
            closestTop: function(selection) {
              var el = this;
              var lastKnown = null;
              do {
                lastKnown = el;
                var guess = $(el).parent().length && $(el).parent().closest(selection || '');
                el = guess && guess.length && guess.get(0) || null;
              } while (el != null);
              return $(lastKnown);
            }
          });
          
          console.log($('#sub1').closestTop('[data-attribute=parent]'))
          <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
          <div id="parent1" data-attribute="parent">
            <div id="child2" data-attribute="child">
              <div id="grandchild4" data-attribute="child">
              </div>
            </div>
          </div>
          <div id="parent2" data-attribute="parent">
            <div id="child3" data-attribute="child">
              <div id="grandchild1" data-attribute="parent">
                <div id="item1"></div>
              </div>
            </div>
            <div id="child4" data-attribute="parent">
              <div id="grandchild2" data-attribute="child">
                <div id="grandchild3" data-attribute="parent">
                  <div id="item2" data-attribute="child">
                    <div id="sub1" data-attribute="child">
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-05-23
            • 2014-04-02
            • 2019-02-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-21
            相关资源
            最近更新 更多