jQ的浏览器兼容性检测【后篇】
发布在# 菜鸟解读 jQuery #2014年5月27日view:4951
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

最后一篇,看起来代码较多,主要是为各种BUG做铺垫
建议大家可以直接看小编的中文注释,如果描述的还好理解的话,自己写个小例子试试就可以了
jQ的这大坨dom结构是比较综合的应用
在看代码前小编先解释一点:
本篇介绍的东西全是在 jQuery(fn); 中进行运行的
这是为了让dom加载完毕,在fn的尾部使用 jQuery.extend() 方法将各种测试结果继承给 support 对象
好了,来看代码吧

var support = (function() {
    var support,
        //...
    jQuery(function() {
        var container, outer, inner, table, td, offsetSupport,
            marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight,
            paddingMarginBorderVisibility, paddingMarginBorder,
            body = document.getElementsByTagName("body")[0];

        if ( !body ) {
            return;
        }

        conMarginTop = 1;
        paddingMarginBorder = "padding:0;margin:0;border:";
        positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;";
        paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;";
        style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;";
        html = "<div " + style + "display:block;'><div style='" + paddingMarginBorder + "0;display:block;overflow:hidden;'></div></div>" +
            "<table " + style + "' cellpadding='0' cellspacing='0'>" +
            "<tr><td></td></tr></table>";

        container = document.createElement("div");
        container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px";
        body.insertBefore( container, body.firstChild );

        // Construct the test element
        div = document.createElement("div");
        container.appendChild( div );

        div.innerHTML = "<table><tr><td style='" + paddingMarginBorder + "0;display:none'></td><td>t</td></tr></table>";
        tds = div.getElementsByTagName( "td" );
        isSupported = ( tds[ 0 ].offsetHeight === 0 );

        tds[ 0 ].style.display = "";
        tds[ 1 ].style.display = "none";

        //ie6,7,8 中,空单元格的可见高度offsetHeight为1,而其他的为0 =>false
        support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );

        //在旧webkit浏览器中,对marginRight会有异常 => false
        //这里设置, 子div, marginRight:0; 父div, width:2px;
        //然后在进行获取计算后的marginRight与0做判断;
        if ( window.getComputedStyle ) {
            div.innerHTML = "";
            marginDiv = document.createElement( "div" );
            marginDiv.style.width = "0";
            marginDiv.style.marginRight = "0";
            div.style.width = "2px";
            div.appendChild( marginDiv );
            support.reliableMarginRight =
                ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
        }

        if ( typeof div.style.zoom !== "undefined" ) {
            div.innerHTML = "";
            div.style.width = div.style.padding = "1px";
            div.style.border = 0;
            div.style.overflow = "hidden";
            div.style.display = "inline";
            div.style.zoom = 1;
            // ie6,7中 display:inline;zoom:1; && div.offsetWidth:3 => true
            // 其他浏览器中 div.offsetWidth:2 
            support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );


            div.style.display = "block";
            div.style.overflow = "visible";
            div.innerHTML = "<div style='width:5px;'></div>";
            // ie6 元素拥有hasLayout属性和固定的width,height时,父元素被子元素的宽度撑开 => true
            // 其他浏览器不会被撑开
            // 本div中设置了zoom:1;以触发hasLayout属性
            support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
        }

        div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility;
        div.innerHTML = html;

        outer = div.firstChild;
        inner = outer.firstChild;
        td = outer.nextSibling.firstChild.firstChild;

        offsetSupport = {
            //ie8 中,子元素距离其父元素上边的距离offsetTop包含了父元素上边框厚度 => false
            doesNotAddBorder: ( inner.offsetTop !== 5 ),
            //ie,ff中 td元素距离其父元素tr上边的距离offsetTop包含了table元素的上边框厚度 => false
            doesAddBorderForTableAndCells: ( td.offsetTop === 5 )
        };

        inner.style.position = "fixed";
        inner.style.top = "20px";

        // ie6 不支持 fixed 属性 => false
        offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 );

        inner.style.position = inner.style.top = "";
        outer.style.overflow = "hidden";
        outer.style.position = "relative";
        // 要被废弃的属性: 父元素overflow:hidden;子元素距父元素边界的距离会减去父元素的边的厚度, => true
        // 目前,所有浏览器都是true...
        offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 );

        // body元素距html元素边框的距离不包括body元素的外边距margin => true
        // 目前,所有浏览器都是true...
        offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop );

        if ( window.getComputedStyle ) {
            div.style.marginTop = "1%";
            //根据标准: getComputedStyle 返回的应当是经浏览器计算过的数值
            //经小编在目前的webkit浏览器测试中
            //这里返回的都是一个具体到xp的像素值,而不是设置的1%
            support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%";
        }
        if ( typeof container.style.zoom !== "undefined" ) {
            container.style.zoom = 1;
        }
        body.removeChild( container );
        marginDiv = div = container = null;
        jQuery.extend( support, offsetSupport );
    });
    return support;
})();

本篇至此就完结了,这三篇一种涉及到了30多在种,有些罕见或者已经不存在的其实在后续版本中已经不再进行检测了,

感谢您的阅读,欢迎留言:提问,交流,斧正
祝各位51愉快,节后小编继续分享jQ有关数据缓存的相关知识

评论
发表评论
暂无评论
WRITTEN BY
前端狮子
JS前端开发工程师 :喜欢研究js,nodejs,html5; 希望结交更多朋友~
TA的新浪微博
PUBLISHED IN
# 菜鸟解读 jQuery #

本栏解读的jQ为1.7.2版本。 本人也是刚开始读起源码,在这里分享下成长的心得。 本人能力有限,也是接触JS不久的初学者,定会有不少解析不全不够明朗【甚至BUG】的地方, 希望各位牛牛多多留言斧正 感谢阅读 ps:由于工作不定时繁忙,本人也无法定期更新,但是会尽量抽时间学习,分享给大家

我的收藏