Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Events and selectors in native javascript

How can this jQuery-dependent code

$('.myElement').click(function () {
  drawMode = !drawMode;
  $icon = $(this).children('i');
  if (drawMode) {
    $icon.removeClass('a').addClass('b');
  } else {
    $icon.removeClass('b').addClass('a');
  }
});

be rewritten into native javascript?

I have tried

var element = document.getElementsByClassName('myElement')[0];    
element.addEventListener('click', function (e) {
  drawMode = !drawMode;
  var icon = this.children()[0];
  if (drawMode) {
    icon.classList.remove('a').add('b');
  } else {
    icon.classList.remove('b').add('a');
  }
});

but I cannot find the children element correctly.

like image 340
Jamgreen Avatar asked Feb 07 '23 05:02

Jamgreen


1 Answers

jQuery's children allows you to filter by selector, something that isn't in the DOM API (you can find all descendants matching a given CSS selector, but you can't [for now] limit it to just children).

If it doesn't matter whether it's a child or just any descendant, then:

var icon = this.querySelector("i");

That finds the first descendant within the element that's an i element. I suspect that would work just fine for you. The only time it might not would be if you had this:

<div class="myElement">
    <span>
        <i>You DON'T want this one</i>
    </span>
    <i>You do want this one</i>
</div>

If that's the case and you need to only look at children, not all descendants, you'll need a loop:

var icon = null;
var n;
for (n = 0; n < !icon && this.children.length; ++n) {
    if (this.children[n].tagName.toLowerCase() === "i") {
        icon = this.children[n];
    }
}

In ES2015+ (you can transpile to use it today), that's so much tidier:

let icon = Array.from(this.children)
                .find(child => child.tagName.toLowerCase() === "i");
like image 70
T.J. Crowder Avatar answered Feb 08 '23 17:02

T.J. Crowder