ag旗舰厅官网_ag旗舰厅下载客户端

热门关键词: ag旗舰厅官网,ag旗舰厅下载客户端

前端技术

当前位置:ag旗舰厅官网 > 前端技术 > 自定义标签在IE6,最近学习JS的感悟

自定义标签在IE6,最近学习JS的感悟

来源:http://www.pedaLyourcycLe.com 作者:ag旗舰厅官网 时间:2019-10-18 22:09

自定义标签在IE6-8的泥沼

2015/07/20 · HTML5 · IE, 自定义标签

原来的文章出处: 司徒正美   

莫不未来前端组件化之路都以自定义标签,但那东西早在20年前,JSTL已在搞了。今后Web Component还独有webkit扶持。但三个组件库,还索要四个出奇的标记它们是一块的。但是那个XML已经帮大家消除了,使用scopeName,如”<xxx:dialog>”。在笔者三番五次往下想什么管理怎么样为那么些标签绑定数据,与其余零件通讯,管理生命周期,等等大事在此以前,作者还会有一个不得不面前碰到的主题素材,正是怎么样包容IE6-8!

例如以下多少个页面:

图片 1

在chrome, firefox, IE11, IE11的IE6包容情势分别如下:

图片 2
图片 3
图片 4
图片 5

小编们会意识IE6下实际是多出不菲标签,它是把闭标签也改成二个独立的要高商点

图片 6

本条AA:DIV标签被开膛破肚,里面子节点全体暴出来,成为其兄弟节点了。因而想包容它,就要费点劲。有个七个情景要求思索,1是顾客已经将它写在页面上,情形同上;2是客商是将它身处字符串模版中,那一个用正则消除。可是正则借使撞倒复杂的属性名,照旧会晕掉。由此小编仍旧筹算采用原生的HTML parser。换言之,字符串,小编要么会将它形成节点。这么办吧?!笔者想了比相当多艺术,后来依旧选取VML的命名空间法解决!

咱俩将方面包车型客车页面改复杂点,再看看效果!

图片 7
图片 8

能够看来其套嵌关系以往完全正确,并且标具名不会大写化,也不会变卦多余节点!

好了,大家再判别一下是否为自定义标签,只怕纯粹地说,那些节点是还是不是大家组件库中定义的自定义标签。有个别意况下,二个页面能够存在多套组件库,富含avalon的,ploymer的,也许是直接用Web Component写的。

avalon的零部件库将使用命名空间,那样就好界别开。在IE6-9中,判别element.scopeName是不是为aa(这是组件库的命名空间,你能够改个更了不起上的名字),在任何浏览器剖断此因素的localName是或不是以aa:伊始就行了!

JavaScript

function isWidget(el, uiName){ return el.scopeName ? el.scopeName === uiName: el.localName.indexOf(uiName+":") === 0 }

1
2
3
function isWidget(el, uiName){
  return   el.scopeName ? el.scopeName === uiName: el.localName.indexOf(uiName+":") === 0
}

本条难题消除后,大家就能够开搞玻璃于自定义标签的UI库了!

1 赞 1 收藏 评论

图片 9

       还记得本身大二的时候开始接触JS,那年从体育场地借了N多的书籍,然前边看边用editplus写,然后遭逢难点,种种DEBUG,在做项指标时候,种种包容性难点,真是难过啊。由于品种必要尽早写完,所以就起来接触了jquery,仍旧从体育场所抱了几本书,然后下载了jquery源码,然后面看书籍边写代码,看了几章之后,认为貌似轻松,然后就从网络下载了jquery的文书档案,对照着文书档案,对其调用搞得到底比较清楚了。

        现在总的来讲,作者感觉学习jquery反而使自个儿走了弯路,用jquery是相比较便利,也毫不驰念宽容性难题了,何况调用特轻易华贵,可是,反而笔者对原生js以为越来越目生了,也产生了后头认为完全离不开jquery了,想去写一个XXX组件,想了一晃,思路有了,然后写的时候蒙受种种难题,然后就又赶回jquery了。

         从今年暑假的时候,笔者决定离开jquery了,jquery是一把双刃剑,开辟的时候是利于,不过,作为三个初大方,笔者认为那是很不利于的。

         然后就从头下载JS的电子书,只怕是友善比较躁动吧,看书真心看不进来,笔者依旧喜欢边看边写代码这种。写了一段时间,慢慢的感到最开端的认为逐步回来了,当然,也境遇了N多的标题。

        到寒假的时候,决定本身的毕设不利用未来成熟的JS库,反而本身来写多个不周详的库,那样学习的更加多,当然,也比较费时间。

        早前写的感觉真是痛楚啊,什么都不懂,所以就去看了看tangram的源码,为何看tangram呢,其实原因相比滑稽,那时校招的时候作者面试百度前端,被刷掉了,当时面试官让自个儿看看它们百度运用的JS库tangram,笔者就想看看它们特别库到底有何了不起的。。。

        写这么些库,首先利用了命名空间,作者相比欣赏toper,所以自身第一定义了一个变量:

var tp = tp || {};

        这种艺术也是借鉴了tangram的写法,选取对象字面量的款型。那样具备toper定义的方法都位于了tp那一个私有空间内了,举例对DOM的操作就位于tp.dom中。

       由于这一个库完全部是为毕设做的,所以那之中的好些个文本皆感觉落到实处毕设的一些作用而写的。

      作者利用的组织是core+组件的办法,tp.core.js(压缩后为tp.core-min.js),而其余的机件各个组件三个文件,而组件之间恐怕存在依据关系,这种依赖关系就透过AMD消除。

      在未曾写这么些库早前,就算是自身动用jquery,每二个JS文件小编都以一向在HTML文件中应用script标签写进去的,而现行内需动用这种异步模块加载的点子,假诺要选拔非宗旨模块,那么须求:

tp.use(["tp.a","tp.b"],function(a,b) {

})

      使用use方式,它会活动去下载tp.a.js和tp.b.js,下载完毕之后,推行回调函数。

      一样,在tp.a.js中,也不能够采纳普通的JS的写法了,而要使用:

 

define("tp.a",["tp.c","tp.d"],function(c,d) {
   tp.modules.add("tp.a",function() {

    });
});

     define的首先个参数是该零件的名字(须要独一,所以本身如故遵从命名空间的情势写的),第贰个参数是那么些组件所依据的零部件,第多个参数是回调函数,也便是当正视的机件下载实现未来,回调施行,而tp.modules.add就足以将以此模块加载到全部库中,那样的话技艺利用tp.use调用。

      这种艺术本人在tangram中没有看出,我是看了Taobao的KISSY之后攻读到的,也等于所谓的AMD(异步模块定义)。

      一时半刻AMD的落成形式是经过setInterval,可是将要被重构图片 10

      小编事先写了一篇日记来落到实处AMD,当然,效能低下,反正大家看看就行了

      然后正是事件了,事件是贰个相比恼火的业务,东西比比较多,小编把它投身了tp.event这一个空间中。

      首先是充裕和移除事件监听器,由于IE和非IE选择的方式不均等,IE采纳attach伊夫nt和detech伊夫nt,非IE采纳add伊夫ntListener和remove伊夫ntListener,並且IE只接济冒泡(从脚下成分冒泡到根成分),而非IE协理冒泡和破获(从根成分捕获到当前因素)。最从前自己是那般做的:

tp.event.on = function(element,event,fn) {
        if (window.attachEvent) {
            //IE
            //第三个参数_realFn是为了修正this
            var realFn = function(e{fn.call(element,e);};
            _realEventCallbackFns[fn] = realFn;
            element.attachEvent("on" + event,realFn);
        } else if (window.addEventListener) {
            element.addEventListener(event, fn,false);
        } else {
            element["on" + event] = fn;
        }
};

     也正是在二个函数内部去看清是不是是IE,然后相应的举办相应的函数,不过如此,要是加上的事件监听器相当多,每便都if什么的,小编个人以为比较倒霉,所以小编背后增多了三个扶助函数:

var _listeners = {},
        _addEventListener,
        _removeEventListener;
    if (window.attachEvent) {

        var _realEventCallbackFns = {};
        _addEventListener = function(element,event,fn) {
            //第三个参数_realFn是为了修正this
            var realFn = function(e) {fn.call(element,e);};
            _realEventCallbackFns[fn] = realFn;
            element.attachEvent("on" + event,realFn);
        };
        _removeEventListener = function(element,event,fn) {
            element.detachEvent("on" + event,_realEventCallbackFns[fn]);
        };
    } else if (window.addEventListener) {
        _addEventListener = function(element,event,fn,capture) {
            element.addEventListener(event, fn,capture);
        };
        _removeEventListener = function (element,event,fn,capture) {
            element.removeEventListener(event,fn,capture);
        };
    } else {
        _addEventListener = function(element,event,fn) {
            element["on" + event] = fn;
        };
        _removeEventListener = function(element,event) {
            delete element["on" + event];
        };
    }

           那样,整个推断只须求实行三次,后边调用的时候只须要选取_add伊夫ntListener就能够,当然,由于应用了闭包,tp.event命名空间之外是不可访谈那多少个函数的。

           那这样,tp.event.on就变得特简单了:

tp.event.on = function(element,event,fn) {
        _addEventListener(element,event,fn,false);
         };

          并且那样还恐怕有一个平价,在此之前的点子只好动用冒泡情势,但未来,可以运用捕获,当然,只可以非IE本事采纳,这样在前边使用事件代理一些非冒泡的事件的时候非常有用,譬如blur和focus事件。

           除了事件监听器,还亟需事件风云的拉长,删除等,相当于add,fire,remove等,这里就背着了。

          在应用事件代理的时候,大家平时要取获得事件的目的成分,而IE和非IE又是不等同的,所以必要独自写三个函数:

tp.event.getTarget = function(event) {
        return event.target || event.srcElement;
    };

          常用的功效本来如故阻止事件冒泡以至阻碍暗许事件的产生,很可惜,IE和非IE管理情势还是不等同的,譬喻阻止冒泡IE接纳的是cancelBubble,而别的浏览器采取的是stopPropagation,所以照旧须要写:

tp.event.preventDefault = function(event) {
        if(event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    };
    tp.event.stopPropagation = function(event) {
        if(event.stopPropagation) {
            event.stopPropagation();
        } else {
            event.cancelBubble = true;
        }
    };

         事件那多只事实上自个儿做了N多东西,但是出于讲不完,所以权且不说了。

        注意一下啊,由于JS变量功用域未有block,所以请不要选拔上面这种:

var arr = new Array();
if(xxx) {
   for(var i = 0,len = arr.length ; i < len; i++) {

   }
} else {
   for(var i = 0,len = arr.length ; i < len; i++) {

   }
}

      那样使用变量i已经被另行定义了,所以须要把变量i定义在if以前,即:

var arr = new Array(),
    i;

          事件现在,当然正是DOM了,感到每一种库在这里个地点都做了数不尽专业。

         首先是ready的论断,关于这些能够看本身别的一篇日记:

         这里本人根本讲一下tp.dom.query,也正是询问如何是好的,首先探问常用的查询有:#aa,.aa,input。

         #aa这种相比简单,因为JS提供了API,也便是document.getElementById;input这种也比较好搞,因为JS有document.getElementsByTagName;可是.aa这种措施就相比纠葛了,因为JS未有提供API,幸好,在局地浏览器中也许提供了API:document.getElementsByClassName,而那多少个并未有提供那一个API的就相比较正剧了,只好遍历全部节点,也正是利用document.getElementsByTagName(*):

          小编那时写了八个协助函数:

var _getElementsByClassName = null;
        if(document.getElementsByClassName) {
                _getElementsByClassName = function(str) {
                    var fetchedEles = document.getElementsByClassName(str),
                        eles = [];

                    for(var i = 0, len = fetchedEles.length; i < len; i++) {
                        eles.push(fetchedEles[i]);
                    }
                    return eles;
                };
        } else {
            _getElementsByClassName = function(str,openClassScan) {
                var eles = [],
                    allElements = document.getElementsByTagName("*"),
                    i;
                if(openClassScan) {
                    for (i = 0; i< allElements.length; i++ ) {
                        if (tp.dom.containClass(allElements[i],str)) {
                            eles.push(allElements[i]);
                        }
                    }
                } else {
                    for (i = 0; i< allElements.length; i++ ) {
                        if (str === allElements[i].className) {
                            eles.push(allElements[i]);
                        }
                    }
                }
                return eles;
            };
        }

            笔者此时写了三个openClassScan参数,解释一下,那些参数是为着化解类似于<div class = "a b"></div>这种,因为即使要扶助通过API查询如class:a,那么供给各种节点都认清是还是不是contain那几个class,相比费时间,而本人觉着非常多时候无需,所以私下认可本身关闭了。

            PS:使用了原生的document.getElementsByClassName的一定不受那一个影响的。

           小编把每多个查询如:tp.dom.query("#aa input")分为二种,一种为轻易询问(约等于如查询:#aaa),别的一种是犬牙相制查询,每一种复杂查询都以由大多简便询问构成的,譬喻#aaa input,就足以切成:#aaa和input。

           所以,在各类查询的最起先,需求将传递的询问格式化,例如#aa >input这种格式化为:#aa > input,三个空格变为1个空格,>两侧必须有一个空格等。

           之后写二个扶持函数,决断是还是不是是复杂查询,借使是,那么切开查询字符串,切成数组。

           我认为:#aa input这种实际上正是经过document.getElementById查询之后然后查询它的子孙节点中的全部满意tagName为input的成分;而#aaa > input这种正是询问它的男女节点中是或不是有这种满意条件的要素。以后总体育工作艺流程比较简单了,对于多个千头万绪查询,首先实行三个简练询问,然后遵照查询的结果集合,进行一遍遍历,对种种节点查询它的子女节点或子孙节点,将装有满足条件的归入到其余八个数组,如若该数组为空,那么直接回到空数组,不然,继续扩充下一回查询(依然查询孩子节点或子孙节点)。

           小编觉着,就疑似此贰个效果与利益相比轻松的query就够了,不供给达成类似于jquery里面的这么复杂的查询,即使要动用它,其实也异常粗略,因为jquery的询问引擎sizzle已经开源,完全可以将它出席到这几个库,而明日toper也是这么做的,要调用sizzle就利用:

tp.use("tp.dom.sizzle",function(sizzle) {});

          认为JS的兼容性真心很脑仁疼啊,就举个例子在DOM这一块儿,为了合作,小编都做了相当长日子。当然,DOM那壹头必定将不唯有这么一点剧情,权且也不写了。

          除了DOM,对变量类型的判定和浏览器的检查评定也是非常重大的。

         首先,类型剖断,由于JS是弱类型语言,而不时候是亟需看清它的品种的,当然也得以利用typeof 去判别,一时半刻作者是这般做的:

  

tp.type = tp.type || {};
tp.type.isArray = function(ele) {
    return "[object Array]" === Object.prototype.toString.call(ele);
};
tp.type.isFunction = function(ele) {
    return "[object Function]" === Object.prototype.toString.call(ele);
};
tp.type.isObject = function(ele) {
    return ("function" === typeof ele) || !!(ele && "object" === typeof ele);
};
tp.type.isString = function(ele) {
    return "[object String]" === Object.prototype.toString.call(ele);
};
tp.type.isNumber = function(ele) {
    return "[object Number]" === Object.prototype.toString.call(ele) && isFinite(ele);
};
tp.type.isBoolean = function(ele) {
    return "boolean" === typeof ele;
};
tp.type.isElement = function(ele) {
    return ele && ele.nodeType == 1;
};
tp.type.isUndefined = function(ele) {
    return "undefined" === typeof ele;
};

        笔者看了一下,差异的库的决断方式差别,小编那时使用的是tangram的剖断格局。

        然后正是浏览器判别,笔者是那样写的:

(function() {
    var ua = navigator.userAgent;
    tp.browser.isIe = ua.hasString("MSIE") && !ua.hasString("Opera");
    tp.browser.isFirefox = ua.hasString("Firefox");
    tp.browser.isChrome = ua.hasString("Chrome");
    tp.browser.isWebKit = ua.hasString("WebKit");
    tp.browser.isGecko = ua.hasString("Gecko") && !ua.hasString("like Gecko");
    tp.browser.isOpera = ua.hasString("Opera");
    tp.browser.isSafari = ua.hasString("Safari") && !ua.hasString('Chrome');
    tp.browser.isStrict = ("CSS1Compat" === document.compatMode);
})();

       当然,还会有浏览器版本的论断,暂且就不贴出来了。这里基本思路就是推断navigator.useAgent重返的字符串中,种种浏览器里面包车型地铁那一个字符串是不一样等的,当然,那一个历程比较恶心,何况有十分的大可能率前面某八个浏览器会改换它的userAgent,导致整个推断失效,比如IE,听人家说前面新IE要把userAgent搞成firefox,真心搞不懂,那是要逆天啊?

       除了这种论断格局,还足以由此剖断是不是有某二个函数或某贰个变量来判别,这种论断形式本人忘掉叫什么名字了,反正早先这种叫浏览器嗅探。

       除了代码之外,工具也很关键,另一篇日记介绍JS工具的:

        对动画片风野趣的童鞋,能够看看本身的前段时间攻读JS的顿悟-2,关于动画的。

       好啊,貌似又超时了,先就像此吗,以为每一次写这种日志都会费用无尽时间。

本文由ag旗舰厅官网发布于前端技术,转载请注明出处:自定义标签在IE6,最近学习JS的感悟

关键词:

上一篇:前端开采工具连串

下一篇:没有了