Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

addEventListener only works on last object

In the following code, it seems I only get the 'otherboxclick' call for the last box added (b1). If I change the order the boxes are added, it's always just the last one that works.

How can I get it to work for all the boxes?

<html>
<head>
</head>
<body>

<script type="text/javascript">
    function otherboxclick(e){
        alert("other clicked");
    }

    function color_toggle_box(boxid, color, width, height, xpos, ypos)
    {
        this.boxid = boxid;

        document.body.innerHTML += 
            "<div id='" + boxid + "'; '; style='position:absolute;left:" + xpos + "px;top:" + 
            ypos +"px;width:" + width + "px;height:" + height + 
            "px;background:#000'></div>";


        this.boxdiv = document.getElementById(boxid);
        this.boxdiv.style.background = color;
        this.boxdiv.addEventListener('click', otherboxclick, true);
    }

    var b2 = new color_toggle_box("223", "#ff0", 100, 100, 205, 100);
    alert("b2 = " + b2.boxid);
    var b3 = new color_toggle_box("323", "#0ff", 100, 100, 100, 205);
    alert("b3 = " + b3.boxid);
    var b1 = new color_toggle_box("123", "#0f0", 100, 100, 100, 100);
    alert("b1 = " + b1.boxid);
</script>

</body>
</html>
like image 435
Doug Banks Avatar asked Oct 14 '25 15:10

Doug Banks


2 Answers

To explain why Lior's code works and yours doesn't:

document.body.innerHTML +=

is always a mistake. It turns your document objects into an HTML string, adds some text to that string, then re-parses the whole HTML back in to make new document objects that replace all the old ones.

In the best case, this will work but is just a bit slow. However a worse side-effect is that any information that doesn't serialise to HTML will be completely lost. That includes form field values, JavaScript properties and references, and event listeners. So, every time you construct a color_toggle_box, you are destroying all the objects you previously had listeners on; hence the listeners will never be called.

like image 171
bobince Avatar answered Oct 18 '25 13:10

bobince


    function color_toggle_box(boxid, color, width, height, xpos, ypos)
    {
        this.boxid = boxid;

        this.boxdiv = document.createElement('DIV');
        this.boxdiv.id = boxid;
        this.boxdiv.style.position = 'absolute';
        this.boxdiv.style.left = xpos + "px";
        this.boxdiv.style.top = ypos + "px";
        this.boxdiv.style.width = width + "px";
        this.boxdiv.style.height = height + "px";
        this.boxdiv.style.backgroundColor = color;

        document.body.appendChild(this.boxdiv);
        this.boxdiv.addEventListener('click', otherboxclick, true);
    }
like image 34
Lior Cohen Avatar answered Oct 18 '25 12:10

Lior Cohen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!