jQuery的屬性操作模塊總共有4個部分,本篇說一下第1個部分:HTML特性部分,html特性部分是對原生方法getAttribute()和setAttribute()的封裝,用于修改DOM元素的特性的
jQuery的靜態方法含有如下API:
- $.attr(elem, name, value) ;設定或讀取html屬性,該方法有三種用法:
·$.attr(elem,name,null) ;如果value為null則呼叫jQuery.removeAttr(elem, name)洗掉該屬性
·$.attr(elem,name,value) ;設定elem元素的name屬性值為value,
·$.attr(elem,name) ;獲取elem元素的name屬性
- $.removeAttr(elem, name) ;從DOM元素elem上移除name屬性,name可以是單個字串,也可以是空格分隔的多個html屬性,對于應布爾屬性會同步設定對應的DOM屬性為false,
jQuery/$ 實體方法(可以通過jQuery實體呼叫的):
- attr(name, value) ;移除、設定html屬性,有以下方法
·attr(obj) ;引數1是物件時 ;access()函式中驗證 表示一次性設定多個屬性
·attr(name,value) ;為每個匹配元素設定一個HTML屬性 ;value可以是一個函式,取值為回傳值,也可以為null時表示洗掉該屬性
·attr(name,NULL) ;引數2為NULL時表示洗掉所有匹配元素的name特性,間接呼叫removeAttr()
·attr(name) ;引數1是字串時,引數2未指定或者設定為false ;表示獲取第一個匹配元素的HTML屬性值,
- removeAttr(name) ;移除每一個匹配元素的一個或多個HTML屬性,name是要是移除的html屬性,多個可以用空格分隔
舉個栗子:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script> </head> <body> <a>鏈接</a> <button>淘寶</button> <!--點擊后a標簽將導航到淘寶--> <button>百度</button> <!--點擊后a標簽將導航到百度--> <button>移除</button> <!--點擊后a標簽將取消導航--> <script> let a = document.getElementsByTagName('a')[0], //獲取a標簽的參考 b1 = document.getElementsByTagName('button')[0], //淘寶按鈕的參考 b2 = document.getElementsByTagName('button')[1], //百度按鈕的參考 b3 = document.getElementsByTagName('button')[2]; //移除按鈕的參考 b1.addEventListener('click',function(){ $.attr(a,'href','http://www.taobao.com'); //通過jQuery的靜態方法設定href屬性 }) b2.addEventListener('click',function(){ $('a').attr('href','http://www.baidu.com') //通過jQuery的實體方法設定href屬性 }) b3.addEventListener('click',function(){ $("a").removeAttr('href') //移除href屬性 }) </script> </body> </html>
渲染的頁面如下:

此時對應的DOM結構如下:

當我們點擊淘寶按鈕后頁面變為了如下:

DOM修改了這樣子:

此時點擊這個a標簽將鏈接到淘寶網,然后我們點擊百度,鏈接會鏈接到百度去的,最后點擊移除時,該a標簽又會變為初始化的狀態,這就是jQuery的html特性操作
原始碼分析
$.attr和$.removeAttr實作如下:
jQuery.extend({ attr: function( elem, name, value, pass ) { //設定或讀取html屬性,是對原生方法getAttribute()和setAttribute()的簡化 var ret, hooks, notxml, nType = elem.nodeType; // don't get/set attributes on text, comment and attribute nodes if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { //如果elem為空 或者是文本、注釋、屬性節點 return; //直接回傳,不接著處理 } if ( pass && name in jQuery.attrFn ) { return jQuery( elem )[ name ]( value ); } // Fallback to prop when attributes are not supported if ( typeof elem.getAttribute === "undefined" ) { //如果不支持方法getAttribute return jQuery.prop( elem, name, value ); //則呼叫對應的DOM屬性 } notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); //判斷elem是否不是xml檔案元素 // All attributes are lowercase // Grab necessary hook if one is defined if ( notxml ) { name = name.toLowerCase(); hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); } if ( value !== undefined ) { //如果傳入了引數value,表示是設定值 if ( value =https://www.cnblogs.com/greatdesert/p/== null ) { //若值是null,則移除該name屬性 jQuery.removeAttr( elem, name ); return; } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { //優先呼叫對應的修正物件的修正方法set() return ret; } else { elem.setAttribute( name, "" + value ); //否則呼叫原生方法setAttribute()設定html屬性 return value; } } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { //如果未傳入引數value,優先呼叫對應的修正物件的修正方法get() return ret; } else { ret = elem.getAttribute( name ); //否則呼叫原生方法getAttrubute()讀取html屬性, // Non-existent attributes return null, we normalize to undefined return ret === null ? undefined : ret; } }, removeAttr: function( elem, value ) { //從DOM元素上移除一個或多個html屬性,多個html屬性用空格分隔,是對removeAttribute的封裝和擴展, var propName, attrNames, name, l, i = 0; if ( value && elem.nodeType === 1 ) { //如果設定了value引數 且 elem是一個元素節點 attrNames = value.toLowerCase().split( rspace ); //執行后attrNames是一個陣列,保存了要移除的屬性名:比如:Array [ "id", "name" ] rspace = /\s+/, l = attrNames.length; //需要移除的屬性的個數 for ( ; i < l; i++ ) { //遍歷陣列attrNames,逐個移除html屬性, name = attrNames[ i ]; //name是要移除的屬性名 if ( name ) { propName = jQuery.propFix[ name ] || name; //如果屬性名name需要修正,則修正屬性 // See #9699 for explanation of this approach (setting first, then removal) jQuery.attr( elem, name, "" ); //先將html屬性設定為空字串,以解決Webkit內核瀏覽器不能 elem.removeAttribute( getSetAttribute ? name : propName ); //呼叫原生方法removeAttribute洗掉對應的屬性,如果jQuery.support.getSetAttribute為true則洗掉name屬性,如果為false,表示在IE6、7下則洗掉特殊屬性, // Set corresponding property to false for boolean attributes if ( rboolean.test( name ) && propName in elem ) { //對應布爾屬性,同步設定對應的DOM屬性為false elem[ propName ] = false; } } } } }, /**/ })
對于jQuery實體來說,它呼叫了不同的工具函式,最后還是執行上面講解的靜態方法的,如下:
jQuery.fn.extend({ attr: function( name, value ) { //移除、設定html屬性 return jQuery.access( this, name, value, true, jQuery.attr ); //呼叫了jQuery.access工具函式,引數5傳入了jQuery.attr }, removeAttr: function( name ) { //移除html屬性 return this.each(function() { //通過each函式方法,依次執行jQuery.removeAttr() jQuery.removeAttr( this, name ); }); }, /*略*/ })
由于jQuery中的特性、DOM屬性和樣式操作的函式引數可以是差不多的,jQuery就定義了一個access函式,為.attr()、.prop()、.css()提供支持,這樣我們通過jQuery實體設定特性、屬性和樣式時可以傳入的引數型別,例如:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script> </head> <body> <a>鏈接</a> <script> $('a').attr('href','http://www.cnblogs.com') //引數2是個字串 $('a').attr('href',()=>'http://www.cnblogs.com') //引數2還是是個函式 $('a').attr({href:'http://www.cnblogs.com'}) //也可以傳入一個物件 </script> </body> </html>
我們傳入不同的引數,都可以實作設定特性的效果,這就是$.access的作用,$.access的原始碼實作如下:
jQuery.extend({ access: function( elems, key, value, exec, fn, pass ) { //為集合中的元素設定一個或多個屬性值,或者讀取第一個元素的屬性值 var length = elems.length; // Setting many attributes if ( typeof key === "object" ) { //如果key是物件,表示要設定多個屬性,則遍歷該物件回圈執行.access函式 for ( var k in key ) { jQuery.access( elems, k, key[k], exec, fn, value ); } return elems; } // Setting one attributes if ( value !== undefined ) { //如果引數value不是undefined,表示要設定單個屬性 // Optionally, function values get executed if exec is true exec = !pass && exec && jQuery.isFunction(value); //修正exec引數,如果沒有傳入pass引數或者該引數值是false,且引數exec為true,且value是函式則設定exec為true,否則exec為false, for ( var i = 0; i < length; i++ ) { fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); //遍歷元素集合elems,為每個元素呼叫回呼函式fn } return elems; //遍歷完成后回傳元素elems,以支持鏈式操作 } // Getting an attribute return length ? fn( elems[0], key ) : undefined; //當value引數為空,且元素集合elems不為空則獲取第一個匹配元素相關的資訊,即執行fn函式 }, /**/ })
writer by:大沙漠 QQ:22969969
之后的DOM屬性和樣式操作都會借用access這個工具方法的,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/36846.html
標籤:jQuery
上一篇:JQuery 常用網址
