1. 程式人生 > >jquery的bind與on和live的使用

jquery的bind與on和live的使用

jquery的bind與on和live的使用

  • 使用.bind()方法非常浪費效能因為它把同一個事件處理函式附加到了每一個匹配的元素上
  • 你應該停止使用.live()方法因為它被棄用了同時也會帶來很多問題
  • 使用.delegate()方法會給你帶來很多好處當你需要解決一些效能上的問題和對動態新增的元素作出處理
  • 新的.on()方法其實就是模擬.bind() , .live() .delegate()實現的語法糖,具體取決於你如何呼叫它

bind繫結dom元素

bind()和unbind()提供了事件的繫結和取消機制,既可以繫結html預設支援的事件,也能夠繫結自定義的事件。

    $("#btnConfirm").bind('click',function(){
    	debugger;
        var $dg = $("#dglist");
        var rows = $dg.datagrid("getSelections");
        var renderSelectObj = parent.renderSelector;
        var _datas = [];
		for(var i=0,len=rows.length; i<len; i++){
			var dataItem = {};
				dataItem.code = rows[i].id;
				dataItem.name = rows[i].userName;
				dataItem.address = rows[i].address;
				dataItem.headPerson= rows[i].headPerson;
				dataItem.headPersonPhone= rows[i].headPersonPhone;
				dataItem.customerType= rows[i].customerType;
				_datas.push(dataItem);
		}
        	renderSelectObj.selectResultAfterCallback(_datas);
	});

			$("input[name='" + _keys[0] +"']").parent().parent().find("button").unbind('click').bind('click', function(){
				debugger;
				var action = "_self." + $(this).attr("action");
				eval(action);
			});

使用bind一次繫結多個事件和處理函式。

如果多個事件需要註冊相同的處理函式,那麼可以使用如下程式碼進行簡化(事件名稱使用空格分隔):

$("#button1").bind("mousedown mouseup",function(){  
   console.log(11);  
}); 

如果每個事件的處理函式不同,那麼可以使用如下的方式(json物件):

$("#button1").bind(  
    {  
        "mousedown":function(){  
            console.log("mousedown");  
       },  
       "mouseup":function(){  
            console.log("mouseup");  
       }  
     }  
); 

unbind用來取消之前通過bind繫結的事件處理函式,總的來說有三種形式:取消所有事件、取消某種型別的事件、取消某種型別下的某個事件處理函式。

 $("#button1").bind("click",func1);   
$("#button1").bind("click",func2);   
  
 // try to cancel function2  
$("#button1").unbind("click",func2);   
   
 function func1()  
 {  
     console.log("click1");    
}  
  
 function func2()  
{  
     console.log("click2");    
 } 

$("#button1").unbind():取消button1上所有已經繫結的事件處理函式。

$("#button1").unbind("click"):只取消button1上繫結的click型別的事件處理函式。

繫結匿名函式,點選時候執行函式體

		$("#listAdd").bind("click", function() {
			var gfyId=$("#gfyId").val();
			if(gfyId==null||gfyId==''){
				$Core.UI.message.error("請先選擇使用者");
				return false;
			}
			
			if(flag){
				$("#listAdd").gridselect({
				    title:'裝置資訊',
				    dialogWidth: '600', //視窗寬度 預設值600
				    dialogHeight: "400",//視窗高度 預設值 70%
				    searchFields: [  //搜尋條件
	    		        {
	    		            name: "deviceName", //separator 指定後會換行顯示
	    		            text: "裝置名稱",
	    		            type: "textbox",  //控制元件型別 只支援 簡單的表單控制元件 textbox my97 combobox 等簡單控制元件 如果條件過多 可以增加 separator 換行顯示
	    		            //url: "system/dic/getDicByCode/material_type",          //字典獲取路徑
	    		            width: '',   //寬度
	    		            querytype: "like",
	    		            //hidden: true, //是否隱藏域 預設否
	    		            value: '' //預設值
	    		        },
	    			        {
	    		            name: "gfy", //separator 指定後會換行顯示
	    		            text: "",
	    		            type: "textbox",  //控制元件型別 只支援 簡單的表單控制元件 textbox my97 combobox 等簡單控制元件 如果條件過多 可以增加 separator 換行顯示
	    		            //url: "system/dic/getDicByCode/material_type",          //字典獲取路徑
	    		            width: '',   //寬度
	    		            querytype: "eq",
	    		            hidden: true, //是否隱藏域 預設否
	    		            value: $("#gfyId").val() //預設值
	    		        }, 
	    		        {
	    		            name: "deviceState", //separator 指定後會換行顯示
	    		            text: "狀態",
	    		            type: "textbox",  //控制元件型別 只支援 簡單的表單控制元件 textbox my97 combobox 等簡單控制元件 如果條件過多 可以增加 separator 換行顯示
	    		            //url: "system/dic/getDicByCode/material_type",          //字典獲取路徑
	    		            width: '',   //寬度
	    		            querytype: "like",
	    		            hidden: true, //是否隱藏域 預設否
	    		            value: 1 //預設值
	    		        }
	    		       
	    		    ],
				    dgOpts: { //datagrid 引數
				        url: 'security/deviceuser/query',
				      /*  queryParams: {
				    		qqq	: '[{"name":"gfy","value":"'+$("#gfyId").val()+'","type":"like"}]',
				    		d:'fff'
				    	},*/
				    	/*onBeforeLoad:function(paras){
				    		 paras.querystra +="&id="+$("#gfyId").val();
				    	},*/
				        columns: [[
				                      { title: '裝置名稱', field: 'deviceName', align: 'center', sortable: false,formatter:function (value,row,index) {
				                           return $Core.DicCache.get("installdevName")[value];
				                       } },
									{ title: '裝置編號', field: 'deviceNumber', align: 'center', sortable: false },
									{ title: '單位', field: 'company', align: 'center', sortable: false},
									{ title: '數量', field: 'number', align: 'center', sortable: false },
									        ]]
									    },
				    //選擇一行時 被呼叫 return false 不會關掉視窗
				    onSelect: function (index, row) {
				        var materialId = row.materialId;
				        var isAppend = true;
				        $.each($("#dglist2").datagrid("getRows"), function (j,k) {
				            if (k.userDeviceId==userDeviceId) {
				                isAppend = false;
				            }
				        });
				        if (isAppend) {
				            $("#dglist2").datagrid("appendRow", row); 
				        }
				        return false;},
				    onClear: function () { //點選清空按鈕時被呼叫
				    	
				    }
				});
				flag = false;
			}	
			$("#listAdd").gridselect("show");
			
		});

live方法是固定把事件都繫結在了document上,而delegate 把事件綁定了提供的父元素上

delegate減少了冒泡次數,效率會更高些

live方法將與事件處理函式關聯的選擇器和事件資訊一起附加到文件的根級元素(即document)。通過將事件資訊註冊到document上,這個事件處理函式將允許所有冒泡到document的事件呼叫它(例如委託型、傳播型事件)。一旦有一個事件冒泡到document元素上,Jquery會根據選擇器或者事件的元資料來決定哪一個事件處理函式應該被呼叫,如果這個事件處理函式存在的話。

  • 這個方法在Jquery 1.7以後的版本被棄用了,你應該在你的程式碼裡逐步放棄使用它
  • 使用 event.stopPropogation() 方法將會沒用,因為事件總是已經被委託到了document元素上
  • 因為所有的選擇器或者事件資訊都被附加到document元素上了,所以一旦有一個事件要呼叫某個事件處理函式,Jquery會在一大堆儲存的元資料中使用matchesSelector方法來決定哪一個事件處理函式將會被呼叫,如果這個函式有的話。
$( "#members li a" ).live( "click", function( e ) {} );

$( "#members" ).delegate( "li a", "click", function( e ) {} );

.delegate()方法十分強大。在上面這個例子中,與事件處理函式關聯的選擇器和事件資訊將會被附加到( #members" )這個元素上。這樣做比使用live()高效多了,因為live()方法總是將與事件處理函式關聯的選擇器和事件資訊附加到document元素上。

  • 你可以選擇將選擇器或者事件資訊附加到指定的元素。
  • 匹配操作實際上在前面並沒有執行,而是用來註冊到指定的元素。
  • 鏈式操作可以得到正確的支援
  • Jquery仍然需要迭代這些選擇器或者事件資訊來匹配元素,不過因為你可以選擇哪一個元素作為根元素,所以篩選的量會大幅減少
  • 因為這項技術使用了事件委託機制,它可以匹配到被動態地新增到DOM的元素
  • 你可以在文件載入完之前連線事件處理函式

在Jquery 1.7版本中.bind() , .live() .delegate()方法只需要使用.on()方法一種方式來呼叫它們。當然.unbind() , .die() 和.undelegate()方法也一樣。一下程式碼片段是從Jquery 1.7版本的原始碼中截

原始碼

bind: function( types, data, fn ) {
 return this.on( types, null, data, fn );
},
unbind: function( types, fn ) {
 return this.off( types, null, fn );
},
 
live: function( types, data, fn ) {
 jQuery( this.context ).on( types, this.selector, data, fn );
 return this;
},
die: function( types, fn ) {
 jQuery( this.context ).off( types, this.selector || "**", fn );
 return this;
},
 
delegate: function( selector, types, data, fn ) {
 return this.on( types, selector, data, fn );
},
undelegate: function( selector, types, fn ) {
 return arguments.length == 1 ? 
  this.off( selector, "**" ) : 
  this.off( types, selector, fn );
}

如何使用.on()方法決定了它如何呼叫其他方法。你可以認為.on()方法被具有不同簽名的方法”過載“了,而這些方法實現了不同的事件繫結的連線方式。

/* Jquery的 .bind() , .live() 和 .delegate() 方法只需要使用`.on()`方法一種方式來呼叫它們 */
 
// Bind
$( "#members li a" ).on( "click", function( e ) {} ); 
$( "#members li a" ).bind( "click", function( e ) {} );
 
// Live
$( document ).on( "click", "#members li a", function( e ) {} ); 
$( "#members li a" ).live( "click", function( e ) {} );
 
// Delegate
$( "#members" ).on( "click", "li a", function( e ) {} ); 
$( "#members" ).delegate( "li a", "click", function( e ) {} );

有三個A標籤,點選其中一個後新增on樣式

<a href="javascript:void(0);" onclick="open('a');return false;" class="off">a</a>
<a href="javascript:void(0);" onclick="open('b');return false;" class="off">b</a>
<a href="javascript:void(0);" onclick="open('c');return false;" class="off">c</a>

$("a").parent().on("click", "a", function() {
    $(this).addClass("on").siblings("a").removeClass("on");
});