JS框架设计之加载器所在路径的探知一模块加载系统

1、要加载一个模块,我们需要一个URL作为加载地址,一个script作为加载媒介,但用户在require是都用ID,我们需要一个将ID转换为URL的方法,思路很简单,强加个约定,URL的合成规则是为:

basepath+模块ID+".js"

2、当浏览器自上而下分析DOM,在浏览器解析我们的Javascript文件时(指的是加载器文件)时,他就肯定是DOM树最后一个加入的script标签,因此有下面的方法:

zcLoadJs.js

function getBasePath()
{
    var nodes=document.getElementsByTagName("script");
    var node=nodes[nodes.length-1];//拿到最后一个加载的script标签对象,也就是加载器
    var src=document.querySelector?node.src:node.getAttribute("src",4);
    /*
    getAttribute(strAttributeName,lFlags)
     0
     默认。执行不区分大小写的属性搜索,如果找到该属性,则返回内插值。
     1
     执行区分大小写的属性搜索。为了找到一个匹配,在大写和小写字母strAttributeName必须完全匹配那些在属性名。
     2
     以String形式返回属性值。此标志不适用于事件属性。
     4
     将属性值作为完全展开的网址返回。仅适用于网址属性。
     */

    return src;
}
alert(getBasePath());

demo.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    document.write('<script src="../../common/jquery1.4.4.js"><\/script>');
    document.write('<script src="../加载器/zcLoadJs.js"><\/script>');
    document.write('<script src="http://common.cnblogs.com/script/jquery.js" type="text/javascript"><\/script>');
</script>

</body>
</html>

在IE678中输出:jquery.js的路径

在其它浏览器中输出:zcLoadJs的路径

zcLoadJs为我的加载器,里面执行getBasePath()方法,预期得到zcLoadJs.js的服务器路径,但是在IE678中却返回juqery.js的路径,这个不奇怪,很多的常规方法在IE中都会失效,除了API的差异性外,它本身也存在很多的bug,所以我们需要修改zcLoadJs.js中的getBasePath方法,使其兼容旧版本的IE,代码如下:

//解决了上面的问题
function getBasePath() {
    var nodes = document.getElementsByTagName('script'),
    node=nodes[nodes.length-1];
    if (window.VBArray)//如果是浏览器的IE的情况
    {
        for(var i=nodes.length;node;node=nodes[--i])
        {
            //通过readyChange属性,微软在document、image、xhr、script中都使用了这个属性,用来查看加载情况
            if(node.readyState === "interactive")
            {
                break;
            }
        }
    }
    else
    {
        node=nodes[nodes.length-1];
    }
    var src=document.querySelector? node.src:node.getAttribute('src',4);//一
    return src;
}

在解决IE678中的bug之后,想一下程序能否优化,访问DOM比一般的Javascript代码消耗高很多,这是可以可以利用Error对象,来对代码进行效率上的优化:

function getBasePath()
{
    try
    {
        a.b.c();
    }
    catch(e)
    {
        if(e.fileName)//firfox,当try中代码异常,通过抛出的e.fileName可以得到发生异常的文件名
        {
            return e.fileName;
        }
        else if(e.sourceURL)//safari,当try中代码异常,通过抛出的e.sourceURL可以得到发生异常的文件名
        {
            return e.sourceURL;
        }
    }
    var nodes = document.getElementsByTagName('script'),
        node=nodes[nodes.length-1];
    if (window.VBArray)//如果是浏览器的IE的情况
    {
        //倒序查找更快
        for(var i=nodes.length;node;node=nodes[--i])
        {
            //通过readyChange属性,微软在document、image、xhr、script中都使用了这个属性,用来查看加载情况
            if(node.readyState === "interactive")
            {
                break;
            }
        }
    }
    else
    {
        node=nodes[nodes.length-1];
    }
    var src=document.querySelector? node.src:node.getAttribute('src',4);//一
    return src;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Ryan Miao

js基础-表单验证和提交

基础知识: 原始提交如下: 1 <form action="/login" method="post" id="form1"> 2 <span>用户<...

4685
来自专栏守望轩

Visual Studio 2008 每日提示(二十二)

#211、在对象浏览器向前和向后导航 原文链接:The Object Browser has a navigate forward and navigate ...

3558
来自专栏IMWeb前端团队

移动端minimvvm框架qvm实现

gitHub地址 1,移动端minimvvm框架qvm实现 qvm概念,一个适用于移动端的mini mvvm(什么是mvvm?没了解的同学自己去了解)框架。参考...

21710
来自专栏软件开发

前端MVC Vue2学习总结(二)——Vue的实例、生命周期与Vue脚手架(vue-cli)

一、Vue的实例 1.1、创建一个 Vue 的实例 每个 Vue 应用都是通过 Vue 函数创建一个新的 Vue 实例开始的: var vm = new Vue...

5027
来自专栏程序员互动联盟

【答疑解惑】getchar()与EOF

先看下面的代码: while((c = getchar()) != EOF){ putchar(c); } 这一段代码是The C Programming ...

3719
来自专栏帘卷西风的专栏

linux下shell技巧

    经常看到一些大牛操作linux的时候,双手运指如飞,指令如流水般输出,会不会感到羡慕呢?

741
来自专栏吴伟祥

Velocity语法大全 转

本文转载自:http://www.cnblogs.com/codingsilence/archive/2011/03/29/2146580.html

604
来自专栏技术翻译

如何编写自己的jQuery插件?

对于那些不知道的人来说,jQuery是一个JavaScript库,它包含了许多特性,非常小而且速度很快。它还包括一个易于使用的API,在所有浏览器上都是兼容的,...

1341
来自专栏逸鹏说道

Python3 与 C# 并发编程之~ 进程篇中

接着上面继续拓展,补充说说获取函数返回值。 上面是通过成功后的回调函数来获取返回值,这次说说自带的方法:

1273
来自专栏我的小碗汤

一个神秘现象引发对beego框架的思考

小强最近在项目中遇到了一个很奇怪的问题:在整改日志规范时,为了避免影响现有的代码结构以及改动尽可能小的前提下,在调用记日志的SDK处将某一个字段值首字母改为大写...

754

扫码关注云+社区