I am trying to listen to a click event of a link using javascript inside a wordpress project. But I could notice, NodeList is getting empty. Seem to be it's having an issue when communicating with the DOM. My attempt is as below. I created a folder called theme and inside the index.php there, below lines were added.
<?php get_header(); ?>
<a href="#" >Next1</a>
<a href="#" >Next2</a>
Then inside the functions.php file imported the external scripting file as below.
<?php
function pet_data1(){
wp_enqueue_script('pet_adoption_style1',
get_stylesheet_directory_uri().'/script.js', array(), false, false);
}
add_action('wp_enqueue_scripts', 'pet_data1');
?>
Next the header.php file takes as below.
<!DOCTYPE html>
<html lang="en">
<head>
<?php wp_head();?>
</head>
</html>
Finally, script.js file which is not given the expected output is as in below.
const nextBtns = document.querySelectorAll(".btn-next");
console.log("nextBtns",nextBtns)
When I print the nodeList, length is zero. But there should be 2 nodes which contains the btn-next class. So I think there should be an issue with wordpress structure which I have followed. Since I am new to wordpress, I need your support to fix this out.
CodePudding user response:
The issue is not with "Wordpress structure", but because you're loading the script in <head>, but attempting to access elements in the document body before waiting for the DOM to be ready.
<script> tags in the <head> will be downloaded and executed, before the browser parses the rest of the HTML found after <head> This causes issues with your selectors since when the script is executed, those elements that would have matched your selectors do not exist in the DOM tree at runtime:
Source: https://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html
There are two solutions:
- Ensure that
script.jsis loaded in the footer, which means the DOM has been parsed and is ready, or - Wrap all DOM querying logic in
script.jsin a callback that is invoked upon the firing ofDOMContentLoadedevent:
window.addEventListener('DOMContentLoaded', () => {
const nextBtns = document.querySelectorAll(".btn-next");
console.log("nextBtns",nextBtns)
});

