Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Page 1 of 2 12 LastLast
Results 1 to 15 of 18
  1. #1
    Senior Coder BarrMan's Avatar
    Join Date
    Feb 2005
    Location
    Israel.
    Posts
    1,644
    Thanks
    69
    Thanked 83 Times in 82 Posts

    RemoveEvent Does Not Work

    Hey,
    I'm trying to use the removeEvent function to clear an "onclick" event from my anchor.

    It does not work for some reason and I have no idea why.
    Can anyone help me please with this code:

    Thanks:

    Code:
    img = document.getElementById("image"+i);
    			anchor = document.getElementById("anchor"+i);
    			img.src = directory + image[first+i-times];
    			img.alt = image[first+i-times];
    			anchor.HRef="#";
    			/*anchor.setAttribute("onclick",null); Ignore this*/
    			removeEvent(anchor,"click",evtHandle);
    			evtHandle = (function(id)
    			{
    			    return function()
    			    {
    			        changePic(id);
    			        changeInfo(id);
    			        return false;
    			    };
    			})(first+i-times);
    			addEvent(anchor,"click",evtHandle);
    evtHandle is a global variable.

  • #2
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    I can't help you much until you post your code for addEvent and removeEvent.

    However, if you substitute these definitions into your code, does your it work?
    Code:
    var addEvent = window.addEventListener
      ? function(el, t, f) {
          el.addEventListener(t, f, false);
        }
      : function(el, t, f) {
          el.attachEvent("on" + t, f);
        };
    
    var removeEvent = window.removeEventListener
      ? function(el, t, f) {
          el.removeEventListener(t, f, false);
        }
      : function(el, t, f) {
          el.detachEvent("on" + t, f);
        };
    Trinithis

  • Users who have thanked Trinithis for this post:

    oesxyl (04-29-2008)

  • #3
    Senior Coder BarrMan's Avatar
    Join Date
    Feb 2005
    Location
    Israel.
    Posts
    1,644
    Thanks
    69
    Thanked 83 Times in 82 Posts
    Oh, Sorry, I forgot about that

    Code:
    function addEvent(obj, type,fn)
    {
    	if(obj.attachEvent)
    	{
    		obj["e"+type+fn] = fn;
    		obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
    		obj.attachEvent( "on"+type, obj[type+fn] );
    	}
    	else if(obj.addEventListener)
    		obj.addEventListener(type,fn,false);
    	else
    	    obj["on"+type] = fn;
    }
    
    function removeEvent( obj, type, fn ) {
      if ( obj.detachEvent ) {
        obj.detachEvent( 'on'+type, obj[type+fn] );
        obj[type+fn] = null;
      } else
        obj.removeEventListener( type, fn, false );
    }
    Here it is.

    Edit: The removeEvent function throws an error on IE.
    Last edited by BarrMan; 04-29-2008 at 02:34 PM.

  • #4
    SSJ
    SSJ is offline
    Regular Coder
    Join Date
    Mar 2007
    Posts
    230
    Thanks
    0
    Thanked 4 Times in 4 Posts
    Quote Originally Posted by BarrMan View Post
    Oh, Sorry, I forgot about that

    Code:
    function addEvent(obj, type,fn)
    {
    	if(obj.attachEvent)
    	{
    		obj["e"+type+fn] = fn;
    		obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
    		obj.attachEvent( "on"+type, obj[type+fn] );
    	}
    	else if(obj.addEventListener)
    		obj.addEventListener(type,fn,false);
    	else
    	    obj["on"+type] = fn;
    }
    
    function removeEvent( obj, type, fn ) {
      if ( obj.detachEvent ) {
        obj.detachEvent( 'on'+type, obj[type+fn] );
        obj[type+fn] = null;
      } else
        obj.removeEventListener( type, fn, false );
    }
    Here it is.
    Yes I think this is the perfect code

  • #5
    Senior Coder BarrMan's Avatar
    Join Date
    Feb 2005
    Location
    Israel.
    Posts
    1,644
    Thanks
    69
    Thanked 83 Times in 82 Posts
    Bump.

  • #6
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    Works for me.

    I would not turn the function into a string to store it in the object's events propery. That is too wasteful. I would recommend an array that stores the function and then you can compare against identity.

    Also, you could enhance the window.event object before you toss it into the handler so it behaves like a firefox event. Eg: window.event.target = window.event.srcElement.

    Code I used to test it.
    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
    <html>
    <head>
    <title>Test</title>
    </head>
    <body><div>
    
    <div id="message">Click Me</div>
    
    <script type="text/javascript">
    
    function addEvent(obj, type,fn)
    {
      if(obj.attachEvent)
      {
        obj["e"+type+fn] = fn;
        obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
        obj.attachEvent( "on"+type, obj[type+fn] );
      }
      else if(obj.addEventListener)
        obj.addEventListener(type,fn,false);
      else
          obj["on"+type] = fn;
    }
    
    function removeEvent( obj, type, fn ) {
      if ( obj.detachEvent ) {
        obj.detachEvent( 'on'+type, obj[type+fn] );
        obj[type+fn] = null;
      } else
        obj.removeEventListener( type, fn, false );
    }
    
    function testClick(e) {
      var el = e.target
        ? e.target
        : e.srcElement;
      alert("turning off the handler for '" + el.id + "'");
      try {
        removeEvent(el, "click", arguments.callee);
        alert("no error");
      }
      catch(ex) {
        alert("error!")
      }
    }
    
    var div = document.getElementById("message");
    
    addEvent(div, "click", testClick);
    
    </script>
    </div></body>
    </html>
    Last edited by Trinithis; 04-30-2008 at 07:26 PM.
    Trinithis

  • Users who have thanked Trinithis for this post:

    BarrMan (05-01-2008)

  • #7
    Senior Coder BarrMan's Avatar
    Join Date
    Feb 2005
    Location
    Israel.
    Posts
    1,644
    Thanks
    69
    Thanked 83 Times in 82 Posts
    Hey. Thanks!

    It works for me when I try your page but it doesn't seem to work on my page. It somehow has something to do with the variable evtHandle which contains the 2 functions. How can I remove this event?

    Also, I'm not too sure what arguments.callee mean.

  • #8
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    arguments.callee means the function that is currently in execution. In this case, you could replace it with testClick if you really wanted to, but arguments.callee is slightly better. If you modify your code and change the name of the function, you have one less place to change. The real benefit though happens when you do something like this:

    Code:
    function fact(n) {
      return n * fact(n - 1);
    }
    
    var f = fact;
    
    fact = function() {
      alert("Fun fact: the function f won't recurse properly!");
    }
    Code:
    function fact(n) {
      return n * arguments.callee(n - 1);
    }
    
    var f = fact;
    
    fact = function() {
      alert("Fun fact: the function f will recurse properly!");
    }
    Trinithis

  • #9
    Senior Coder BarrMan's Avatar
    Join Date
    Feb 2005
    Location
    Israel.
    Posts
    1,644
    Thanks
    69
    Thanked 83 Times in 82 Posts
    Oh, Thanks I see that now.
    But still, my first problem isn't solved.

    How can I make the same thing I did on my code and be able to remove the events later on?

  • #10
    Senior Coder BarrMan's Avatar
    Join Date
    Feb 2005
    Location
    Israel.
    Posts
    1,644
    Thanks
    69
    Thanked 83 Times in 82 Posts
    Bump.

  • #11
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    You need to post more code. I can't deduce anything from what's already here.
    Trinithis

  • #12
    Senior Coder BarrMan's Avatar
    Join Date
    Feb 2005
    Location
    Israel.
    Posts
    1,644
    Thanks
    69
    Thanked 83 Times in 82 Posts
    Here, try this:
    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
    <html>
    <head>
    <title>Test</title>
    </head>
    <body><div>
    
    <div id="message">Click Me</div>
    
    <script type="text/javascript">
    
    function addEvent(obj, type,fn)
    {
      if(obj.attachEvent)
      {
        obj["e"+type+fn] = fn;
        obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
        obj.attachEvent( "on"+type, obj[type+fn] );
      }
      else if(obj.addEventListener)
        obj.addEventListener(type,fn,false);
      else
          obj["on"+type] = fn;
    }
    
    function removeEvent( obj, type, fn ) {
      if ( obj.detachEvent ) {
        obj.detachEvent( 'on'+type, obj[type+fn] );
        obj[type+fn] = null;
      } else
        obj.removeEventListener( type, fn, false );
    }
    
    function testClick(e) {
      var el = e.target
        ? e.target
        : e.srcElement;
      alert("turning off the handler for '" + el.id + "'");
      try {
        removeEvent(el, "click",evtHandle);// arguments.callee);
        alert("no error");
      }
      catch(ex) {
        alert("error!")
      }
    }
    
    var div = document.getElementById("message");
    var evtHandle = function(){return function(){testClick();return false;};};
    addEvent(div, "click", evtHandle);
    
    </script>
    </div></body>
    </html>

  • #13
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    The solution:
    Code:
    var evtHandle = function(e) {
      testClick(e);
      return false;
    };
    I revamped the addEvent code, but it is not needed for your code to work. But it is better.
    Code:
    function addEvent(el, type, f) {
      if(el.addEventListener)
        el.addEventListener(type, f, false);
      else if(el.attachEvent) {
        if(!el.evtHandlers)
          el.evtHandlers = [];
        var hldObj;
        for(var i = el.evtHandlers.length - 1; i >= 0; --i) {
          hldObj = el.evtHandlers[i];
          if(hldObj.type === type && hldObj.callback === f)
            return;  // if the handler already exists, don't add it
        }
        hldObj = {
          type: type,
          callback: f,
          handler: function() {
            var e = window.event;
            e.target = e.srcElement;
            // add more standard attributes to e here
            f(e);
          }
        };
        el.evtHandlers.push(hldObj);
        el.attachEvent("on"+type, hldObj.handler);
      }
      else
        el["on"+type] = f;
      el = null;
    }
    
    function removeEvent(el, type, f) {
      if(el.removeEventListener)
        el.removeEventListener(type, f, false);
      else if(el.detachEvent) {
        if(!el.evtHandlers)
          return;  // return if no handler attached
        var hldObj;
        for(var i = el.evtHandlers.length - 1; i >= 0; --i) {
          hldObj = el.evtHandlers[i];
          if(hldObj.type === type && hldObj.callback === f)
            break;
        }
        if(i === -1)
          return;  // return if the handler does not exist
        el.evtHandlers.splice(i, 1);
        el.detachEvent("on"+hldObj.type, hldObj.handler);
      }
      else
        el["on"+type] = null;
    }
    Last edited by Trinithis; 05-03-2008 at 09:42 PM.
    Trinithis

  • #14
    Senior Coder BarrMan's Avatar
    Join Date
    Feb 2005
    Location
    Israel.
    Posts
    1,644
    Thanks
    69
    Thanked 83 Times in 82 Posts
    Hey, Thanks for the reply.

    The problem still remains. You've change my function's structure and that's why it works. The function structure is necessary because it doesn't work otherwise.

    Can you try to make it work with the current structure?
    Code:
    function(){return function(){testClick(e); return false;};}
    Thanks!

  • #15
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    What you have:
    Code:
    function evtHandle() {
      return function() { // really should have the e parameter
        testClick(e);
        return false;
      };
    }
    Event handlers always have the form:
    Code:
    function(e) {
      do something
    };
    You can leave out the e parameter in the function if you never use it inside. In that case, arguments[0] is equal to the event object.

    So in your case, whenever the event is triggered, your event handler does the following:
    • It simply returns a function and does nothing else.

    In essense it does absolutely nothing!

    What your evtHandle function does do is generate an event handling function (assuming you fix it by adding the e parameter to the returned function):
    Code:
    addEvent(el, "click", evtHandle()); // note evtHandle is being called!
    However, this adds an anonymous function to el. And it should be noted that anyonymous functions cannot be removed if added using DOM methods (addEventListener / attachEvent).

    The only way to remove it is to keep a reference to the anonymous function:
    Code:
    // functions compare by identity
    alert(evtHandle() === evtHandle());  // false
    var hdl = evtHandle();
    alert(hdl ===  hdl);  // true
    
    // The following won't work because evtHandle() generates a new function
    addEvent(el, "click", evtHandle()); // adds the event, but it cannot be removed
    removeEvent(el, "click", evtHandle()); // oops! not same function
    
    // This works
    addEvent(el, "click", hdl);
    removeEvent(el, "click", hdl);
    Sorry, you're stuck. There's nothing you can do about it except change your game plan.
    Trinithis


  •  
    Page 1 of 2 12 LastLast

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •