Search code examples
prototypejs

Really Weird Prototype JS Error - hide() function doesn't hide intended element


Ok. So I just started with Prototype JS demo. My first was a simple "hello world" library intro kinda demo.

There are two divs on the page. One is hidden by default.

Two buttons invoke show() and hide() methods of Prototype JS. When you click "Append" button the hidden div is visible, but when you click "Remove" (to invoke hide()) on the same div, it hides the source of the event i.e. remove button itself instead of the intended div (although ID given for $() function is correct)

Here is the code:

<script type="text/javascript">

             document.observe("dom:loaded", function() {


                 alert("loaded");
                 $('mydiv2').hide();

});

             function append()
             {
                 $('mydiv2').show();
             }

             function remove()
             {
                 $('mydiv2').hide();
             }


             </script>

<body>

        <div id='mydiv1'>

            This is my first Prototype Application

        </div>

        <div id='mydiv2'>

            This is appended text

        </div>



        <br/> <br/> <br/>

        <button id="b1" onclick="append();"> Append Text </button> | 
        <button id="b2" onclick="remove();"> Remove Text </button>

    </body>

Here, when you click "remove text" button, it hides the button itself instead of the intended "mydiv2" div

And here comes the real weirdness: This bug is observed in modern browsers (i.e. when tested on Chrome and IE 10). However, it works all fine when tested on IE7.

Here is the firebug console:

this._cps2 is undefined
[Break On This Error]   

Filtered chrome url chrome://browser/content/browser.js

browser.js (line 1557)

Can anybody plz explain me what is happening here?


Solution

  • OK here is what is happening.

    There is another method remove() http://api.prototypejs.org/dom/Element/prototype/remove/ that is a method on the actual button element. Because you are using the direct onclick attributes instead of observers the remove method of the element is fired instead of your observer. The reason it "works" in IE 7 is the way that the events are handled in IE 7.

    Here is how to fix it (and the prescribed way to handle events)

    First remove the onclick attributes of the buttons

    Then in your domloaded function add

    document.observe('dom:loaded',function(){
        $('b1').observe('click',append);
        $('b2').observe('click',remove);
    
    });
    

    And event behavior as intended is yours.

    JSfiddle with working example http://jsfiddle.net/sPLmM/