Attaching click event to a JQuery object not yet added to the DOM
Use this. You can replace body with any parent element that exists on dom ready
$('body').on('click', '#my-button', function () {
console.log("yeahhhh!!! but this doesn't work for me :(");
});
Look here http://api.jquery.com/on/ for more info on how to use on() as it replaces live() as of 1.7+.Below lists which version you should be using
$(selector).live(events, data, handler); // jQuery 1.3+$(document).delegate(selector, events, data, handler); // jQuery 1.4.3+
$(document).on(events, selector, data, handler); // jQuery 1.7+
Attaching click events to DOM elements that are not yet created (no jQuery)
A simpler solution (not involving delegation), would be
Refactor the click handler for li
lis.forEach(function(li){
li.addEventListener("click", handleLiClick);
function handleLiClick( event )
{
var thisObj = event.currentTarget;
thisObj.classList.toggle( "completed" )
console.log( thisObj.parentElement );
}
And then when you create an li
, bind the same click
handler to it then and therefilterInput.addEventListener("keypress", function(event){
if(event.which === 13){
var todo = filterInput.value;
var newLi = document.createElement("li")
var element = newLi.appendChild(document.createTextNode(todo));
ul.appendChild(newLi);
filterInput.value = " ";
newLi.addEventListener("click", handleLiClick); //this line has been added
}
});
Binding events to not yet created DOM elements (jquery)
jQuery.live() has been deprecated. Here is the accepted answer using jQuery.on() instead:
$(document).on('click', '#btn-remove-item', function() {
this.parentNode.removeChild(this);
});
How to add an Event Listener on elements that are not yet in the DOM [no-jQuery]?
You could parse your HTML string to a document
in JS and then add the event listener to that element.
So you've got your Template Literal string.
const messageFormatted = messageText => {
return `
<li class="message-item">
<img class="message-avatar" src="./icons/boy.png" alt="Username">
<article class="message-content">
<p class="author">Ernesto Campese</p>
<p class="message">${messageText}</p>
<p class="datetime">A moment ago</p>
</article>
<div class="message-actions">
<img id="message-edit" class="action-button" src="./icons/edit.png" alt="Sample Image" width="22" height="22">
<img id="message-delete" class="action-button" src="./icons/delete.png" alt="Sample Image" width="22" height="22">
</div>
</li>
`;
}
You can transform your string
into HTML by writing a function like the one below.It uses the
DOMParser API
which creates a new document
that will contain all of your HTML you've written in your string
.const parseStringToHTML = (str) => {
const parser = new DOMParser();
return parser.parseFromString(str, 'text/html');
};
And this document works like the one you have in your page, its just a new one that only exists in your JS memory for the time being. Give your string
as argument to parseStringToHTML
to create HTML.const message = messageFormatted('This is the message'); // Example message
const messageHTML = parseStringToHTML(message); // Returns a document object with all the features a document object has.
So now that your string
is a document
you can use methods on it like getElementById
, querySelector
, etc. But first you must select the element that you need.const messageDeleteButton = messageHTML.querySelector("#message-delete");
See that I've used messageHTML
instead of document
. In this scenario messageHTML
is a document
and therefor we can query inside of it. And now you've found your element inside this document
you can add an event listener to it.messageDeleteButton.addEventListener("click", (e) => {
e.parentNode.parentNode.remove();
});
Okay, so now the event listener has been added. All you have to do now is append the HTML you need from the messageHTML
into the document
of your page. The HTML can be found in the messageHTML.body
property.Now instead of insertAdjacentHTML
use insertAdjacentElement
to insert the element in the position of your choosing. The element you want to append is the <li class="message-item">
which would be the firstElementChild
in the body
of the messageHTML.body
property.
So in your submit
event listener of your form change the following line from:
messageList.insertAdjacentHTML("beforeend", messageFormatted(messageTextarea.value));
To all that I've explained above.// Create string
const message = messageFormatted(messageTextarea.value);
// String to document
const messageHTML = parseStringToHTML(message);
// Select delete element.
const messageDeleteButton = messageHTML.querySelector("#message-delete");
// Add event listener to delete element.
messageDeleteButton.addEventListener("click", (e) => {
e.parentNode.parentNode.remove();
});
// Append the <li> element to the messageList.
messageList.insertAdjacentElement("beforeend", messageHTML.body.firstElementChild);
Don't forget to include the parseStringToHTML
function in your code. I understand that this is a lot to work out so if you have any question please do ask.I hope that this will help you out.
Note I see that event delegation (global event listener) is not something you want to do, although as other have stated, it is more performant and easier to implement than other methods, even my own answer. It would also solve listening for elements that you've added or even removed from your list. You could set it even on the <ul id="message-list">
element like T.J. Crowder suggested.
Add event handler to an element that not yet exists using on()?
$('body').on('click','p#two', function() {
console.log('p#two clicked');
});
you can also use$(document).on('click', 'p#two', function() {
});
Read more about .on()
you can also use .delegate()
$('body').delegate('#two', 'click', function() {
});
Jquery .click() not work if HTML element not yet added
add the number sign # when calling the id of your div,
from
$("myDiv").on("click" ,".color-picker-icon" , function(){
alert("hi");
$("#color-picker-box").removeClass("display-none");
});
to$("#myDiv").on("click" ,".color-picker-icon" , function(){
alert("hi");
$("#color-picker-box").removeClass("display-none");
});
jQuery - how to attach handlers to elements which don't exist yet?
You can attach the click event to an already existing element, yet make it trigger only on certain children of that element, as follows:
$('.sidebarElement').on('click', 'span', function() {
//...
});
You can technically attach your event to $('body')
even, as long as the second argument (which is a jquery selector) is precise enough. I wouldn't recommend this method though as it surely has a negative impact on performance.For reference, take a look at jquery's .on() function.
Related Topics
How to Bind Bootstrap Popover on Dynamic Elements
Splicing a JavaScript Array from Within the Callback Passed to Foreach
How Does Appcelerator Titanium Mobile Work
Finding "Line-Breaks" in Textarea That Is Word-Wrapping Arabic Text
How to Update a Specific Index from the Array in Firestore
Why Is There a 'Null' Value in JavaScript
Check If Element Is Visible on Screen
Authorization of Google Drive Using JavaScript
Remove Zero-Width Space Characters from a JavaScript String
Get the Current Year in JavaScript
Problems with Circular Dependency and Oop in Angularjs
How to Use a Link to Call JavaScript
Calling a JavaScript Function Recursively