mvc-2事件監聽

現代瀏覽器都支持的事件

  • click
  • dbclick
  • mouseover
  • mousemove
  • mouseout
  • focus
  • blur
  • change(表單輸入框特有)
  • submit(表單特有)

addEventListener/removeEventListenr

  • 注意若是第二個參數是匿名函數的話,不銷燬這個元素節點則監聽不會中止;
第三參數 對應事件 效果 取消事件
true 事件捕捉 從外向內傳播
false 事件冒泡 從內向外傳播 e.stopPropagation()
  • 阻止默認行爲: e.preventDefault() / return false

事件對象

  • 事件類型
    • bubbles: 表示事件是否經過DOM以冒泡形式觸發
  • 環境信息屬性
    • button:表示鼠標所按下的按鈕
      • 0:左
      • 1:中
    • ctrlKey/altKey/shiftKey 表示是否按下相應鍵
  • 鍵盤事件屬性
    • isChar:表示當前按下的鍵是否表示一個字符
    • charCode:表示當鍵的unicode值(僅對keypress有效)
    • keyCode:表示非字符按鍵的unicode值
    • which:表示當前按鍵的unicode值,無論是不是字符
  • 事件發生的環境參數
    • pageX/pageY:相對於可視區域的座標
    • screenX,screenY:想對於屏幕的座標
  • 和事件相關的元素
    • currentTarget:事件冒泡階段當前所在的DOM元素
    • target,originateTarget:原始的DOM元素
    • relatedTarget:其餘和事件相關的DOM元素(有的話)

切換上下文

  • 在addEventListener()方法中的執行函數中,上下文已經切換到當前監聽的節點,若是想改變,請使用以前提到的方法

事件委託

  • 從冒泡事件開始就開始了事件委託;能夠直接給父元素綁定事件監聽
list.addEventListener("click", function(e) {
  if(e.currentTarget.tagName == "LI") {
    /**/
  }
}, false)

自定義事件

以jquery插件爲例;下面代碼使用自定義事件讓代碼變得整潔,在點擊選項卡時觸發一個change.tabs事件,並綁定若干回調方法來修改active類html

<ul id="tabs">
  <li data-tab="user">Users</li>
  <li data-tab="group">Groups</li>
</ul>
<div id="tabsContent">
  <div data-tab="user">user</div>
  <div data-tab="group">group</div>
</div>
jQuery.fn.tabs = function(control) {
  var elem = $(this);
  control = $(control);

  elem.on("click", "li", function() {
    var tabName = $(this).attr("data-tab");
    elem.trigger("change.tabs", tabName);
  });
  elem.on("change.tabs", function(e, tabName) {
    elem.find("li").removeClass("active");
    elem.find(">[data-tab='" + tabName + "']").addClass("active");    
  });
  elem.on("change.tabs", function(e, tabName) {
    control.find(">[data-tab]").removeClass("active");
    control.find(">[data-tab='" + tabName + "']").addClass("active");
  });

  //將切換選項卡的動做和窗口的hash作關聯,這樣能夠使用瀏覽器的退後按鈕
  elem.on("change.tabs", function(e, tabName) {
    window.location.hash = tabName;
  });
  $(window).on("hashchange", function() {
    var tabName = window.location.hash.slice(1);
    elem.trigger("change.tabs", tabName);
  })

  var firstName = elem.find("li:first").attr("data-tab");
  elem.trigger("change.tabs", firstName);
  return this;
}

$("ul#tabs").tabs("#tabsContent");

DOM無關事件

  • 基於事件的編程能夠使應用框架充分解耦,事件本質上是和DOM無關的,所以能夠開發事件驅動的庫;
  • 這種模式稱爲發佈/訂閱的消息模式,發佈者和訂閱者是徹底解耦的,彼此不知道對方的存在,二者僅僅共享一個信道名稱;
  • 應用這種模式只須要記錄回調和事件名稱的對應關係及調用他們的方法;
var PubSub = {
  //訂閱
  subscribe: function(ev, callbacks) {
  //雙重賦值
    var calls = this._callbacks || (this._callbacks = {});
    (this._callbacks[ev] || (this._callbacks[ev] = [])).push(callbacks);
    return this;
  },
  //發佈
  publish: function() {
    var args = Array.prototype.slice.call(arguments, 0);
    var ev = args.shift();
    var list, calls, i, l;
    if(!(calls = this._callbacks)) return this;
    if(!(list = this._callbacks[ev])) return this;
    for(i = 0, l = list.length; i < l; i++) list[i].apply(this, args);
    return this;
  }
}

PubSub.subscribe("wem", function() {});
PubSub.publish("wem");
//能夠使用命名空間的方式管理事件名稱
PubSub.subscribe("user:create", function() {});

將其擴充到一個局部對象jquery

var Asset = {};
jQuery.extend(Asset, PubSub);
Asset.subscribe("test", function() {alert("test")});
Asset.publish("test");

使用jquery實現該模式編程

(function($) {
  var o = $({});
  $.subscribe = function() {
    o.bind.apply(o, arguments);
  };
  $.unsubscribe = function() {
    o.unbind.apply(o, arguments);
  };
  $.publish = function() {
    var arguments = $.makeArray(arguments);
    var type = arguments[0];
    arguments.shift();
    o.trigger.apply(o, [type, arguments]);
  }
})(jQuery);

$.subscribe("/some/topic", function(event, a, b, c) {
  console.log(event.type, a + b +c);
});
$.publish("/some/topic","a","b","c");
相關文章
相關標籤/搜索