Rib_Eye
Rib_Eye

Reputation: 11

How to add an event listener to html created by an object in JavaScript

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

Answers (3)

enhzflep
enhzflep

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

Nicolas Bouvrette
Nicolas Bouvrette

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

Shaunak D
Shaunak D

Reputation: 20636

onclick

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

Related Questions