国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

由一個(gè)“bug”到鮮為人知的jQuery.cssHooks

ernest.wang / 1263人閱讀

摘要:干想了半天,認(rèn)為可能還是本身的寫(xiě)法問(wèn)題。對(duì)象提供了一種通過(guò)定義函數(shù)來(lái)獲取或設(shè)置特定值的方法。簡(jiǎn)單來(lái)說(shuō),給我們暴露了一個(gè)鉤子,我們可以自己定義方法比如,來(lái)實(shí)現(xiàn)針對(duì)某個(gè)屬性的特定行為。

寫(xiě)在最前

本次分享一下在一次jQuery賦值樣式失效的結(jié)果中來(lái)分析背后原因的過(guò)程。在翻jQuery源碼的過(guò)程中,感覺(jué)真是還不能說(shuō)自己只是會(huì)用jQuery,我好像連會(huì)用都達(dá)不到(逃

歡迎關(guān)注我的博客,不定期更新中——

一個(gè)很簡(jiǎn)單的賦值問(wèn)題
$("#" + id).css({"left": "200"})

我只是單純的想控制一個(gè)left值,大家都懂,但是竟然失敗了,打印出的元素屬性中可以看到left為"";我其實(shí)一開(kāi)始沒(méi)想到可能是jQuery本身的原因?qū)е碌模蚁瓤紤]的是我這個(gè)元素是不是當(dāng)前要賦值的?js的問(wèn)題?等等。。干想了半天,認(rèn)為可能還是本身的寫(xiě)法問(wèn)題。所以進(jìn)行了如下實(shí)驗(yàn):

$("#" + id).css({"left": 200})

看起來(lái)是字符串和數(shù)字的區(qū)別!omg,從來(lái)沒(méi)想過(guò)字符串和數(shù)字的效果竟然會(huì)不一致。。你以為事情已經(jīng)結(jié)束了?no,看下面這個(gè):

$("#" + id).css({"width": "200"})

好的為什么,width設(shè)定字符串就可以被添加px后綴,left就不可以??

現(xiàn)在我們可以總結(jié)一下通過(guò)jQuery.fn.css方法來(lái)設(shè)定元素屬性的時(shí)候會(huì)有一些不一致的情況,以width和left為例子(因?yàn)閷傩院芏啵灰恢碌那闆r很多,了解原理即可):

left通過(guò)number類型可以補(bǔ)全px完成樣式設(shè)定,string類型無(wú)法設(shè)定屬性

width均可以通過(guò)number或string類型完成設(shè)定屬性

從而可以拋出由一開(kāi)始的奇怪現(xiàn)象的底層問(wèn)題:為什么通過(guò)jQuery.fn.css方法設(shè)定樣式時(shí),string類型的值在某些屬性上無(wú)法生效?

從源碼中找線索

jQuery的源碼相比react、vue相比應(yīng)該是很直接的了,就是一個(gè)js。(不過(guò)我仍然看不懂?

首先引入一個(gè)沒(méi)有壓縮過(guò)的jQuery,里面保留了所有的注釋和代碼結(jié)構(gòu),很方便大家閱讀

https://cdn.bootcss.com/jquery/3.3.1/jquery.js

先找到我們本次設(shè)定樣式的方法jQuery.fn.css:

jQuery.fn.extend( {
        css: function( name, value ) {
            return access( this, function( elem, name, value ) {
                var styles, len,
                    map = {},
                    i = 0;
                if ( Array.isArray( name ) ) {
                    styles = getStyles( elem );
                    len = name.length;
    
                    for ( ; i < len; i++ ) {
                        map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
                    }
    
                    return map;
                }
    
                return value !== undefined ?
                    jQuery.style( elem, name, value ) :
                    jQuery.css( elem, name );
            }, name, value, arguments.length > 1 );
        }
    } );

如何通過(guò)瀏覽器來(lái)調(diào)試源碼呢?(因?yàn)橹苯涌丛创a太繁瑣了,通過(guò)debug的形式可以看到每次的調(diào)用棧)我們可以通過(guò)console.log的形式,在這段源碼中將console寫(xiě)入,之后在控制臺(tái)中就可以看到對(duì)應(yīng)源碼的調(diào)用:

進(jìn)入jQuery.style之后就會(huì)來(lái)到最終產(chǎn)生區(qū)別的地方:

style: function( elem, name, value, extra ) {
    
            ...
            hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
            if ( value !== undefined ) {
                type = typeof value;
                if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
                    value = adjustCSS( elem, name, ret );
                    type = "number";
                }
                ...
                if ( type === "number" ) {
                    value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
                }
                ...
                if ( !hooks || !( "set" in hooks ) ||( value = hooks.set( elem, value, extra ) ) !== undefined ) {
                    //此時(shí)的value到底是200還是200px;只有添加了后綴才能賦值成功
                    if ( isCustomProp ) {
                        style.setProperty( name, value );
                    } else {
                        style[ name ] = value;
                    }
                }
    
            } 
            ...
        },

源碼中可以看到在傳入的value中確實(shí)對(duì)string和number做了區(qū)分;而不是我之前所認(rèn)為的,string應(yīng)該和number差不多:)如果傳入number類型,便會(huì)為其添加px后綴;但是這仍然沒(méi)有解釋為什么left和width均傳入string而結(jié)果不同的問(wèn)題。重點(diǎn)在于這句話:

hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
...
if ( !hooks || !( "set" in hooks ) ||
    ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
    ...
}

在value是string類型,到最終賦值之前,還會(huì)經(jīng)過(guò)value = hooks.set( elem, value, extra ) ) !== undefined的判斷,也就是說(shuō)如果hooks.set方法存在,我們還有一次通過(guò)這個(gè)方法來(lái)將string類型的value進(jìn)行后綴補(bǔ)全的機(jī)會(huì)。而這個(gè)hooks是由jQuery.cssHooks得到的,那么jQuery.cssHooks是什么:

從源碼中可以看出,cssHooks中包含了屬性的一些方法,其中l(wèi)eft只有g(shù)et;width有g(shù)et和set。再結(jié)合上面的判斷條件就可以推斷出,由于width存在了set方法,在其方法中對(duì)string類型的value完成了后綴的補(bǔ)齊,而left則不行從而形成了文中一開(kāi)始的“神奇”現(xiàn)象。

cssHooks
直接向 jQuery 中添加鉤子,用于覆蓋設(shè)置或獲取特定 CSS   屬性時(shí)的方法,目的是為了標(biāo)準(zhǔn)化 CSS 屬性名或創(chuàng)建自定義屬性。
$.cssHooks 對(duì)象提供了一種通過(guò)定義函數(shù)來(lái)獲取或設(shè)置特定 CSS 值的方法。可以用它來(lái)創(chuàng)建新的 cssHooks 用于標(biāo)準(zhǔn)化 CSS3 功能,例如,盒子陰影(box shadows)及漸變(gradients)。

例如,某些基于 Webkit 的瀏覽器會(huì)使用 -webkit-border-radius 來(lái)設(shè)置對(duì)象的 border-radius,然而,早先版本的 Firefox 則使用 -moz-border-radius。cssHook 就可以將這些不同的寫(xiě)法進(jìn)行標(biāo)準(zhǔn)化,從而讓 .css() 可以使用統(tǒng)一的標(biāo)準(zhǔn)化屬性名(border-radius 或?qū)?yīng)的 DOM 屬性寫(xiě)法 borderRadius)。

該方法除了提供了對(duì)特定樣式的處理可以采用更加細(xì)致的控制外,$.cssHooks 同時(shí)還擴(kuò)展了 .animate() 方法上的屬性集。

簡(jiǎn)單來(lái)說(shuō),jQuery給我們暴露了一個(gè)鉤子,我們可以自己定義方法比如set,來(lái)實(shí)現(xiàn)針對(duì)某個(gè)屬性的特定行為。所以出現(xiàn)left和width的問(wèn)題就是有沒(méi)有set這個(gè)鉤子方法。so。。我們還剩最后一個(gè)問(wèn)題:

為什么width要對(duì)其設(shè)定鉤子函數(shù)?

答案可以從其set方法來(lái)窺探一下:

set: function( elem, value, extra ) {
    var matches,
        styles = getStyles( elem ),
        isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
        subtract = extra && boxModelAdjustment(
            elem,
            dimension,
            extra,
            isBorderBox,
            styles
        );

    // Account for unreliable border-box dimensions by comparing offset* to computed and
    // faking a content-box to get border and padding (gh-3699)
    if ( isBorderBox && support.scrollboxSize() === styles.position ) {
        subtract -= Math.ceil(
            elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
            parseFloat( styles[ dimension ] ) -
            boxModelAdjustment( elem, dimension, "border", false, styles ) -
            0.5
        );
    }

    // Convert to pixels if value adjustment is needed
    if ( subtract && ( matches = rcssNum.exec( value ) ) &&
        ( matches[ 3 ] || "px" ) !== "px" ) {

        elem.style[ dimension ] = value;
        value = jQuery.css( elem, dimension );
    }

    return setPositiveNumber( elem, value, subtract );
}

從這個(gè)鉤子函數(shù)中我們可以看出,要對(duì)width做特殊處理是因?yàn)閏ss的盒模型有好幾種,content-box|border-box|inherit分別代表“不包括padding、border、margin” | “包含border和padding” | “繼承”;故為了統(tǒng)一外界的調(diào)用,隱藏這些背后的判斷,從而增加了這個(gè)set方法。順帶著在其中把px補(bǔ)全了。同時(shí)left這種沒(méi)什么需要兼容的故沒(méi)有設(shè)定set方法。

小結(jié)

雖然cssHooks不常用(我反正從來(lái)沒(méi)用過(guò),現(xiàn)在對(duì)于標(biāo)準(zhǔn)化格式有很多其他的方法來(lái)做,cssHooks的鉤子感覺(jué)還是有些復(fù)雜了),但這次通過(guò)頁(yè)面上一個(gè)很小的問(wèn)題從而引發(fā)思考并且試圖深挖一些的過(guò)程還是值得總結(jié)下來(lái)的。雖然我們不是造輪子的人,但理解別人的輪子也是比“會(huì)用”好一些的;更何況看了cssHooks我感覺(jué)我都不會(huì)用jQuery:)

參考文章

jQuery源碼解析

jQuer中文文檔

最后

慣例po作者的博客,不定時(shí)更新中——

有問(wèn)題歡迎在issues下交流。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/107455.html

相關(guān)文章

  • 一個(gè)bug鮮為人知jQuery.cssHooks

    摘要:干想了半天,認(rèn)為可能還是本身的寫(xiě)法問(wèn)題。對(duì)象提供了一種通過(guò)定義函數(shù)來(lái)獲取或設(shè)置特定值的方法。簡(jiǎn)單來(lái)說(shuō),給我們暴露了一個(gè)鉤子,我們可以自己定義方法比如,來(lái)實(shí)現(xiàn)針對(duì)某個(gè)屬性的特定行為。 寫(xiě)在最前 本次分享一下在一次jQuery賦值樣式失效的結(jié)果中來(lái)分析背后原因的過(guò)程。在翻jQuery源碼的過(guò)程中,感覺(jué)真是還不能說(shuō)自己只是會(huì)用jQuery,我好像連會(huì)用都達(dá)不到(逃 歡迎關(guān)注我的博客,不定期更...

    malakashi 評(píng)論0 收藏0
  • jQuery源碼解析之width()

    摘要:一在講之前,先弄清屬性是默認(rèn)值這是的值是是這是的值是因?yàn)槭前ǖ模话ā?上攵闹幸舶藢?duì)的判斷。 showImg(https://segmentfault.com/img/remote/1460000019169187); 一、在講之前,先弄清 boxSizing 屬性(1)box-sizing 是默認(rèn)值 content-box 這是divTwo $(#pTwo)...

    ARGUS 評(píng)論0 收藏0
  • 求索:GSAP動(dòng)畫(huà)快于jQuery嗎?為何?

    摘要:本文已完結(jié),請(qǐng)看下文求索的動(dòng)畫(huà)快于嗎為何續(xù)本文源自對(duì)問(wèn)題動(dòng)畫(huà)性能優(yōu)于的原理是什么的回答。是這樣的嗎請(qǐng)看下文求索的動(dòng)畫(huà)快于嗎為何續(xù) 本文已完結(jié),請(qǐng)看下文: > 求索:GSAP的動(dòng)畫(huà)快于jQuery嗎?為何?/續(xù) 本文源自對(duì)問(wèn)題《GSAP js動(dòng)畫(huà)性能優(yōu)于jQuery的原理是什么?》的回答。GSAP是一個(gè)js動(dòng)畫(huà)插件,它聲稱20x faster than jQuery,是什么讓...

    LiangJ 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<