Binyamin
Binyamin

Reputation: 7803

Mootools `Events` works just on first `click`, after stops working. Why?

Mootools Events works just on first click, after stops working.
Hope someone have issue for that: http://jsfiddle.net/3j3Ws/
CSS

ul li,li.selected div{
    width:22px;
    height:22px;
    display:block;
    background:#000;
    color:#fff;
    text-align:center;
    border-radius:3px;
}
ul#list{
    display:none;
    opacity:0;
    float:left;
}

HTML

<ul id="option">
    <li class="selected" id="a">a</li>
    <ul id="list">
        <li id="b">b</li>
        <li id="c">c</li>
        <li id="d">d</li>
    </ul>
</ul>​

Mootools JavaScript

window.addEvent('domready', function(){
    var x = '<div>v</div>';
    $$('ul#option li.selected').set('html',x);
    var opt = $$('ul#option li.selected div');
    var d = opt.getStyle('display');
    var l = document.id('list');
    var list = opt.set('morph').addEvents({
        click:function(){
            l.store('timerA',(function(){
                l.morph({
                    'display':'block',
                    'opacity':1
                });
             $$('ul#option li.selected').setStyle('background-color','#fff');
             $$('ul#option li.selected div').destroy();
            }).delay(10,this));//$clear(this.retrieve('timerA'));
        }
    }
    );
    l.set('morph').addEvents({
    mouseleave:function(el){
        this.store('timerB',(function(){
            this.morph({
                'display':d,
                'opacity':0
            });
            $$('ul#option li.selected').removeProperties('style');
            $$('ul#option li.selected').set('html',x);
        }).delay(500,this));//$clear(this.retrieve('timerB'));
    }
    });
});​

Upvotes: 0

Views: 318

Answers (2)

Marc B
Marc B

Reputation: 360762

It's most likely this:

         $$('ul#option li.selected div').destroy();

At that point, you're deleting the <div>v</div> that you inserted earlier and had attached the click event to.

In the mouseleave later, you do:

        $$('ul#option li.selected').set('html',x);

which recreates the div, but has not also reattached the click handler to the new copy.

comment followup:

when you use the .set('html', x), you're replacing the original node with a new one, which also replaces the event handlers. Handlers are attached to an actual node, not to the node's location in the DOM tree.

Upvotes: 0

Dimitar Christoff
Dimitar Christoff

Reputation: 26165

odd writing style you have.

anyway. it is the destroy. the events are not delegated. i.e. your selector is the first div but that's a physical element that gets a UID and a functional cllback against that.

by doing .destroy() you are removing this div from the dom and even if you reinsert it after, because you don't use event delegation, the event will no longer work (events are part of element storage so destroy removes them too).

check out http://jsfiddle.net/dimitar/3j3Ws/1/ -> proves it can work fine (i added mootools more for easy .show() and .hide() but you can just use .setStyle("display", "none").

alternatively, look at doing an event for document.id("option") as click:relay(div.down) and mod the x html to have class='down' - then the code you have at the moment will keep.

Upvotes: 1

Related Questions