Reputation: 11
I'm creating objects in JavaScript that contain html, which are basically buttons that contain dynamically created words and do functions that use those words. I need to be able to attach onclick event handlers on them either when they're created or afterwards.
var MyClass = function(word) {
this.word = word;
this.wordHtml = '<span class="option">' + word + '</span>';
var wordArea = document.getElementById('wordArea');
this.displayWordButton = function() {
wordArea.innerHTML += this.wordHtml;
};
}
var myObject = new MyClass("sampleWord");
myObject.displayWordbutton();
It's adding all the buttons correctly but I can't get them to be clickable.
I've tried myObject.onclick = sampleFunction();
but it seems to activated the click event when the object is created and not when actually clicked.
I've tried adding an onclick attribute directly to the span in the class, but it doesn't function.
Upvotes: 1
Views: 568
Reputation: 13099
Here's how I'd consider going about it.
There's a few changes from your code, I've chucked-out element creation via string concatenation. I've added the ability for the created objects to be appended to any element when the displayWordButton
is pressed, as well as the option of none, which then requires (and allows) manual insertion anywhere in the DOM.
I've used proper handlers, instead of inline ones.
Here 'tis:
<!DOCTYPE html>
<html>
<head>
<script>
"use strict";
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
// this element will have #wordArea as its parent
var myObject = new MyClass("sampleWord", "wordArea");
myObject.displayWordButton();
// these elements may be parented by anyone
var digits = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
for (var i=0; i<digits.length; i++)
{
myObject = new MyClass(digits[i]+" ");
document.body.appendChild(myObject);
}
}
function MyClass(word, idOfFixedTargetOrEmpty)
{
var mElem = document.createElement('span');
mElem.originalWord = word;
mElem.classList.add('option');
mElem.appendChild( document.createTextNode(word) );
mElem.addEventListener('click', function(){alert(this.originalWord);}, false);
mElem.displayWordButton = function()
{
if (idOfFixedTargetOrEmpty !== undefined)
document.getElementById(idOfFixedTargetOrEmpty).appendChild(this);
};
return mElem;
}
</script>
<style>
</style>
</head>
<body>
<div id='wordArea'></div>
</body>
</html>
Upvotes: 0
Reputation: 4757
You need to stop using innerHTML
and start using objects. Afterall JavaScript's entire design is made out of objects. Here would be a remake of your code using objects which you can easily add events to:
var MyClass = function(word) {
this.word = word;
this.wordElement = document.createElement('span');
this.wordElement.classList.add('option');
this.wordElement.appendChild(document.createTextNode(word));
this.wordElement.addEventListener('click', function() {
alert('hello world');
});
var wordArea = document.getElementById('wordArea');
this.displayWordButton = function() {
wordArea.appendChild(this.wordElement);
};
};
var myObject = new MyClass("sampleWord");
myObject.displayWordButton();
Upvotes: 3
Reputation: 20636
Syntax :
element.onclick = *functionRef*;
-where functionRef is a function - often a name of a function declared elsewhere or a function expression.
Issue :
myObject.onclick = sampleFunction();
will call the function as soon as it is loaded as func()
is a function call.
Solution :
Use a reference to the function,
myObject.onclick = sampleFunction;
or if you need to pass args to the click handler,
myObject.onclick = function(){
sampleFunction(args)
};
Upvotes: 1