jQuery attributes提供了文檔節點的屬性操作方法。
為了更好的理解,我們先解決jQuery core中的access參數設置函數。
?
jQuery.access
jQuery.access是一個專用于參數設置以及讀取的方法。
在 jQuery鏈式操作 中我們對BigInteger的值獲取是通過方法val來獲取的,很顯然此時val后面不能再鏈式操作了。所以:
如果要讀取參數值,那么這個操作就不能鏈式操作。
/* ************************ * elems: 接受操作的元素組 * fn: 設置或讀取函數 * key: 要設置的屬性 * value: 要設置的值,也可以是函數 * chainable: 是否可以鏈式操作,即是讀還是寫操作 * emptyGet: 讀取如果為空用什么表示 * raw: value能否直接傳給fn,如果的確就是想將屬性設置成函數value,那么要把這個值設成true */ jQuery.access = function ( elems, fn, key, value, chainable, emptyGet, raw ) { var i = 0 , length = elems.length, // key是否為空 bulk = key == null ; // 設置許多屬性 if ( jQuery.type( key ) === "object" ) { chainable = true ; for ( i in key ) { // 迭代執行設置一個值 jQuery.access( elems, fn, i, key[i], true , emptyGet, raw ); } // 只設置一個值 } else if ( value !== undefined ) { chainable = true ; // 如果value不是函數 if ( ! jQuery.isFunction( value ) ) { raw = true ; } // 如果key為空 if ( bulk ) { // 如果raw為true,即value不是函數 if ( raw ) { // 執行fn,其this為elems,參數為value fn.call( elems, value ); fn = null ; // 如果value是函數 } else { // 用bulk保存fn bulk = fn; // 將fn變成特定形式 fn = function ( elem, key, value ) { return bulk.call( jQuery( elem ), value ); }; } } // 如果fn存在 if ( fn ) { // 遍歷所有elems for ( ; i < length; i++ ) { // value是函數則運行fn(elem, key, value.call(elem, i, fn(elem, key))) // value非函數則運行fn(elem, key, value) fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); } } } // 如果是可鏈式操作的則返回elems return chainable ? elems : // 否則則是讀取操作 bulk ? fn.call( elems ) : // 否則如果長度不為0,則返回fn( elems[0], key ),否則返回空 length ? fn( elems[0 ], key ) : emptyGet; }
jQuery官方文檔沒有該函數,應該說這是jQuery的一個內部工具。主要是為了實現jQuery中設置與讀取復用性邏輯以及其內循環的,也就是為了節省寫代碼而已。
?
jQuery.fn.attr()
fn也就是jQuery實例對象的方法集。
fn中的方法attr也就是我們常用的attr方法。
如獲取em標簽的title屬性:
var
title = $("em").attr("title");
那么這個函數式怎么實現的呢?
jQuery.fn.attr = function ( name, value ) { return jQuery.access( this , jQuery.attr, name, value, arguments.length > 1 ); };
當參數長度為0或只為1時,則是讀取操作,不能鏈式操作。
而這里用的設置函數是jQuery.attr,即實際運行時會運行jQuery.attr(elem, name, value)。
那么jQuery.attr是如何實現的呢?
/* ************************** * elem: 要操作的元素 * name: 元素的屬性名 * value: 要改變的值 */ jQuery.attr = function ( elem, name, value ) { var ret, hooks, notxml, nType = elem.nodeType; // 不處理text,comment,attribute節點 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { return ; } // 如果屬性不支持則使用jQuery.prop if ( typeof elem.getAttribute === "undefined" ) { return jQuery.prop( elem, name, value ); } // 是否不是XML notxml = nType !== 1 || ! jQuery.isXMLDoc( elem ); // 如果不是XML if ( notxml ) { // 那么所有屬性名應當是小寫 name = name.toLowerCase(); // 如果屬性定義了,那么就抓住必要的鉤子,解決IE6-9的相關問題 hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); } // 如果value不是沒有定義,即寫入操作 if ( value !== undefined ) { // 如果value為空,則是刪除操作 if ( value === null ) { jQuery.removeAttr( elem, name ); // 如果鉤子有set方法,則設置了之后,返回其值 } else if ( hooks && notxml && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { return ret; // 否則使用setAttribute方法 } else { elem.setAttribute( name, value + "" ); return value; } // 如果是讀取操作,如果鉤子有get方法,則通過get得到返回值 } else if ( hooks && notxml && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { return ret; // 如果沒有get方法 } else { // IE9+中Flash對象沒有.getAttrubute方法,判斷防止錯誤 if ( typeof elem.getAttribute !== "undefined" ) { ret = elem.getAttribute( name ); } // 返回undefined或則值 return ret == null ? undefined : ret; } };
?
jQuery.removeAttr
removeAttr = function ( elem, value ) { var name, propName, i = 0 , // 分解value成為多個屬性的數組 attrNames = value && value.match( core_rnotwhite ); // 如果有要刪除的屬性名 if ( attrNames && elem.nodeType === 1 ) { // 遍歷所有屬性名 while ( (name = attrNames[i++ ]) ) { // 看看需不需要用propFix來修改名字,不用直接用name propName = jQuery.propFix[ name ] || name; // 如果屬性是布爾量先改成false if ( rboolean.test( name ) ) { elem[ propName ] = false ; } // 刪除屬性 elem.removeAttribute( name ); } } };
jQuery.propFix干了什么呢?
實際只是修改一下屬性名,比如很多人喜歡用class來表示css類名,但實際上是className。
jQuery.propFix = { tabindex: "tabIndex" , readonly: "readOnly" , "for": "htmlFor" , "class": "className" , maxlength: "maxLength" , cellspacing: "cellSpacing" , cellpadding: "cellPadding" , rowspan: "rowSpan" , colspan: "colSpan" , usemap: "useMap" , frameborder: "frameBorder" , contenteditable: "contentEditable" };
?
jQuery.fn.removeAttr
這個函數實現比較簡單,只是用each方法來調用jQuery.removeAttr而已。
jQuery.fn.removeAttr = function ( name ) { return this .each( function () { jQuery.removeAttr( this , name ); }); };
?
jQuery.fn.prop
jQuery.fn.prop = function ( name, value ) { return jQuery.access( this , jQuery.prop, name, value, arguments.length > 1 ); };
可見jQuery.fn.prop和jQuery.fn.attr差不多。
?
jQuery.prop
jQuery.prop = function ( elem, name, value ) { var ret, hooks, notxml, nType = elem.nodeType; if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { return ; } notxml = nType !== 1 || ! jQuery.isXMLDoc( elem ); if ( notxml ) { // 修復name和鉤子 name = jQuery.propFix[ name ] || name; hooks = jQuery.propHooks[ name ]; } if ( value !== undefined ) { if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { return ret; } else { return ( elem[ name ] = value ); } } else { if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { return ret; } else { return elem[ name ]; } } };
由于和jQuery.attr差不多,就不備注了。
?
jQuery.fn.removeProp
removeProp = function ( name ) { name = jQuery.propFix[ name ] || name; return this .each( function () { // try/catch handles cases where IE balks (such as removing a property on window) try { this [ name ] = undefined; delete this [ name ]; } catch ( e ) {} }); };
removeProp相對簡單些,只是通過each將所有元素的屬性設為undefined然后delete掉而已。
?
Attrubute和Property
從源代碼我們可以發現,jQuery.attr如果找不到相應的方法會使用jQuery.prop。
jQuery 1.6加入jQuery.prop方法后,對很多人來說可能根本沒啥用,因為用jQuery.attr方法肯定是對的。
但jQuery.attr和jQuery.prop到底差別在哪里呢?
這是Attrubute和Property的差別。
jQuery.attr方法會處理Attrubute和Property,但jQuery.prop只處理Property。
雖然這兩個單詞都可以翻譯成“屬性”,但是這兩個實際上是不同的。
我們用一個例子來說明這個問題:
function Demo(){ var attrs = {}; this .name = "Bob" ; this .setAttr = function (name, value){ attrs[name] = value; return value; } this .getAttr = function (name){ return attrs[name]; } }
那么對于一個實例:
var i = new Demo(); i.name // Property i.setAttr("name", "Tom" ); i.getAttr( "name") // Attrubute
所以jQuery文檔中對jQuery.prop的解釋是: 獲取在匹配的元素集中的第一個元素的屬性值。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
