Reputation: 63
I am currently struggling copying the innerHTML part of classes to another div. The problem is that I am using the same class name for every div but each div has another content. I want to achieve that based on a EventListener the innerHTML of the clicked div is copied to another div. So I basically want that If someone clicks on a emoji in div.emoji--select the same emoji is copied into div#text. With my current JavaScript code my innerHTML ends up as undefined. I am currently trying to save each innerHTML of every div.emoji--select to an array and then use it in my function addEmoji(). I would highly appreciate your help. Please only plain JavaScript.
My HTML
<div id="text_wrapper">
<div id="text" contentEditable="true" hidefocus="true"></div>
</div>
<span class="emoji--select" >😛</span>
<span class="emoji--select">😂</span>
My JavaScript
//Select clicked emoji in div.emoji--select
var emojiText = []
var emojiSelect = document.getElementsByClassName('emoji--select')
for (var i = 0; i <= emojiSelect.length; i++) {
emojiText.push(emojiSelect[i].innerHTML)
emojiSelect[i].addEventListener('click', function() {
addEmoji(emojiText[i])
})
}
//Add Emoji to div#text
function addEmoji(emojiSelected) {
var text = document.getElementById('text')
text.append(emojiSelected)
}
Upvotes: 2
Views: 223
Reputation: 68943
Try the following:
var emojiText = []
var emojiSelect = document.getElementsByClassName('emoji--select');
for (var i = 0; i < emojiSelect.length; i++) {
emojiText.push(emojiSelect[i].outerHTML)
emojiSelect[i].addEventListener('click', function() {
addEmoji(this);
})
}
function addEmoji(emojiSelected) {
var elem = emojiSelected.cloneNode(true)
text.append(elem);
}
<div id="text_wrapper">
<div id="text" contentEditable="true" hidefocus="true"> </div>
</div>
<span class="emoji--select" >😛</span>
<span class="emoji--select">😂</span>
Upvotes: 3
Reputation: 2841
The problem you are having is one of context. The way your current code executes is that i
exists in a parent scope of your loop from the anonymous event handler. When an event is handled, the handler looks at the nearest definition of i
, which after the loop is completed, is 2.
To fix the scoping issue, you should use a self-invoking function to create a new shell for i
.
for (var i = 0, len = emojiSelect.length; i < len; i++) {
emojiText.push(emojiSelect[i].innerHTML);
(function(i) {
emojiSelect[i].addEventListener('click', function() {
addEmoji(emojiText[i]);
});
})(i);
}
Also note that I changed the the loop definition to store the array length and to iterate i < len
instead of i <= len
. You were looping one too many times.
Upvotes: 3