Enable/Disable events of DOM elements with JS / jQuery

随声附和 提交于 2021-02-18 11:19:29

问题


I stuck here with a little problem I have put pretty much time in which is pretty bad compared to its functionality.

I have tags in my DOM, and I have been binding several events to them with jQuery..

var a = $('<a>').click(data, function() { ... })

Sometimes I would like to disable some of these elements, which means I add a CSS-Class 'disabled' to it and I'd like to remove all events, so no events are triggered at all anymore. I have created a class here called "Button" to solve that

var button = new Button(a)
button.disable()

I can remove all events from a jQuery object with $.unbind. But I would also like to have the opposite feature

button.enable()

which binds all events with all handlers back to the element OR maybe there is a feature in jQuery that actually nows how to do that?!

My Button Class looks something similar to this:

Button = function(obj) {
  this.element = obj
  this.events = null

  this.enable = function() {
    this.element.removeClass('disabled')
    obj.data('events', this.events)
    return this
  }

  this.disable = function() {
    this.element.addClass('disabled')
    this.events = obj.data('events')
    return this
  }
}

Any ideas? Especially this rebind functionality must be available after disable -> enable

var a = $('<a>').click(data, function() { ... })

I found these sources that did not work for me: http://jquery-howto.blogspot.com/2008/12/how-to-disableenable-element-with.html

http://forum.jquery.com/topic/jquery-temporarily-disabling-events -> I am not setting the events within the button class

Appreciate your help.


回答1:


$("a").click(function(event) {
    event.preventDefault(); 
    event.stopPropagation(); 
    return false;
});

Returning false is very important.

Or you could write your own enable and disable functions that do something like:

function enable(element, event, eventHandler) {
    if(element.data()[event].eventHandler && !eventHandler) { //this is pseudo code to check for null and undefined, you should also perform type checking
        element.bind(event, element.data()[event]);

    }
    else (!element.data()[event] && eventHandler) {
        element.bind(event, element.data()[event]);
        element.data({event: eventHandler}); //We save the event handler for future enable() calls
    }
}

function disable(element, event) {
    element.unbind().die();
}

This isn't perfect code, but I'm sure you get the basic idea. Restore the old event handler from the element DOM data when calling enable. The downside is that you will have to use enable() to add any event listener that may need to be disable() d. Otherwise the event handler won't get saved in the DOM data and can't be restored with enable() again. Currently, there's no foolproof way to get a list of all event listeners on an element; this would make the job much easier.




回答2:


I would go on this with different approach:

<a id="link1">Test function</a>
<a id="link2">Disable/enable function</a>

<script type="text/javascript">
  $(function() {
      // this needs to be placed before function you want to control with disabled flag
      $("#link1").click(function(event) {
          console.log("Fired event 1");
          if ($(this).hasClass('disabled')) {
              event.stopImmediatePropagation();
          }
      });

      $("#link1").click(function() {
          console.log("Fired event 2");
      });

      $("#link2").click(function() {
          $("#link1").toggleClass("disabled");
      });
  });
</script>

This may not be what you require, since it may effect also other functions binded into this event later. The alternative may be to modify the functions itself to be more like:

$("#link1").click(function(event) {
    console.log("Fired event 1");
    if ($(this).hasClass('disabled')) {
       return;
    }

    // do something here
});

if that is an option.




回答3:


Instead of adding event handler to each element separately, you should use event delegation. It would make much more manageable structure.

  • http://www.sitepoint.com/javascript-event-delegation-is-easier-than-you-think/
  • http://cherny.com/webdev/70/javascript-event-delegation-and-event-hanlders
  • http://brandonaaron.net/blog/2010/03/4/event-delegation-with-jquery

This why you can just check for class(es) on clicked element , and act accordingly. And you will be able even to re-eanble them , jsut by changing the classes of a tag.

P.S. read the links carefully, so that you can explain it to others later. Event delegation is a very important technique.




回答4:


You could use an <input type="button"> and then use $("#buttonID").addAttr('disabled', 'disabled'); and $("#buttonID").removeAttr('disabled');. Disabling and enabling will be handled by the browser. You can still restyle it to look like an anchor, if you need that, by removing backgrounds and borders for the button. Be aware though, that some margins and padding might still bugger u in some browsers.



来源:https://stackoverflow.com/questions/8249641/enable-disable-events-of-dom-elements-with-js-jquery

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!