mass Framework support模块

特征嗅探模块。基本取自jQuery,再加入一些与我的方法相关的特征嗅探。jQuery对DOM的研究非常深入,尤其是其clean与clone方法所带动对节点的生成技术研究,比其他类库高出一截。各种稀奇古怪的BUG都被它发掘出来了。为了对付这些BUG,support模块就是做这些先头工作的重要模块了。

//==========================================
// 特征嗅探模块 by 司徒正美
//==========================================
(function(global,DOC){
    var dom = global[DOC.URL.replace(/(#.+|\W)/g,'')];
    dom.define("support", function(){
        dom.log("已加载support模块");
        var div = DOC.createElement('div'),TAGS = "getElementsByTagName";
        div.innerHTML = ' <link/><a href="/nasami" class="u" style="float:left;opacity:.25;">d</a>'+
        '<object><param/></object><table></table><input type="checkbox"/>';
        var a = div[TAGS]("a")[0], style = a.style,
        select = DOC.createElement("select"),
 
        opt = select.appendChild( DOC.createElement("option") );
        var support = dom.support = {
            //是否支持自动插入tbody
            insertTbody: !!div[TAGS]("tbody").length,
            // checkbox的value默认为on,唯有Chrome 返回空字符串
            checkOn :  div[TAGS]( "input" )[ 0 ].value === "on",
            //safari下可能无法取得这个属性,需要访问一下其父元素后才能取得该值
            attrSelected:!!opt.selected,
            //是否区分href属性与特性
            attrHref: a.getAttribute("href") === "/nasami",
            //IE67是没有style特性(特性的值的类型为文本),只有el.style(CSSStyleDeclaration)(bug)
            attrStyle:a.getAttribute("style") !== style,
            //IE8,FF能直接用getAttribute("class")取得className,而IE67则需要将"class"映射为"className",才能用getAttribute取得
            attrProp:a.getAttribute("className") !== "u",
            //http://www.cnblogs.com/rubylouvre/archive/2010/05/16/1736535.html
            //IE8返回".25" ,IE9pp2返回0.25,chrome等返回"0.25"
            cssOpacity: style.opacity == "0.25",
            //某些浏览器不支持w3c的cssFloat属性来获取浮动样式,而是使用独家的styleFloat属性
            cssFloat: !!style.cssFloat,
            //某些浏览器使用document.getElementByTagName("*")不能遍历Object元素下的param元素(bug)
            traverseAll: !!div[TAGS]("param").length,
            //https://prototype.lighthouseapp.com/projects/8886/tickets/264-ie-can-t-create-link-elements-from-html-literals
            //某些浏览器不能通过innerHTML生成link,style,script节点
            createAll: !!div[TAGS]("link").length,
            //IE的cloneNode才是真正意义的复制,能复制动态添加的自定义属性与事件(可惜这不是标准,归为bug)
            cloneAll: false,
            optDisabled: false,
            boxModel: null,
            insertAdjacentHTML:false,
            innerHTML:false,
            fastFragment:false
        };
 
        //当select元素设置为disabled后,其所有option子元素是否也会被设置为disabled
        select.disabled = true;
        support.optDisabled = !opt.disabled;
        if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
            div.attachEvent("onclick", function click() {
                support.cloneAll = true;//w3c的节点复制是不复制事件的
                div.detachEvent("onclick", click);
            });
            div.cloneNode(true).fireEvent("onclick");
        }
        //测试是否符合w3c的盒子模型
        div.style.width = div.style.paddingLeft = "1px";
        //判定insertAdjacentHTML是否完美,用于append,prepend,before,after等方法
        var table = div[TAGS]("table")[0]
        try{
            table.insertAdjacentHTML("afterBegin","<tr><td>1</td></tr>");
            support.insertAdjacentHTML = true;
        }catch(e){ }
        try{
            var range =  DOC.createRange();
            support.fastFragment = range.createContextualFragment("<a>") && range;
        }catch(e){ };
        //判定innerHTML是否完美,用于html方法
        try{
            table.innerHTML = "<tr><td>1</td></tr>";
            support.innerHTML = true;
        }catch(e){};
 
        //有些特征嗅探必须连接到DOM树上才能进行
        var body = DOC[TAGS]( "body" )[ 0 ],i,
        testElement = DOC.createElement( body ? "div" : "body" ),
        testElementStyle = {
            visibility: "hidden",
             0,
            height: 0,
            border: 0,
            margin: 0,
            background: "none"
        };
        if ( body ) {
            dom.mix( testElementStyle, {
                position: "absolute",
                left: "-1000px",
                top: "-1000px"
            });
        }
        for ( i in testElementStyle ) {
            testElement.style[ i ] = testElementStyle[ i ];
        }
        testElement.appendChild( div );//将DIV加入DOM树
        var testElementParent = body || dom.html;
        testElementParent.insertBefore( testElement, testElementParent.firstChild );
 
        support.boxModel = div.offsetWidth === 2;
        if ( "zoom" in div.style ) {
            //IE7以下版本并不支持display: inline-block;样式,而是使用display: inline;
            //并通过其他样式触发其hasLayout形成一种伪inline-block的状态
            div.style.display = "inline";
            div.style.zoom = 1;
            support.inlineBlockNeedsLayout = div.offsetWidth === 2;
            //http://w3help.org/zh-cn/causes/RD1002
            // 在 IE6 IE7(Q) IE8(Q) 中,如果一个明确设置了尺寸的非替换元素的 'overflow' 为 'visible',
            // 当该元素无法完全容纳其内容时,该元素的尺寸将被其内容撑大
            // 注:替换元素(replaced element)是指 img,input,textarea,select,object等这类默认就有CSS格式化外表范围的元素
            div.style.display = "";
            div.innerHTML = "<div style='4px;'></div>";
            support.shrinkWrapBlocks = div.offsetWidth !== 2;
        }
        div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
        var tds = div[TAGS]("td"), isSupported = ( tds[ 0 ].offsetHeight === 0 );
        //只有IE8存在这个问题,那当td元素的display为none时,其高度依旧会受其所在行的高度的影响,而不是0
        //这个问题的存在根本上导致了对元素可见性的判定出现差错
        tds[ 0 ].style.display = "";
        tds[ 1 ].style.display = "none";
        support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
        div.innerHTML = "";
        testElementParent.removeChild( testElement );
        div = tds = null;
    });
})(this, this.document);
/**
2011.9.7 优化attrProp判定
2011.9.16所有延时判定的部分现在可以立即判定了
2011.9.23增加fastFragment判定
*/
原文地址:https://www.cnblogs.com/rubylouvre/p/2178194.html