views:

37

answers:

2

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'));
    }
    });
});​
A: 

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.

Marc B
It does not meter, even without destroy(); it does not work repeated.
Binyamin
I think he is onto something in the last line. You may need to reattach the event.
Shane Reustle
+1  A: 

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.

Dimitar Christoff
Thanks a lot! It works excellent!
Binyamin