简体   繁体   中英

document.querySelectorAll() function not working on all elements

I am using document.querySelectorAll() function to catch <a> in my list of <li> but the function is not working on all elements i have to define like this document.querySelectorAll('//elements')[0] , document.querySelectorAll('//elements')[1] if i define like this it works on element on that index only.

I don't think its good to define like this for all elements. Can anyone tell me please where i am wrong why its not working on all elements.

Here is my current code

HTML

<ul class="questions">
    <li>
        <a href="#" class="clearfix"><span class="faq_name">My Account</span><span class="arrow"><img src="images/plus.png"></span></a>
        <div class="answer_box">
            <p>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. </p>
        </div>
    </li>
    <li>
        <a href="#" class="clearfix"><span class="faq_name">Categories</span><span class="arrow"><img src="images/plus.png"></span></a>
        <div class="answer_box">
            <p>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. </p>
        </div>
    </li>
    <li>
        <a href="#" class="clearfix"><span class="faq_name">Trouble with check-in</span><span class="arrow"><img src="images/plus.png"></span></a>
        <div class="answer_box">
            <p>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. </p>
        </div>
    </li>
</ul>

JS

document.querySelectorAll('.questions li a').onclick = function() {myFunction()};
function myFunction(){
    alert('asd');
}; 

querySelectorAll returns a collection of elements. The DOM doesn't have a "set-based" feature letting you assign handlers to the entire set in one statement (the jQuery library does, if you fancy using it), you have to use a loop.

For example:

Array.prototype.forEach.call(
    document.querySelectorAll('.questions li a'),
    function(element) {
        element.onclick = myFunction;
    }
);
function myFunction(){
    alert('asd');
}

There, we use Array#forEach to loop through the collection (because it can be used on any array-like object, not just arrays). You have several other options outlined in the "array-like" part of this answer .


Side note 1: I used MyFunction directly above since wrapping it in a function that just calls it seems unnecessary, but that will change what arguments it receives, so add a wrapper if needed.

Side note 2: While I didn't change it above, I strongly recommend using addEventListener (and attachEvent if you have to support IE8 or the broken "compatibility mode" of IE9-IE11) instead of onclick .

Side note 3: For this specific use case, you might look into event delegation rather than adding a handler to each element. In event delegation, you add a handler to a container that has all your links in it (could be document.body , but usually there's a container closer to them that's more appropriate), and then when the event occurs, you see if it passed through a matching element while bubbling.

Side note 4: On those occasions where you just want the first match, intead of querySelectorAll(...)[0] , use querySelector(...) . It returns the first match, or null if nothing matches.

You need to convert the "HTMLcollection" to an array then loop that array to bind event listeners to each element.

By "calling" Array.prototype.slice on a 'array-like-objects', slice iterates & fills an new array that is returned. Then you can use array methods on that array.

 Array.prototype.slice.call(document.querySelectorAll('.questions li a')) //converts HTMLCollection to an array //or Array.apply(null ,document.querySelectorAll('.questions li a')) .forEach(function(element){ element.onclick = function(){ //do something } }) 

I found an easier way with a loop in which loop will run till the length of the elements

var question = document.querySelectorAll('.questions li a');
var i;
for(i=0;i<question.length;i++){
    question[i].addEventListener('click',myFunction)
}
function myFunction(){
    alert('adasd');
}

Every thing is same just calling the click in loop.

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