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;








0















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!");


);













share|improve this question
























  • 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.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

















0















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!");


);













share|improve this question
























  • 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.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













0












0








0


0






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!");


);













share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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.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

















  • 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.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
















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












1 Answer
1






active

oldest

votes


















1














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)






share|improve this answer

























  • 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











  • 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











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
);



);













draft saved

draft discarded


















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









1














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)






share|improve this answer

























  • 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











  • 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















1














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)






share|improve this answer

























  • 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











  • 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













1












1








1







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)






share|improve this answer















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)







share|improve this answer














share|improve this answer



share|improve this answer








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 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

















  • 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











  • 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



















draft saved

draft discarded
















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

용인 삼성생명 블루밍스 목차 통계 역대 감독 선수단 응원단 경기장 같이 보기 외부 링크 둘러보기 메뉴samsungblueminx.comeh선수 명단용인 삼성생명 블루밍스용인 삼성생명 블루밍스ehsamsungblueminx.comeheheheh

155 수학 과학 기타 둘러보기 메뉴eh추가해eh문서를 완성해