javascript - How to click an element that we get from http request using SetInterval?

window.addEventListener("load" , () => {
setInterval(() => {
let xhttp = new XMLHttpRequest();
xhttp.open("GET", "./messagedUsers.php", true);
xhttp.onload = () => {
if(xhttp.readyState === XMLHttpRequest.DONE) {
if(xhttp.status === 200) {
let data = xhttp.response;
sideActiveUsers.innerHTML = data;
}
}
}
xhttp.send();
} , 500);
messageInputContainer.focus();
})
let userInfo = document.querySelectorAll(".user-info");
userInfoClick(userInfo); // function that does operation using the nodeList userInfo
In the above code , what I'm trying to do is send a HttpRequest to the php and get a div container as a response from there. As a response , I do get the div container. The div I got from there has a class name "user-info". And I want to click it and further , apply some css to the all the elements it holds(as there will be lot of "user-info" container coming from the response.). What I'm unable to figure out is "user-info" container can be applied styling through css(not JS). But if I try to use some JS for the node with className "user-info" , nothing happens as the nodeList seems to be empty.
And I've also tried using querySelector inside the setInterval for "user-info". But that makes the function outside userInfoClick(userInfo) takes a userInfo that is not defined.
And if I use both querySelector and the function that takes the variable that holds that nodeList(userInfoClick), I am able to click the element coming back from php. But its effect is stopped after every 500 ms(as the setInterval is set for 500ms).
I want to be able to click the element coming back from php and click it whose effect doesn't change after every 500ms(along with the element getting from php every 500ms).
Help me out guys.
userInfoClick function:
const userInfoClick = (userInfo) => {
let userinfo = Array.from(userInfo);
userinfo.forEach((el , ind) => {
el.addEventListener("click" , () => {
for(let i=0 ; i<userInfo.length ; i++)
{
if(ind!==i)
{
userinfo[i].style.backgroundColor = "#dddddd";
}
}
el.style.backgroundColor = "#fff";
})
})
}
Answer
Solution:
You cannot bind an event handler to an element that does not yet exist. ThequerySelectorAll
call will return an empty collection, as the assignment toinnerHTML
will only happen in some future.
In this case, where you have the interval, it is better to use event delegation. This means that you listen to click events at a higher level in the DOM tree -- on an element that is always there and is not dynamically created. In your case this could besideActiveUsers
.
So change your code as follows:
Remove this line (as it will return a useless empty collection):
let userInfo = document.querySelectorAll(".user-info");
And change theuserInfoClick
function, which should be called only once, without any arguments:
function userInfoClick() {
sideActiveUsers.addEventListener("click" , (e) => {
const el = e.target;
// We're only interested in user-info clicks:
if (!el.classList.contains("user-info")) return;
// Since we clicked on a user-info, the following will now have matches:
for (const sibling of sideActiveUsers.querySelectorAll(".user-info")) {
sibling.style.backgroundColor = "#dddddd";
}
el.style.backgroundColor = "#fff";
});
}
Share solution ↓
Additional Information:
Link To Answer People are also looking for solutions of the problem: call to undefined function mysqli_connect()
Didn't find the answer?
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Similar questions
Find the answer in similar questions on our website.
Write quick answer
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.