此设置没有任何问题(或存在吗?),但是我可以对其进行一些平滑处理吗?
看一下使用事件委托。在那儿,您可以在不会消失的容器上实际监视事件,然后使用event.target(或event.srcElement在IE上)找出事件的实际发生位置并正确处理。
这样,您只需附加一次处理程序,即使您换出内容,它们也将继续工作。
这是不使用任何帮助程序库的事件委托的示例:
(function() {
  var handlers = {};
  if (document.body.addEventListener) {
    document.body.addEventListener('click', handleBodyClick, false);
  }
  else if (document.body.attachEvent) {
    document.body.attachEvent('onclick', handleBodyClick);
  }
  else {
    document.body.onclick = handleBodyClick;
  }
  handlers.button1 = function() {
    display("Button One clicked");
    return false;
  };
  handlers.button2 = function() {
    display("Button Two clicked");
    return false;
  };
  handlers.outerDiv = function() {
    display("Outer div clicked");
    return false;
  };
  handlers.innerDiv1 = function() {
    display("Inner div 1 clicked, not cancelling event");
  };
  handlers.innerDiv2 = function() {
    display("Inner div 2 clicked, cancelling event");
    return false;
  };
  function handleBodyClick(event) {
    var target, handler;
    event = event || window.event;
    target = event.target || event.srcElement;
    while (target && target !== this) {
      if (target.id) {
        handler = handlers[target.id];
        if (handler) {
          if (handler.call(this, event) === false) {
            if (event.preventDefault) {
              event.preventDefault();
            }
            return false;
          }
        }
      }
      else if (target.tagName === "P") {
        display("You clicked the message '" + target.innerHTML + "'");
      }
      target = target.parentNode;
    }
  }
  function display(msg) {
    var p = document.createElement('p');
    p.innerHTML = msg;
    document.body.appendChild(p);
  }
})();
现场例子
请注意,如果您单击动态添加到页面的消息,那么即使没有代码可以挂接正在添加的新段落上的事件,您的单击也会被注册和处理。还要注意,您的处理程序如何只是映射中的条目,而您在上有一个处理程序document.body可以执行所有调度。现在,您可能将其植根于比更具针对性的目标document.body,但您明白了。另外,在上文中,我们基本上是通过调度的id,但是您可以根据需要进行复杂或简单的匹配。
诸如jQuery,Prototype,YUI,Closure或其他任何一种之类的现代JavaScript库都应提供事件委托功能,以平滑浏览器差异并清晰地处理边缘情况。jQuery确实做到了,它live和delegate功能,允许您使用全套的CSS3选择器(然后一些)的指定处理。
例如,这是使用jQuery的等效代码(除非我确定jQuery可以处理上述即时可用的原始版本无法处理的极端情况):
(function($) {
  $("#button1").live('click', function() {
    display("Button One clicked");
    return false;
  });
  $("#button2").live('click', function() {
    display("Button Two clicked");
    return false;
  });
  $("#outerDiv").live('click', function() {
    display("Outer div clicked");
    return false;
  });
  $("#innerDiv1").live('click', function() {
    display("Inner div 1 clicked, not cancelling event");
  });
  $("#innerDiv2").live('click', function() {
    display("Inner div 2 clicked, cancelling event");
    return false;
  });
  $("p").live('click', function() {
    display("You clicked the message '" + this.innerHTML + "'");
  });
  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }
})(jQuery);
即时复制