jQuery1.6c新增的適配器

來源:互聯網
上載者:User

其實在jQuery1.5中已有這東西,cssHooks,或者更早之前的jQuery.event.special, 或者 Sizzle.selectors裡面更多的對象。它們共同的特點是包含了許多相關的函數,cssHooks是專門處理css屬性的擷取與設定,如IE的opacity,event.special用於裝載與卸載submit, change, focus ,mouseenter等特別事件與自訂事件, Sizzle.selectors裡面的過濾器與候選集擷取器就更不用說了。由於JS用對象做為表進行尋找是比if條句與switch語句快很多,加之,適配器這種模式對於擴充新功能非常有利,因為jQuery1.6便把它發揚光大了。

在jQuery的attributes模組(github是這樣分割的,但耦合這麼高很難說是模組),共增加了三個這樣對象,valHooks,attrHooks, propHooks,分別對應val,attr與prop這個三個方法。prop是新增的,表示jQuery決定區分屬性與特性的決心,但IE6/7還是無法區分它們,因此attr基本上涵蓋了prop的功能。

我們看一下它們各自的運用吧!

// jQuery.style 方法      if ( value !== undefined ) {        //=================略==============        // If a hook was provided, use that value, otherwise just set the specified value        if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {          // Wrapped to prevent IE from throwing errors when 'invalid' values are provided          // Fixes bug #5509          try {            style[ name ] = value;          } catch(e) {}        }       } else {        // If a hook was provided get the non-computed value from there        if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {          return ret;        }         // Otherwise just get the value from the style object        return style[ name ];      }

// jQuery.fn.val 方法      if ( !arguments.length ) {        if ( elem ) {          hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];          if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {            return ret;          }          return (elem.value || "").replace(rreturn, "");        }        return undefined;      }     //===============略============      hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];      // If set returns undefined, fall back to normal setting      if ( !hooks || ("set" in hooks && hooks.set( this, val, "value" ) === undefined) ) {        this.value = val;      }

// jQuery.attr 方法     hooks = jQuery.attrHooks[ name ] || ( jQuery.nodeName( elem, "form" ) && formHook );      if ( value !== undefined ) {        if ( value === null || (value === false && !rspecial.test( name )) ) {          jQuery.removeAttr( elem, name );          return undefined;        } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {          return ret;        } else {          // Set boolean attributes to the same name          if ( value === true && !rspecial.test( name ) ) {            value = name;          }          elem.setAttribute( name, "" + value );          return value;        }      } else {        if ( hooks && "get" in hooks && notxml ) {          return hooks.get( elem, name );        } else {          ret = elem.getAttribute( name );          // Non-existent attributes return null, we normalize to undefined          return ret === null ? undefined : ret;        }      }

// jQuery.prop 方法           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 )) !== undefined ) {return ret;} else {return elem[ name ];}}

//jQuery.event.add      if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {        // Bind the global event handler to the element        if ( elem.addEventListener ) {          elem.addEventListener( type, eventHandle, false );        } else if ( elem.attachEvent ) {          elem.attachEvent( "on" + type, eventHandle );        }      }//jQuery.event.remove      if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {        jQuery.removeEvent( elem, type, elemData.handle );      }

可以發現還是很有章法的。這些適配器就是用來處理一些特殊的屬性,樣式或事件。而這些屬性,樣式或事件,我們可以通過瀏覽器的特徵嗅探,把相應的解決方案添加到適配器中。有了這些適配器,jQuery就可以省去許多if else 判定,當正式版發布時,又可以高興地宣布這幾個方法快了多少百分比了!

attr = function( el, name, value ) {
// 標識是否使用寫方法
var set = value !== undefined;
if(el.nodeType == 1){
var notxml = !dom.isXML(el);
//對於HTML,我們需要對一些屬性名稱進行映射
name = notxml && dom.props[ name ] || name;
//safari 我們必須訪問上一級元素時,才能擷取這個值
if ( name === "selected" && !dom.support.optSelected ) {
var parent = el.parentNode,i = -2
while(i++ ){
parent.selectedIndex;
parent = parent.parentNode;
}
}
if (name === "style" && notxml && !dom.support.attrStyle) {
if ( set ) {
el.style.cssText = "" + value;
}
return el.style.cssText;
}
if (el[ name ] !== undefined && notxml ) {
if ( set ) {
try{
if ( value === null ) {
el.removeAttribute( name );
} else {
el[ name ] = value;
}
}catch(e){};
}
//注意formElement[name] 相等於formElement.elements[name],會返回其轄下的表單元素
if (el.tagName === "FORM" && el.getAttributeNode(name) ) {
return el.getAttributeNode( name ).nodeValue;
}
//只有能獲得焦點的元素才具有tabIndex屬性,如表單元素與指定了href的連結元素
if ( name === "tabIndex" ) {
var attributeNode = el.getAttributeNode( "tabIndex" );
return attributeNode && attributeNode.specified ?
attributeNode.value : (dom.isFormElement( el ) || el.href )?
0 : undefined;
}
if(el[name] !== el.getAttribute( name, 2 )){
return el.getAttribute( name, 2 )
}
return el[ name ];
}
if ( set ) {
el.setAttribute( name, "" + value );
}
var attr = el.getAttribute( name );
return attr === null ? undefined : attr;

}else if(el.nodeType === 9 || el.setTimeout){
if ( set ) {
el[ name ] = value;
}
return el[ name ];
}else{
return undefined;
}
}

posted on 2011-04-27 09:18 司徒正美 閱讀(...) 評論(...) 編輯 收藏

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.