Search code examples
javascriptclosestselectors-api

How to call closest() on first element selected by querySelectorAll in custom chainable JavaScript library?


What exactly is wrong about my try to call closest() on first element selected by querySelectorAll in my custom JavaScript library?

var $ = function(selector){

  var x; 
  var obj = {
  
    myLib(selector){
      return x || document.querySelectorAll(selector);
    },
    
    cl(selector){
      x[0].closest(selector);
      return this;
    },
      
    style(aaa,bbb){
           !aaa && !bbb ? x.getAttribute('style')                         :
            aaa &&  bbb ? x.forEach( zzz => { zzz.style[aaa]=bbb;     } ) :
      aaa.includes(';') ? x.forEach( zzz => { zzz.style.cssText+=aaa; } )
                        : getComputedStyle(x,null)[aaa];
      return this;
    },
      
  };
        
  x = obj.myLib(selector);
  return obj;
  
};

// now i want to call it

$('div').style('background','#FFFF00');
$('.kilo').cl('.uniform').style('color:','#880088');
<div id="foxtrott">
  foxtrott
  <div class="uniform">
    uniform
    <div class="charlie">
      charlie
      <div class="kilo">
        kilo
      </div>
    </div>
  </div>
</div>

When I change my cl() function to this the console tells me: $(...).cl(...) is null

cl(selector){
  return x[0].closest(selector);
},

I really don't get it how to do it correctly. :(


Solution

  • You're not setting x in cl.

    i.e.

        cl(selector) {
          x = [x[0].closest(selector)];
          return this;
        },
    

    Also of note, you'll want to drop the trailing colon on 'border-left:' (EDIT: or 'color:' in your latest edition)

    Here's a "working" example https://repl.it/repls/MixedRipeGlobalarrays