So, I'm trying to add an "edit" button before dynamic "post" is shown in the <div>
. I want to add event listener to this "edit" button when clicked. However, it works as desired(onclick works and "edit clicked" is printed on console) only when I append this "edit" at certain position in my code(code-2), ie, when there is no change to the innerHTML of parent <div>
after appending this button, but that's not how the UI is demanded.
When it is not working, CODE-1(this is where I want "edit" in UI)
let post_div = document.createElement('div');
let edit = document.createElement('div');
edit.style.color = 'blue';
edit.innerHTML = 'Edit';
post_div.append(edit);
let htmlsegment2 = `
<div id="post-data">${post.post_data}</div>
<div style="color: grey;">${post.timestamp}</div>`;
post_div.innerHTML += htmlsegment2;
edit.onclick = function(){
console.log("edit clicked");
}
post_div.className = 'all-posts';
document.querySelector('#all-posts').append(post_div);
When I change the position of appended line, it starts working CODE-2
let post_div = document.createElement('div');
let edit = document.createElement('div');
edit.style.color = 'blue';
edit.innerHTML = 'Edit';
let htmlsegment2 = `
<div id="post-data">${post.post_data}</div>
<div style="color: grey;">${post.timestamp}</div>`;
post_div.innerHTML += htmlsegment2;
edit.onclick = function(){
console.log("edit clicked");
}
post_div.append(edit);
post_div.className = 'all-posts';
document.querySelector('#all-posts').append(post_div);
The key difference is the order of these 2 statements, which is different between the two examples:
1:
post_div.append(edit);
2:
post_div.innerHTML += htmlsegment2;
In the first (non-working) snippet, 1) happens first, then 2). The problem here is that 2) completely replaces the innerHTML
of the post_div
. It replaces it with a copy of what was there before, with the content of htmlsegment2
added at the end. It's just a shorthand for:
post_div.innerHTML = post_div.innerHTML + htmlsegment2;
and hopefully seeing it in that form makes it clearer that the entire innerHTML
gets thrown away and then replaced. Although the result will still contain the same HTML content, it importantly won't maintain the presence of the DOM element you've called edit
as a child of post_div
. This means that when you later set edit.onclick
, you're setting an attribute of an element that isn't actually in the DOM - therefore nothing noticeable actually happens.
In the second snippet, 2) happens first, which means that edit
is appended to post_div
and not replaced thereafter - so any manipulations of edit
do apply to an element in the actual DOM.
Hopefully that makes sense as to what the difference is between the two snippets. I would say as a general point that your code has some issues - assigning strings of HTML directly to the innerHTML
property isn't very maintainable, and using the +=
operator with innerHTML
has some common gotchas, of which your question is an example (and it's also quite inefficient). And it's much better to use the addEventListener
method than assign to the onclick
property (although both are much better than inline event listeners in HTML, admittedly).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.