0

I have a problem detatching a mouseout event from a div. I pulled the function from this forum (link). Its purpose is to prevent event-bubbling. It works like a charm, but detatching fails. Ik keeps multiplying the eventhandlers every time I attach and detach. After hours of trying... maybe someone else has the answer :-)

my HTML:

<div id="dd_301" onclick="dd_show(this,301)">
    <span id="sel_301">selected item</span>
    <div id="sel_A301" style="display:none">
        <div id="sel_B3010" onclick="dd_click(this,1)">option 1</div>
        <div id="sel_B3011" onclick="dd_click(this,2)">option 2</div>
    </div>
</div>

the javascript:

function dd_show(p, i) {
    getObj('sel_A' + i).style.display = 'block';
    addEvent(p, 'mouseout', makeMouseOutFn(p));
}

function dd_remove(o) {
    removeEvent(o,'mouseout',makeMouseOutFn);
    o.getElementsByTagName('div')[0].style.display = 'none';
}

function dd_click(o,i){
   var p=o.parentNode.parentNode;
   dd_remove(o);
   }

function addEvent(elem, ev, fn) {
    function listenHandler(e) {
        var ret = fn.apply(this, arguments);
        if (ret === false) {
            e.stopPropagation();
            e.preventDefault();
        }
        return (ret);
    }

    function attachHandler() {
        var ret = fn.call(elem, window.ev);
        if (ret === false) {
            window.ev.returnValue = false;
            window.ev.cancelBubble = true;
        }
        return (ret);
    }
    if (elem.addEventListener) {
        elem.addEventListener(ev, listenHandler, false);
    } else {
        elem.attachEvent("on" + ev, attachHandler);
    }
}

function removeEvent(o, ev, fn) {
    if (o.removeEventListener) {
        o.removeEventListener(ev, fn, false);
    } else {
        if (o.detachEvent) {
            o.detachEvent(ev, fn);
        }
    }
}

function makeMouseOutFn(elem) {
    var list = traverseChildren(elem);
    return function onMouseOut(event) {
        var e = event.toElement || event.relatedTarget;
        if ( !! ~list.indexOf(e)) {
            return;
        }
        alert('MouseOut');
    };
}

function traverseChildren(elem) {
    var children = [];
    var q = [];
    q.push(elem);
    while (q.length > 0) {
        var elem = q.pop();
        children.push(elem);
        pushAll(elem.children);
    }

    function pushAll(elemArray) {
        for (var i = 0; i < elemArray.length; i++) {
            q.push(elemArray[i]);
        }
    }
    return children;
}

[EDIT] In the end, it was the bubbling that somehow prevented the removal of the onclick. Adding

if('bubbles' in event){if(event.bubbles){event.stopPropagation();}}else{event.cancelBubble=true;}

did the trick

Community
  • 1
  • 1
Michel
  • 4,076
  • 4
  • 34
  • 52
  • Yick. Is there some reason why you can't use jQuery and replace all that code with 2 lines? – aquinas Jan 18 '13 at 17:34
  • 1
    You have not included the source of `dd_click`. None of the included code calls `removeEvent`. And I agree with aquinas - jQuery will make this much easier. – George Jan 18 '13 at 17:39
  • Added dd_click() and the correct line in dd_remove. Which at the moment only calls dd_remove. The reason I don't use jQuery is because this is about as much js I use, and I don't want to load the whole library if not nessecery. – Michel Jan 19 '13 at 06:51
  • Can you add a jsfiddle so that we can work on it... – Wolf Jan 19 '13 at 07:10

0 Answers0