DOM / pure JavaScript solution to jQuery.closest() implementation?

后端 未结 8 1883
感动是毒
感动是毒 2020-12-06 00:26

Here\'s the markup i\'m trying to query. So given the markup:

8条回答
  •  北荒
    北荒 (楼主)
    2020-12-06 01:02

    You can't do this without a loop :

    function closest (el, predicate) {
      do if (predicate(el)) return el;
      while (el = el && el.parentNode);
    }
    

    Well, actually you can, using recursivity (a disguised loop) :

    function closest(el, predicate) {
      return predicate(el) ? el : (
         el && closest(el.parentNode, predicate)
      );
    }
    

    A demo (using Sizzle for the DOM queries) :

    // s = selectors
    // n = number of selectors
    // get closest s[i+1] from s[i]
    // where 0 <= i < n and i % 2 = 0
    
    function main (s) {
      var i, el, from;
      var n = s.length;
      for (i = 0; i < n; i += 2) {
        from = Sizzle(s[i])[0];
        el = closest(from, function (el) {
          return !!el && el !== document && (
            Sizzle.matchesSelector(el, s[i + 1])
          );
        });
        console.log(el);
      }
    }
    
    function closest (el, predicate) {
      do if (predicate(el)) return el;
      while (el = el && el.parentNode);
    }
    
    main([
      "#winner" , "b", 
      "#winner" , "p", 
      "#winner" , "div", 
      "#winner" , "div:not(#trump)", 
      "#winner" , "#clinton",
      "#looser" , "html"
    ]);
    
    
    

    Donald Trump

    Hillary Clinton

提交回复
热议问题