on繫結
$("div").on("click mouseenter click.Liang", function(){});
off解綁
$("div").off();
$("div").off("click.sjl");
//對於_addEventFn(){}函式的解釋
//events屬性是以下的格式
div.events = {
click : {
sjl : function(){
console.log();
},
yl : function(){
},
anonymous : [fn, fn, fn] //存放沒有自定義名字的事件函式值
},
mouseenter : {
anonymous : [fn, fn, fn],
sjl : function(){
},
yl : function(){
}
},
}
複製程式碼
//阻止預設行為的相容
if(!Event.prototype.preventDefault){
Event.prototype.preventDefault = function(){
window.event.returnValue = false;
};
}
//阻止冒泡的相容
if(!Event.prototype.stopPropagation){
Event.prototype.stopPropagation = function{
window.event.cancelBubble = true;
};
}
//將新增到dom身上的事件函式儲存起來的方法
function _addEventFn(data){
//dom:節點 type:事件陣列 fn:事件函式
//之前從來沒繫結過任何事件,把它變成一個物件
if(typeof data.dom.events === "undefined"){
data.dom.events = {};
}
//之前沒有繫結過相同型別的事件
if(typeof data.dom.events[data.type[0]] === "undefined"){
data.dom.events[data.type[0]] = {};
data.dom.events[data.type[0]].anonymous = [];
//anonymous是一個陣列,存放匿名函式
}
//type是陣列,類似["mouseenter", "sjl"] 或者["click"]
//判斷有沒有自定義事件的名字 存事件函式
if(data.type[1] === undefined){
//如果為undefined,說明是匿名函式,存放到anonymous屬性對應的陣列中
data.dom.events[data.type[0]].anonymous.push(data.fn);
}else{
data.dom.events[data.type[0]][data.type[1]] = data.fn;
// data.dom.events[data.type[0]]代表事件 例如click
}
}
//相容removeEventListener
function _removeEvent(dom, type, fn, bool){
//v, key1, v.events[key1].anonymous[j], false
if(dom.removeEventListener){
//主流
dom.removeEventListener(type, fn, !!bool);
}else{
//ie
dom.detachEvent("on"+type, fn);
}
}
//原型裡的方法
Liang.prototype = function(){
constructor : Liang,
init : function(){}, //(1)
html : function(){}, //(2)
//事件繫結
on : function(eventType, fn){
//非字串不做操作
if(typeof eventType !== "string") return;
var arr = eventType.trim().split(/\s+/);
for(var i = 0, len = this.length; i < len; i++){
(function(i, that){
//that當前jq物件中的元素
for(var j = 0, len = var.lenght; j < len; j++ ){
var type = arr[j].split(/\./),
eventFnName = null;
if(type[0] === "mousewheel"){
//需要判斷火狐及其他瀏覽器的事件
function _eventWheelFn(e){
var dir = e.wheelDelta / 120 || -e.detail / 3;
fn.call(that, e, dir) === false && e.preventDefault();
}
type[0] = (that.onmousewheel === null) ? "mousewheel" : "DOMMouseScroll";
eventFnName = _eventWheelFn;
}else{
function _eventFn(e){
e = e || window.event;
fn.call(that, e) === false && e.preventDefault;
}
eventFnName = _eventFn;
}
that.addEventListener ?
that.addEventListener(type[0], eventFnName, false) :
that.attachEvent("on"+type[0], eventFnName);
//儲存對應事件函式
_addEventFn({
dom : that,
type : type,
fn : eventFnName
});
}
}(i, this[i]))
}
return this;
},
//事件解綁
off : function(){
if(typeof eventType === "undefined"){
//解綁所有事件
Liang.each(this, function(v){
// v 當前進來的元素
for(var key1 in v.events){
// key1 是事件型別的名字 例如 click mouseenter
for(var key2 in v.events[key1]){
// key2 是事件型別物件中自定義的名字 例如 sjl
if(Liang.type(v.events[key1][key2]) === "function"){
//給自定義名字的事件解綁函式
_removeEvent(v, key1, v.events[key1][key2],false);
}else{
//給anonymous陣列中的函式解綁
var len = v.events[key1].anonymous.length;
for(var j = 0; j < len; j++){
//解綁anonymous陣列內的函式
_removeEvent(v, key1, v.events[key1].anonymous[j], false);
}
}
}
}
v.events = {}; //清空events裡所有資料
});
}else if(typeof eventType === "string"){ //例如 "click.yl mouseenter.sjl"
var arr = eventType.trim().split(/\s+/); //["click.yl", "mouseenter.sjl"]
//判斷輸入的為[""],則不作操作
if(arr.toString() === "") return this;
//對事件名陣列的遍歷
for(var i = 0, len = arr.length; i < len; i++){
var type = arr[i].split(/\./); //["click","yl"],["mouseenter","sjl"]
//遍歷例項物件,取到元素,解綁元素身上對應的事件
Liang.each(this, function(v){
//判斷是否火狐,修改對應的事件名
if(type[0] === "mousewheel"){
//判斷滾動事件是否在火狐或者主流瀏覽器執行
type[0] = (v.onmousewheel === null) ? "mousewheel" : "DOMMouseScroll";
}
if(type.length > 1){
//解綁自定義名的事件函式
_removeEvent(v, type[0], v.events[type[0]][type[1]], false);
delete v.events[type[0]][type[1]];
}else{
//解綁同型別事件
//解綁對應事件的所有匿名事件 例如$("div").off("click")
for(var j = 0, len = v.events[type[0]].anonymous.length; j < len; j++){
_removeEvent(v, type[0], v.events[type[0]].anonymous[j], false);
}
//解綁該事件型別中有名的 例如$("div").off("click.yl")
for(var k in v.events[type[0]]){
// k是自定義屬性名 sjl yl //判斷在不在陣列的原型上.false則表示不在,說明是function,取反
if(!(v.events[type[0]][k] instanceof Array)){
//自定義名字的事件屬性值
_removeEvent(v, type[0], v.events[type[0]][k], false);
}
}
delete v.events[type[0]];
}
});
}
}
},
}
複製程式碼