简体   繁体   中英

Check if element has class on click of another element and run a function

Vanilla JS. Trying to run a function on click of an element if the body tag has a class of example . No jQuery solutions please, I come from jQuery and want to learn and understand this simple task in JavaScript .

More so if you care to let me know, where is the error in my thinking please? Do I need to wrap the onclick event inside the condition for the body class? Tried that but also not getting the alert .

  var imgContainer = document.querySelector('.img-container'); var bodyTag = document.getElementsByTagName('body'); var bodyClassName = bodyTag.classname; imgContainer.onclick = infoBox; function infoBox(event) { if (bodyTag.classList.contains("example")) { alert('img-container has been clicked'); } } 
 <body class="example"> <div class="img-container"> <img src="https://dummyimage.com/320x120/000/fff" alt="dummy image"> <div class="img-infobox"> <p>This is a dummy image from https://dummyimage.com/</p> </div> </div> </body> 

Edit
From the given answers I am thinking that instead of returning an array like object and querying the DOM it would be fastest to just just document.body . no?

And this then means this question does not really have to do with

What do querySelectorAll, getElementsByClassName and other getElementsBy* methods return?

since the answer provided by the comment from https://stackoverflow.com/users/949476/dfsq uses neither of the methods from the linked answer.

Also
How can I compare the speed of using the document.querySelector vs. document.getElementsByTagName('body')[0]; vs. document.body please?

Like to give an explanation why I accepted what answer to be fair as all answers provide a working solution.

Answer
Since all answers work and document.body is fastest but also for another reason I like to post my answer here.

I am using this script from "4 novel ways to deal with sticky :hover effects on mobile devices" to handle the sticky hover problem. With this a class is added to the html tag of the site.

At first I had the click function inside the condition to check for the body or html class and only fire the click functions once the class is met, however with using this script I had to first run the function and only once it is run check if the html/body has the wanted class.

So while

  if (bodyTag.classList.contains("example")) {

    imgContainer.onclick = infoBox;

    function infoBox(event) {
        alert('img-container has been clicked and body has class "example"');    
    }

as well as

var bodyClassName = bodyTag.classname;

imgContainer.onclick = infoBox;

function infoBox(event) {

  if (bodyTag.classList.contains("example")) {

    alert('img-container has been clicked');

  }
}

works in a pure JSFiddle, it won't work with this setting since the sticky hover script sets the desired class on the element once a touch is made.

So once a click is made (I assume) it is then already too late to check for a condition outside of this touch/tap/click event and hence it won't fire.

In the end this leads to these simple lines that work together fine with the sticky hover script. The click event must run first and then check for the desired class/condition.

var imgContainer = document.querySelector('.img-container');

imgContainer.onclick = infoBox;

function infoBox(){

    if (document.documentElement.classList.contains('can-touch')) {
        alert('click on touch');
    }
}

Selector used for selecting body element is not appropriate.

getElementsByTagName will give an array like object so you will have to use index to get the first element.

Read : https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName

you are already using querySelector which return the first matching element , do the same for body as well.

Read : https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector

 var imgContainer = document.querySelector('.img-container'); var bodyTag = document.querySelector('body'); var bodyClassName = bodyTag.classname; imgContainer.onclick = infoBox; function infoBox(event) { if (bodyTag.classList.contains("example")) { alert('img-container has been clicked and body has class "example"'); } } 
 <body class="example"> <div class="img-container"> <img src="https://dummyimage.com/320x120/000/fff" alt="dummy image"> <div class="img-infobox"> <p>This is a dummy image from https://dummyimage.com/</p> </div> </div> </body> 

Performance Comparision : https://jsperf.com/body-selector-comparision

The document.getElementsByTagName returns a HTMLCollection which can be accessed as an array of objects, all you need is to select the first by using [0] after it like the following example:

 var imgContainer = document.querySelector('.img-container'); var bodyTag = document.getElementsByTagName('body')[0]; var bodyClassName = bodyTag.classname; imgContainer.onclick = infoBox; function infoBox(event) { if (bodyTag.classList.contains("example")) { alert('img-container has been clicked'); } } 
 <body class="example"> <div class="img-container"> <img src="https://dummyimage.com/320x120/000/fff" alt="dummy image"> <div class="img-infobox"> <p>This is a dummy image from https://dummyimage.com/</p> </div> </div> </body> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM