How can I set event listener after dom is loaded by className Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!How can I upload files asynchronously?How can I merge properties of two JavaScript objects dynamically?How to manage a redirect request after a jQuery Ajax callHow can I convert a string to boolean in JavaScript?How can I know which radio button is selected via jQuery?How can I get query string values in JavaScript?How can I select an element with multiple classes in jQuery?How do I set/unset a cookie with jQuery?How can I pretty-print JSON using JavaScript?How can I refresh a page with jQuery?
How would a mousetrap for use in space work?
Using audio cues to encourage good posture
Wu formula for manifolds with boundary
Withdrew £2800, but only £2000 shows as withdrawn on online banking; what are my obligations?
What causes the direction of lightning flashes?
Is it cost-effective to upgrade an old-ish Giant Escape R3 commuter bike with entry-level branded parts (wheels, drivetrain)?
How to down pick a chord with skipped strings?
Why wasn't DOSKEY integrated with COMMAND.COM?
Generate an RGB colour grid
How do I find out the mythology and history of my Fortress?
How to answer "Have you ever been terminated?"
An adverb for when you're not exaggerating
Trademark violation for app?
Do I really need to have a message in a novel to appeal to readers?
Is "Reachable Object" really an NP-complete problem?
Why do the resolve message appear first?
8 Prisoners wearing hats
When the Haste spell ends on a creature, do attackers have advantage against that creature?
Crossing US/Canada Border for less than 24 hours
Is it fair for a professor to grade us on the possession of past papers?
Do wooden building fires get hotter than 600°C?
Compare a given version number in the form major.minor.build.patch and see if one is less than the other
2001: A Space Odyssey's use of the song "Daisy Bell" (Bicycle Built for Two); life imitates art or vice-versa?
Do square wave exist?
How can I set event listener after dom is loaded by className
Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!How can I upload files asynchronously?How can I merge properties of two JavaScript objects dynamically?How to manage a redirect request after a jQuery Ajax callHow can I convert a string to boolean in JavaScript?How can I know which radio button is selected via jQuery?How can I get query string values in JavaScript?How can I select an element with multiple classes in jQuery?How do I set/unset a cookie with jQuery?How can I pretty-print JSON using JavaScript?How can I refresh a page with jQuery?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I have a card with class name contact-card when i click this card it should toggle another div's visibility. The card is laid out after getting data from a database.
function buildCard(doc)
let ulList = document.createElement('ul');
let listItem = document.createElement('li');
let link = document.createElement('a');
let icon = document.createElement('i');
let icon2=document.createElement('i');
ulList.className = "collection";
listItem.className = "collection-item avatar card-contact";
link.className = "secondary-content";
icon.className = "material-icons";
icon2.className = "material-icons";
listItem.setAttribute('id', 'card-contact');
icon.setAttribute('id','mail');
icon2.setAttribute('id','fav');
if(doc.read==true)
icon2.textContent='drafts';
else
icon2.textContent='mail_outline';
if(doc.favourite==true)
icon.textContent = 'grade';
else
icon.textContent='star_border';
link.appendChild(icon2);
link.appendChild(icon);
listItem.appendChild(link);
ulList.appendChild(listItem);
mainContactCard.appendChild(ulList);
MRef = db.collection("user").doc("3454").collection('contact').orderBy("time", "desc").limit(10);
MRef.get().then(function (querySnapshot)
querySnapshot.forEach(function (doc)
buildCard(doc.data());
);
)
.catch(function (error)
console.log("Error getting documents: ", error);
);
var contactCard = document.querySelector('.card-contact');
setTimeout(ert, 2000);
function ert()
contactCard.addEventListener('click', toggleThis);
function toggleThis()
$("#chat-card").toggle("fast");
//chat-card is supposed to be the div that fades in and out
I tried to add a timeout of ten seconds thinking that the dom is being loaded fast and failing to get the value of the variable contactCard but this is not the case. After ten seconds I still get the error Uncaught TypeError: Cannot read property 'addEventListener' of null
What am I doing wrong. I need there to be many cards which if i click any it toggles visibility of the div. That is why I am selecting by className
(more added code)
lastMessageRef.get().then(function (querySnapshot)
querySnapshot.forEach(function (doc)
buildContactCard(doc),str();
);
)
.catch(function (error)
console.log("Error getting documents: ", error);
);
function str()
var contactCard=document.getElementsByClassName('card-contact')
for (var i = 0; i < contactCard.length; i++)
//Distribute(contactCard.item(i));
contactCard.item(i).addEventListener('click', function (e)
$("#chat-card").toggle("fast");
if (e.target && e.target.nodeName == "LI")
// List item found! Output the ID!
console.log("List item ", e.target.id.replace("", ""), " was clicked!");
);
javascript jquery
add a comment |
I have a card with class name contact-card when i click this card it should toggle another div's visibility. The card is laid out after getting data from a database.
function buildCard(doc)
let ulList = document.createElement('ul');
let listItem = document.createElement('li');
let link = document.createElement('a');
let icon = document.createElement('i');
let icon2=document.createElement('i');
ulList.className = "collection";
listItem.className = "collection-item avatar card-contact";
link.className = "secondary-content";
icon.className = "material-icons";
icon2.className = "material-icons";
listItem.setAttribute('id', 'card-contact');
icon.setAttribute('id','mail');
icon2.setAttribute('id','fav');
if(doc.read==true)
icon2.textContent='drafts';
else
icon2.textContent='mail_outline';
if(doc.favourite==true)
icon.textContent = 'grade';
else
icon.textContent='star_border';
link.appendChild(icon2);
link.appendChild(icon);
listItem.appendChild(link);
ulList.appendChild(listItem);
mainContactCard.appendChild(ulList);
MRef = db.collection("user").doc("3454").collection('contact').orderBy("time", "desc").limit(10);
MRef.get().then(function (querySnapshot)
querySnapshot.forEach(function (doc)
buildCard(doc.data());
);
)
.catch(function (error)
console.log("Error getting documents: ", error);
);
var contactCard = document.querySelector('.card-contact');
setTimeout(ert, 2000);
function ert()
contactCard.addEventListener('click', toggleThis);
function toggleThis()
$("#chat-card").toggle("fast");
//chat-card is supposed to be the div that fades in and out
I tried to add a timeout of ten seconds thinking that the dom is being loaded fast and failing to get the value of the variable contactCard but this is not the case. After ten seconds I still get the error Uncaught TypeError: Cannot read property 'addEventListener' of null
What am I doing wrong. I need there to be many cards which if i click any it toggles visibility of the div. That is why I am selecting by className
(more added code)
lastMessageRef.get().then(function (querySnapshot)
querySnapshot.forEach(function (doc)
buildContactCard(doc),str();
);
)
.catch(function (error)
console.log("Error getting documents: ", error);
);
function str()
var contactCard=document.getElementsByClassName('card-contact')
for (var i = 0; i < contactCard.length; i++)
//Distribute(contactCard.item(i));
contactCard.item(i).addEventListener('click', function (e)
$("#chat-card").toggle("fast");
if (e.target && e.target.nodeName == "LI")
// List item found! Output the ID!
console.log("List item ", e.target.id.replace("", ""), " was clicked!");
);
javascript jquery
The issue is obvious, the element doesn't exist in the DOM when you attempt to add the event handler, but we can't see why this is happening with the excerpt of the code you've shown. Can you add a complete example of the code - an MCVE would help too.
– Rory McCrossan
Mar 22 at 9:42
Also note that a single delegated handler may be a better approach, but again this is just conjecture without seeing a more complete example of your logic.
– Rory McCrossan
Mar 22 at 9:43
window.onload = () => ...in vanilla JS,$(document).ready(() => ...)in jQuery
– iArcadia
Mar 22 at 9:59
document.readyis included
– Taio
Mar 22 at 10:00
Just realized when I create 10 cards using a loop. Only the very first card responds to the event listener
– Taio
Mar 22 at 10:01
add a comment |
I have a card with class name contact-card when i click this card it should toggle another div's visibility. The card is laid out after getting data from a database.
function buildCard(doc)
let ulList = document.createElement('ul');
let listItem = document.createElement('li');
let link = document.createElement('a');
let icon = document.createElement('i');
let icon2=document.createElement('i');
ulList.className = "collection";
listItem.className = "collection-item avatar card-contact";
link.className = "secondary-content";
icon.className = "material-icons";
icon2.className = "material-icons";
listItem.setAttribute('id', 'card-contact');
icon.setAttribute('id','mail');
icon2.setAttribute('id','fav');
if(doc.read==true)
icon2.textContent='drafts';
else
icon2.textContent='mail_outline';
if(doc.favourite==true)
icon.textContent = 'grade';
else
icon.textContent='star_border';
link.appendChild(icon2);
link.appendChild(icon);
listItem.appendChild(link);
ulList.appendChild(listItem);
mainContactCard.appendChild(ulList);
MRef = db.collection("user").doc("3454").collection('contact').orderBy("time", "desc").limit(10);
MRef.get().then(function (querySnapshot)
querySnapshot.forEach(function (doc)
buildCard(doc.data());
);
)
.catch(function (error)
console.log("Error getting documents: ", error);
);
var contactCard = document.querySelector('.card-contact');
setTimeout(ert, 2000);
function ert()
contactCard.addEventListener('click', toggleThis);
function toggleThis()
$("#chat-card").toggle("fast");
//chat-card is supposed to be the div that fades in and out
I tried to add a timeout of ten seconds thinking that the dom is being loaded fast and failing to get the value of the variable contactCard but this is not the case. After ten seconds I still get the error Uncaught TypeError: Cannot read property 'addEventListener' of null
What am I doing wrong. I need there to be many cards which if i click any it toggles visibility of the div. That is why I am selecting by className
(more added code)
lastMessageRef.get().then(function (querySnapshot)
querySnapshot.forEach(function (doc)
buildContactCard(doc),str();
);
)
.catch(function (error)
console.log("Error getting documents: ", error);
);
function str()
var contactCard=document.getElementsByClassName('card-contact')
for (var i = 0; i < contactCard.length; i++)
//Distribute(contactCard.item(i));
contactCard.item(i).addEventListener('click', function (e)
$("#chat-card").toggle("fast");
if (e.target && e.target.nodeName == "LI")
// List item found! Output the ID!
console.log("List item ", e.target.id.replace("", ""), " was clicked!");
);
javascript jquery
I have a card with class name contact-card when i click this card it should toggle another div's visibility. The card is laid out after getting data from a database.
function buildCard(doc)
let ulList = document.createElement('ul');
let listItem = document.createElement('li');
let link = document.createElement('a');
let icon = document.createElement('i');
let icon2=document.createElement('i');
ulList.className = "collection";
listItem.className = "collection-item avatar card-contact";
link.className = "secondary-content";
icon.className = "material-icons";
icon2.className = "material-icons";
listItem.setAttribute('id', 'card-contact');
icon.setAttribute('id','mail');
icon2.setAttribute('id','fav');
if(doc.read==true)
icon2.textContent='drafts';
else
icon2.textContent='mail_outline';
if(doc.favourite==true)
icon.textContent = 'grade';
else
icon.textContent='star_border';
link.appendChild(icon2);
link.appendChild(icon);
listItem.appendChild(link);
ulList.appendChild(listItem);
mainContactCard.appendChild(ulList);
MRef = db.collection("user").doc("3454").collection('contact').orderBy("time", "desc").limit(10);
MRef.get().then(function (querySnapshot)
querySnapshot.forEach(function (doc)
buildCard(doc.data());
);
)
.catch(function (error)
console.log("Error getting documents: ", error);
);
var contactCard = document.querySelector('.card-contact');
setTimeout(ert, 2000);
function ert()
contactCard.addEventListener('click', toggleThis);
function toggleThis()
$("#chat-card").toggle("fast");
//chat-card is supposed to be the div that fades in and out
I tried to add a timeout of ten seconds thinking that the dom is being loaded fast and failing to get the value of the variable contactCard but this is not the case. After ten seconds I still get the error Uncaught TypeError: Cannot read property 'addEventListener' of null
What am I doing wrong. I need there to be many cards which if i click any it toggles visibility of the div. That is why I am selecting by className
(more added code)
lastMessageRef.get().then(function (querySnapshot)
querySnapshot.forEach(function (doc)
buildContactCard(doc),str();
);
)
.catch(function (error)
console.log("Error getting documents: ", error);
);
function str()
var contactCard=document.getElementsByClassName('card-contact')
for (var i = 0; i < contactCard.length; i++)
//Distribute(contactCard.item(i));
contactCard.item(i).addEventListener('click', function (e)
$("#chat-card").toggle("fast");
if (e.target && e.target.nodeName == "LI")
// List item found! Output the ID!
console.log("List item ", e.target.id.replace("", ""), " was clicked!");
);
javascript jquery
javascript jquery
edited Mar 23 at 10:23
Taio
asked Mar 22 at 9:40
TaioTaio
334418
334418
The issue is obvious, the element doesn't exist in the DOM when you attempt to add the event handler, but we can't see why this is happening with the excerpt of the code you've shown. Can you add a complete example of the code - an MCVE would help too.
– Rory McCrossan
Mar 22 at 9:42
Also note that a single delegated handler may be a better approach, but again this is just conjecture without seeing a more complete example of your logic.
– Rory McCrossan
Mar 22 at 9:43
window.onload = () => ...in vanilla JS,$(document).ready(() => ...)in jQuery
– iArcadia
Mar 22 at 9:59
document.readyis included
– Taio
Mar 22 at 10:00
Just realized when I create 10 cards using a loop. Only the very first card responds to the event listener
– Taio
Mar 22 at 10:01
add a comment |
The issue is obvious, the element doesn't exist in the DOM when you attempt to add the event handler, but we can't see why this is happening with the excerpt of the code you've shown. Can you add a complete example of the code - an MCVE would help too.
– Rory McCrossan
Mar 22 at 9:42
Also note that a single delegated handler may be a better approach, but again this is just conjecture without seeing a more complete example of your logic.
– Rory McCrossan
Mar 22 at 9:43
window.onload = () => ...in vanilla JS,$(document).ready(() => ...)in jQuery
– iArcadia
Mar 22 at 9:59
document.readyis included
– Taio
Mar 22 at 10:00
Just realized when I create 10 cards using a loop. Only the very first card responds to the event listener
– Taio
Mar 22 at 10:01
The issue is obvious, the element doesn't exist in the DOM when you attempt to add the event handler, but we can't see why this is happening with the excerpt of the code you've shown. Can you add a complete example of the code - an MCVE would help too.
– Rory McCrossan
Mar 22 at 9:42
The issue is obvious, the element doesn't exist in the DOM when you attempt to add the event handler, but we can't see why this is happening with the excerpt of the code you've shown. Can you add a complete example of the code - an MCVE would help too.
– Rory McCrossan
Mar 22 at 9:42
Also note that a single delegated handler may be a better approach, but again this is just conjecture without seeing a more complete example of your logic.
– Rory McCrossan
Mar 22 at 9:43
Also note that a single delegated handler may be a better approach, but again this is just conjecture without seeing a more complete example of your logic.
– Rory McCrossan
Mar 22 at 9:43
window.onload = () => ... in vanilla JS, $(document).ready(() => ...) in jQuery– iArcadia
Mar 22 at 9:59
window.onload = () => ... in vanilla JS, $(document).ready(() => ...) in jQuery– iArcadia
Mar 22 at 9:59
document.ready is included– Taio
Mar 22 at 10:00
document.ready is included– Taio
Mar 22 at 10:00
Just realized when I create 10 cards using a loop. Only the very first card responds to the event listener
– Taio
Mar 22 at 10:01
Just realized when I create 10 cards using a loop. Only the very first card responds to the event listener
– Taio
Mar 22 at 10:01
add a comment |
1 Answer
1
active
oldest
votes
The element does not exist yet when you try to access it.
Adding a 10 seconds delay after document.querySelector('.card-contact'); does not help since you try to find the element before waiting the 10 seconds.
To make this works:
var contactCard = document.querySelector('.card-contact');
setTimeout(ert, 10000);
function ert()
contactCard.addEventListener('click', toggleThis);
You should change it to:
setTimeout(ert, 10000);
function ert()
var contactCard = document.querySelector('.card-contact');
contactCard.addEventListener('click', toggleThis);
Note that this is still not a good solution. You have many ways to solve your issue, depending on the coupling between the creation of the element, and its use. Without more of your code, we cannot give you a proper solution.
EDIT (I just refreshed and you added some code): The above code only gets the first element with the class .card-contact. If you want to keep this solution, you should probably use querySelectorAll and iterate over the elements found instead of using querySelector. Anyway, keep on reading.
One solution could be to return your element from the function that creates it, and add the listener on the returned element.
const card = buildCard(doc.data());
card.addEventListener(/* ... */);
Another one could be using callbacks, when you call the function to create the element, you pass a callback as parameter and call the callback inside the function, with the created element as parameter. Since what you're doing is not asynchronous, I don't really see an advantage to using a callback here.
function callback(card)
card.addEventListener(/* ... */);
buildCard(doc.data(), callback);
Another one could be using events, a custom emitter. When you're done creating your element, you dispatch an event to notify listeners that the element is created. You assign a listener on this event, to do all post-creation things.
myEmitter.addEventListener('card-created', /* ... */);
buildCard(doc.data()); // This function should fire 'card-created' on myEmitter
Another one... is to add a MutationObserver. I don't recommend it as it is overkill for your simple use-case. This would let you "observe" for changes in an element's child list, so you could detect when the card is added to its parent, then execute your code.
Hope this helps you.
(Note: This is my first activity on SO, so I cannot comment)
What I am trying to do is a simple chat. On the left is cards for the contacts. When I click the card it should load up the chat of the user, on the right.. like that. I am still not able to wrap around that only the first card responds to the event listener. I thought sharing classes is normal
– Taio
Mar 22 at 16:44
How does the iterator for thequeryselectorAllwork exactly
– Taio
Mar 22 at 16:45
querySelectorAll returns a NodeList, which can act kind of like an array. You could iterate over it with methods like forEach, or by indexing.
– pgiammel
Mar 22 at 22:14
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55296740%2fhow-can-i-set-event-listener-after-dom-is-loaded-by-classname%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The element does not exist yet when you try to access it.
Adding a 10 seconds delay after document.querySelector('.card-contact'); does not help since you try to find the element before waiting the 10 seconds.
To make this works:
var contactCard = document.querySelector('.card-contact');
setTimeout(ert, 10000);
function ert()
contactCard.addEventListener('click', toggleThis);
You should change it to:
setTimeout(ert, 10000);
function ert()
var contactCard = document.querySelector('.card-contact');
contactCard.addEventListener('click', toggleThis);
Note that this is still not a good solution. You have many ways to solve your issue, depending on the coupling between the creation of the element, and its use. Without more of your code, we cannot give you a proper solution.
EDIT (I just refreshed and you added some code): The above code only gets the first element with the class .card-contact. If you want to keep this solution, you should probably use querySelectorAll and iterate over the elements found instead of using querySelector. Anyway, keep on reading.
One solution could be to return your element from the function that creates it, and add the listener on the returned element.
const card = buildCard(doc.data());
card.addEventListener(/* ... */);
Another one could be using callbacks, when you call the function to create the element, you pass a callback as parameter and call the callback inside the function, with the created element as parameter. Since what you're doing is not asynchronous, I don't really see an advantage to using a callback here.
function callback(card)
card.addEventListener(/* ... */);
buildCard(doc.data(), callback);
Another one could be using events, a custom emitter. When you're done creating your element, you dispatch an event to notify listeners that the element is created. You assign a listener on this event, to do all post-creation things.
myEmitter.addEventListener('card-created', /* ... */);
buildCard(doc.data()); // This function should fire 'card-created' on myEmitter
Another one... is to add a MutationObserver. I don't recommend it as it is overkill for your simple use-case. This would let you "observe" for changes in an element's child list, so you could detect when the card is added to its parent, then execute your code.
Hope this helps you.
(Note: This is my first activity on SO, so I cannot comment)
What I am trying to do is a simple chat. On the left is cards for the contacts. When I click the card it should load up the chat of the user, on the right.. like that. I am still not able to wrap around that only the first card responds to the event listener. I thought sharing classes is normal
– Taio
Mar 22 at 16:44
How does the iterator for thequeryselectorAllwork exactly
– Taio
Mar 22 at 16:45
querySelectorAll returns a NodeList, which can act kind of like an array. You could iterate over it with methods like forEach, or by indexing.
– pgiammel
Mar 22 at 22:14
add a comment |
The element does not exist yet when you try to access it.
Adding a 10 seconds delay after document.querySelector('.card-contact'); does not help since you try to find the element before waiting the 10 seconds.
To make this works:
var contactCard = document.querySelector('.card-contact');
setTimeout(ert, 10000);
function ert()
contactCard.addEventListener('click', toggleThis);
You should change it to:
setTimeout(ert, 10000);
function ert()
var contactCard = document.querySelector('.card-contact');
contactCard.addEventListener('click', toggleThis);
Note that this is still not a good solution. You have many ways to solve your issue, depending on the coupling between the creation of the element, and its use. Without more of your code, we cannot give you a proper solution.
EDIT (I just refreshed and you added some code): The above code only gets the first element with the class .card-contact. If you want to keep this solution, you should probably use querySelectorAll and iterate over the elements found instead of using querySelector. Anyway, keep on reading.
One solution could be to return your element from the function that creates it, and add the listener on the returned element.
const card = buildCard(doc.data());
card.addEventListener(/* ... */);
Another one could be using callbacks, when you call the function to create the element, you pass a callback as parameter and call the callback inside the function, with the created element as parameter. Since what you're doing is not asynchronous, I don't really see an advantage to using a callback here.
function callback(card)
card.addEventListener(/* ... */);
buildCard(doc.data(), callback);
Another one could be using events, a custom emitter. When you're done creating your element, you dispatch an event to notify listeners that the element is created. You assign a listener on this event, to do all post-creation things.
myEmitter.addEventListener('card-created', /* ... */);
buildCard(doc.data()); // This function should fire 'card-created' on myEmitter
Another one... is to add a MutationObserver. I don't recommend it as it is overkill for your simple use-case. This would let you "observe" for changes in an element's child list, so you could detect when the card is added to its parent, then execute your code.
Hope this helps you.
(Note: This is my first activity on SO, so I cannot comment)
What I am trying to do is a simple chat. On the left is cards for the contacts. When I click the card it should load up the chat of the user, on the right.. like that. I am still not able to wrap around that only the first card responds to the event listener. I thought sharing classes is normal
– Taio
Mar 22 at 16:44
How does the iterator for thequeryselectorAllwork exactly
– Taio
Mar 22 at 16:45
querySelectorAll returns a NodeList, which can act kind of like an array. You could iterate over it with methods like forEach, or by indexing.
– pgiammel
Mar 22 at 22:14
add a comment |
The element does not exist yet when you try to access it.
Adding a 10 seconds delay after document.querySelector('.card-contact'); does not help since you try to find the element before waiting the 10 seconds.
To make this works:
var contactCard = document.querySelector('.card-contact');
setTimeout(ert, 10000);
function ert()
contactCard.addEventListener('click', toggleThis);
You should change it to:
setTimeout(ert, 10000);
function ert()
var contactCard = document.querySelector('.card-contact');
contactCard.addEventListener('click', toggleThis);
Note that this is still not a good solution. You have many ways to solve your issue, depending on the coupling between the creation of the element, and its use. Without more of your code, we cannot give you a proper solution.
EDIT (I just refreshed and you added some code): The above code only gets the first element with the class .card-contact. If you want to keep this solution, you should probably use querySelectorAll and iterate over the elements found instead of using querySelector. Anyway, keep on reading.
One solution could be to return your element from the function that creates it, and add the listener on the returned element.
const card = buildCard(doc.data());
card.addEventListener(/* ... */);
Another one could be using callbacks, when you call the function to create the element, you pass a callback as parameter and call the callback inside the function, with the created element as parameter. Since what you're doing is not asynchronous, I don't really see an advantage to using a callback here.
function callback(card)
card.addEventListener(/* ... */);
buildCard(doc.data(), callback);
Another one could be using events, a custom emitter. When you're done creating your element, you dispatch an event to notify listeners that the element is created. You assign a listener on this event, to do all post-creation things.
myEmitter.addEventListener('card-created', /* ... */);
buildCard(doc.data()); // This function should fire 'card-created' on myEmitter
Another one... is to add a MutationObserver. I don't recommend it as it is overkill for your simple use-case. This would let you "observe" for changes in an element's child list, so you could detect when the card is added to its parent, then execute your code.
Hope this helps you.
(Note: This is my first activity on SO, so I cannot comment)
The element does not exist yet when you try to access it.
Adding a 10 seconds delay after document.querySelector('.card-contact'); does not help since you try to find the element before waiting the 10 seconds.
To make this works:
var contactCard = document.querySelector('.card-contact');
setTimeout(ert, 10000);
function ert()
contactCard.addEventListener('click', toggleThis);
You should change it to:
setTimeout(ert, 10000);
function ert()
var contactCard = document.querySelector('.card-contact');
contactCard.addEventListener('click', toggleThis);
Note that this is still not a good solution. You have many ways to solve your issue, depending on the coupling between the creation of the element, and its use. Without more of your code, we cannot give you a proper solution.
EDIT (I just refreshed and you added some code): The above code only gets the first element with the class .card-contact. If you want to keep this solution, you should probably use querySelectorAll and iterate over the elements found instead of using querySelector. Anyway, keep on reading.
One solution could be to return your element from the function that creates it, and add the listener on the returned element.
const card = buildCard(doc.data());
card.addEventListener(/* ... */);
Another one could be using callbacks, when you call the function to create the element, you pass a callback as parameter and call the callback inside the function, with the created element as parameter. Since what you're doing is not asynchronous, I don't really see an advantage to using a callback here.
function callback(card)
card.addEventListener(/* ... */);
buildCard(doc.data(), callback);
Another one could be using events, a custom emitter. When you're done creating your element, you dispatch an event to notify listeners that the element is created. You assign a listener on this event, to do all post-creation things.
myEmitter.addEventListener('card-created', /* ... */);
buildCard(doc.data()); // This function should fire 'card-created' on myEmitter
Another one... is to add a MutationObserver. I don't recommend it as it is overkill for your simple use-case. This would let you "observe" for changes in an element's child list, so you could detect when the card is added to its parent, then execute your code.
Hope this helps you.
(Note: This is my first activity on SO, so I cannot comment)
edited Mar 22 at 10:52
answered Mar 22 at 10:26
pgiammelpgiammel
112
112
What I am trying to do is a simple chat. On the left is cards for the contacts. When I click the card it should load up the chat of the user, on the right.. like that. I am still not able to wrap around that only the first card responds to the event listener. I thought sharing classes is normal
– Taio
Mar 22 at 16:44
How does the iterator for thequeryselectorAllwork exactly
– Taio
Mar 22 at 16:45
querySelectorAll returns a NodeList, which can act kind of like an array. You could iterate over it with methods like forEach, or by indexing.
– pgiammel
Mar 22 at 22:14
add a comment |
What I am trying to do is a simple chat. On the left is cards for the contacts. When I click the card it should load up the chat of the user, on the right.. like that. I am still not able to wrap around that only the first card responds to the event listener. I thought sharing classes is normal
– Taio
Mar 22 at 16:44
How does the iterator for thequeryselectorAllwork exactly
– Taio
Mar 22 at 16:45
querySelectorAll returns a NodeList, which can act kind of like an array. You could iterate over it with methods like forEach, or by indexing.
– pgiammel
Mar 22 at 22:14
What I am trying to do is a simple chat. On the left is cards for the contacts. When I click the card it should load up the chat of the user, on the right.. like that. I am still not able to wrap around that only the first card responds to the event listener. I thought sharing classes is normal
– Taio
Mar 22 at 16:44
What I am trying to do is a simple chat. On the left is cards for the contacts. When I click the card it should load up the chat of the user, on the right.. like that. I am still not able to wrap around that only the first card responds to the event listener. I thought sharing classes is normal
– Taio
Mar 22 at 16:44
How does the iterator for the
queryselectorAll work exactly– Taio
Mar 22 at 16:45
How does the iterator for the
queryselectorAll work exactly– Taio
Mar 22 at 16:45
querySelectorAll returns a NodeList, which can act kind of like an array. You could iterate over it with methods like forEach, or by indexing.
– pgiammel
Mar 22 at 22:14
querySelectorAll returns a NodeList, which can act kind of like an array. You could iterate over it with methods like forEach, or by indexing.
– pgiammel
Mar 22 at 22:14
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55296740%2fhow-can-i-set-event-listener-after-dom-is-loaded-by-classname%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
The issue is obvious, the element doesn't exist in the DOM when you attempt to add the event handler, but we can't see why this is happening with the excerpt of the code you've shown. Can you add a complete example of the code - an MCVE would help too.
– Rory McCrossan
Mar 22 at 9:42
Also note that a single delegated handler may be a better approach, but again this is just conjecture without seeing a more complete example of your logic.
– Rory McCrossan
Mar 22 at 9:43
window.onload = () => ...in vanilla JS,$(document).ready(() => ...)in jQuery– iArcadia
Mar 22 at 9:59
document.readyis included– Taio
Mar 22 at 10:00
Just realized when I create 10 cards using a loop. Only the very first card responds to the event listener
– Taio
Mar 22 at 10:01