- 浏览: 1460207 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
luhouxiang:
写的很不错,学习了
Extjs 模块化动态加载js实践 -
kingkongtown:
如果想改成淘宝后台那样,可以在编辑器批量上传图片呢?
kissy editor 阶段体会 -
317966578:
兄弟我最近也在整jquery和caja 开放一些接口。在git ...
caja 原理 : 前端 -
liuweihug:
Javascript引擎单线程机制及setTimeout执行原 ...
setTimeout ,xhr,event 线程问题 -
辽主临轩:
怎么能让浏览器不进入 文档模式的quirks模式,进入标准的
浏览器模式与文本模式
How to Auto Include a Javascript File
By Mark Kahn
Many developers have a large library of JavaScript code at their fingertips that they developed, their collegues developed, or that they've pieced together from scripts all over the Internet. Have you ever thought that it would be nice to not have to search through all those files just to find that one function? This article will show you how dynamically include any JavaScript file, at runtime, by simply calling a function in that file!
Here's an example: You have a function foo() in file bar.js. In your code, you know that foo() might be called, but it probably won't be because most people do not use its functionality. You don't want to force the user to download bar.js unless it's going to be used because it's a fairly large file. Here you'll learn how to make a fake foo() function that actually loads bar.js on the fly and then calls the real foo() function.
Dynamically Loading a Script
As many developers know, there are at least two different ways to dynamically load a script at runtime. The first is to create a script object and append it to the document. The second is to use an XMLHTTP request to grab the source code, and then eval() it.
It is this second method that we're going to use, and we're going to exploit the fact that an XMLHTTP request has the capability to completely stall any script activity.
First, some basics: how to create an XMLHTTP Object. There are as many different functions to return a cross-browser XMLHTTP Object as there are developers that work with AJAX. I happen to have my own as well, and here's a simplified example of that:
function getXMLHttpObj(){ if(typeof(XMLHttpRequest)!='undefined') return new XMLHttpRequest(); var axO=['Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.4.0', 'Msxml2.XMLHTTP.3.0', 'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP'], i; for(i=0;i<axO.length;i++) try{ return new ActiveXObject(axO[i]); }catch(e){} return null; }
Most browsers other than Internet Explorer 5 or 6 have a built-in XMLHttpRequest object. Internet Explorer 7, when it's released, will also have this object natively. The first thing we do is check to see if this object exists. If it does, we create an instance of it and that's it. If the object doesn't exist, we attempt to create one of several ActiveX Objects. We don't know what objects our users have installed, so we attempt to create several different XMLHTTP objects, starting with the newest ones.
Now in order to dynamically load functions, we first need to define them. We could do this one function at a time, but instead of hard-coding dozens of functions, we can choose to just make an object or array with all the file names and the functions you want to have auto-included:
var autoIncludeFunctions = { 'scripts/file1.js': ['function1', 'function2', 'function3'], 'scripts/file2.js': ['function4', 'function5', 'function6'], 'scripts/file3.js': ['function7', 'function8', 'function9'] }
Our autoIncludeFunctions object should contain a list of JavaScript files, as well as a list of functions in those files. Here we are using shorthand JavaScript notation to create both the object and the arrays, but the same thing could be accomplished in many different ways.
These .js files can contain any code you have available, such as JavaScript menus, animations, etc. The simplest example would be a file titled "file1.js" that only contained "function function1(){ alert('Hello, World!'); }".
Note that if any of these files contain functions with the same name as another file, only the last function listed will be used.
To make things a bit easier, we're going to make a function that will pull a JavaScript file down and execute it. It's very important, in our case, that the third paramater sent to the XMLHTTP object be false. This forces the script to wait for the response to download as opposed to continuing on with other code.
function loadScript(scriptpath, functions){ var oXML = getXMLHttpObj(); oXML.open('GET', scriptpath, false); oXML.send(''); eval(oXML.responseText); for(var i=0; i<functions.length; i++) window[functions[i]] = eval(functions[i]); }
The loadScript function expects two arguments: scriptpath and functions. "scriptpath" should contain the URL to your JavaScript file, and "functions" is the array of functions that exist in this JavaScript file.
As you can see, the code to pull and execute a script is straightforward. The browser first downloads, and then interprets the JavaScript file. If you've read any other articles on AJAX development, you might remember that in most cases the third argument sent to the open() function of an XMLHTTP object is usually "true." In our case we have it set to "false." This argument controls the state of the XMLHTTP object. If set to true, the object runs asynchrounously, meaning that all other JavaScript code continues while the object is loading. While this is a good thing in many circumstances, if we implemented it here our code would return before our file was done loading. Since we want our code to wait until this file is complete, we set this third argument to false, thus pausing our JavaScript execution until we are ready to continue.
When the code is evaluated from the responseText, it's executed in the limited scope of the loadScript function and because of this, none of these functions will be available outside of the loadScript function. In order do get around this, the for loop adds each function to the window object, thus making it globally available.
It's important to note that only scripts on the same server as the current page can be called in this manner. This is inherent to the XMLHTTP Object and is a necessary measure to increase general browser security.
Now that we have everything we need, we'll piece it together. We're going to create a "fake" function for each function that we want to auto-load. When these "fake" functions are called, they will load the real file and then re-execute the real function.
for(var fileName in autoIncludeFunctions){ var functionNames = autoIncludeFunctions[fileName]; for(var i=0; i<functionNames.length; i++){ var functionName = functionNames[i]; window[functionName] = function(){ loadScript(fileName, functionNames); var execCode = functionName+'( '; for(var i=0; i<arguments.length; i++) execCode+='arguments['+i+'],'; execCode = execCode.substr(0, execCode.length-1)+')'; return eval(execCode); } } }
The first part is relatively simple. We are looping through our list of files, one at a time, and then looping through each function in those files. Let's break down the inner code, so that it's a bit easier to understand:
window[functionName] = function(){ loadScript(fileName, functionNames);
Here, we're using a global setting for our new "fake" function. We use the window object so that this function will be available throught the code. Inside of this function, we're calling the loadScript function that we previously created. After this is called, our fake global function is replaced with the real one, and we're halfway home. We now have to call the real function with all of the parameters passed to the fake one.
var execCode = functionName+'( '; for(var i=0; i<arguments.length; i++) execCode+='arguments['+i+'],'; execCode = execCode.substr(0, execCode.length-1)+');';
We now generate a string with which to call our real function. If you didn't already know, the arguments object contains all of the parameters passed into a function. We loop through the arguments object so that we can pass each and every parameter sent to this fake function on to the real one. At the end, this string will look something like "functionName(arguments[0], arguments[1], arguments[2]);".
return eval(execCode);
Now that we have a string containing the proper call to our real function, we just have to execute it and we're done! Our real function has now replaced the fake one so that we don't have to go through all of this again, and it's been called. Any value that the real function would return gets sent to the original calling code as it should.
Things to Look Out For
If you are implementing this code, you might want to take the following into account:
1. As briefly mentioned, any scripts that are loaded must be on the same server. Using this method, you can not load a script from www.some_other_site.com from www.your_site.com.
2. When the auto load code is initiated, there will be a pause for the end user. Depending on the size of the file being downloaded, the speed of the user's connection and other variables, this pause can be anywhere from a few ms to a few seconds or more. During this time, the page will appear to be locked to your user. If you included this script the normal way, you would have the same delay, but it would occur when the page was loading.
3. Any functions in a script file that are not defined in the autoIncludeFunctions variable will not be globally accessible. So if your file 'file1.js' has 20 functions in it, in the above example only three of them will be available for use. One solution to this is to define all of your functions in the javascript as "window.functionName = function(){" instead of "function functionName(){".
4. This code has the potential to replace existing functions with the same names. You might consider adding a check for this by checking to see if window[functionName] before replacing it. If you don't do a function check, it's suggested that you run this code before including other js files, in case a function might be overridden.
If you want to see this concept in more detail, take a look at my general.js file. It's not implemented exactly as portrayed here, but it's fairly close, and is a bit more robust.
Conclusion
You now have the ability to access any JavaScript file you've ever created, all from one script. The examples in this article are straightforward, but it shouldn't be hard to modify this code to add validation to see if the file exists, prevent the code from overriding other functions, and any other features you may need.
About the Author
Mark Kahn is a Web Developer and DBA. Mark can be contacted through his website, http://www.jslibrary.org.
发表评论
-
continuation, cps
2013-09-12 16:49 2791起 随着 nodejs 的兴起,异步编程成为一种潮流 ... -
一种基于匹配回朔的 css3 选择器引擎实现
2013-05-07 20:40 3401一种基于匹配回朔的 css3 选择器引擎实现 介绍 C ... -
cubic-bezier 模拟实现
2013-01-05 16:34 14089cubic-bezier 曲线是 css3 动画的一个重要基石 ... -
构建前端 DSL
2012-10-11 22:10 5359目前在传统的软件开 ... -
Get cursor position and coordinates from textarea
2012-04-10 20:50 5037最近需要从 textarea 中获 ... -
兼容 ie 的 transform
2012-02-23 14:00 6424css 2d transform 是 css3 引入的一个新的 ... -
promise api 与应用场景
2012-02-07 17:34 7375promise 是 commonjs 社区中提出的异步规范,其 ... -
closure compiler 代码优化实例
2012-01-08 03:23 2829closure compiler 可以进行不少有意思的优化 ... -
write html parser
2011-12-01 02:48 2916首先需要声明 html 不能用正则表达式来直接匹配进行内容抽取 ... -
获取剪贴板数据
2011-11-07 23:31 6447兼容性: 获取剪贴板数据这块各个浏览器间存在很大的 ... -
url 映射问题
2011-11-07 21:52 3221背景 url mapping 我最早知道是作为 j ... -
tip:如何原生播放声音
2011-10-19 12:45 2977如果不想考虑浏览器间 ... -
转载:瀑布流布局浅析
2011-09-29 19:02 2845简介 如果你经 ... -
cross domain request
2011-09-29 18:39 2845场景 跨域请求是随着 ... -
基于多继承的树设计
2011-09-18 03:42 2268分类 树是一种常见 ... -
caja 原理 : 前端
2011-09-01 16:48 7047作为前端开放的基础安全保证,caja 是目前比较合 ... -
tokenization of html
2011-08-29 22:38 2786html 符号解析问题 场景: 在页面上输出包 ... -
ie 下 cloneNode 导致的属性克隆
2011-08-24 16:10 2475这个还是很值得记下,一直存在的很大隐患终于解决,由于在 ie& ... -
循环引用下的深度克隆
2011-08-04 20:39 2305深度复制和浅度复制 是当初初学 c 遇到的第一批问题,似乎使 ... -
模块的静态与动态循环依赖
2011-07-25 03:43 3278场景: 循环依赖 我是不支持的,但现实中似乎又确实需 ...
相关推荐
同时,我们引入了一个名为`blinking.js`的外部JavaScript文件,用于实现图片闪烁逻辑。 接下来,我们在`blinking.js`文件中编写JavaScript代码: ```javascript document.addEventListener('DOMContentLoaded', ...
在网页中,JavaScript通常嵌入在HTML代码中或者通过外部JS文件引用,使得网页具备动态性,提高了用户体验。"jsyanshi.rar_javascript"这个标题可能指的是一个包含JavaScript延迟效果的示例压缩包,而"javascript延时...
这个名为"mode_window"的压缩包可能包含了上述所有资源,包括HTML、CSS和JavaScript文件,用于构建和演示这个简单的JavaScript模态弹出窗口。通过学习和理解这些文件,开发者可以了解如何在自己的项目中实现类似的...
通过扩展String的prototype,我们可以添加自定义方法如`trim()`,这对外部使用者来说是透明的。 命名空间是一种管理JavaScript代码的策略,类似于Java中的`import`机制。通过创建和使用命名空间,我们可以确保在未...
7. **index.htm**:这是网页的主入口文件,通常包含HTML结构和内联JavaScript代码,或者是引入外部JavaScript文件的链接。通过这个文件,我们可以看到整个网页的布局和JavaScript如何与HTML配合工作。 8. **readme....
HTML文件通常包含结构化的文本内容和嵌入的JavaScript代码,或者链接到外部的JavaScript文件以保持代码的组织性。 在JavaScript中,字符渐变出现的实现可能涉及以下知识点: 1. **定时器(setTimeout 或 ...
遮罩层通常用于显示提示信息或加载状态,通过CSS和JavaScript可以创建覆盖整个页面或特定区域的半透明层,提高用户体验。 8. **工具和源码**:标签中的“工具”可能指的是开发者工具,如浏览器内置的开发者工具,...
创建完毕后,将这个link元素添加到head元素中,从而实现动态加载外部CSS文件的效果。 ### 总结 通过上述知识点的分析,我们可以了解到动态添加CSS样式表文件不仅涉及到DOM操作,还包含了兼容性处理、代码转换、...
HTML文件通过`<script>`标签来引入JavaScript代码,或者引用外部的.js文件来添加功能和特效。 `page`可能是一个文件夹,里面包含了多个页面或者组件,这些页面或组件各自展示了不同的JavaScript特效。每个页面可能...
这个名为"javascript实例"的压缩包包含了几个利用纯JavaScript实现的动画效果,旨在展示如何在不依赖任何外部组件的情况下,仅通过JavaScript库就能创建出丰富多彩的视觉表现。 在网页开发中,JavaScript常用于实现...
在HTML文档中,通过`<script>`标签引入JavaScript代码,或者使用外部JS文件来添加脚本。在这个特效中,JavaScript的主要作用是控制文本元素的可见性。 1. DOM操作:在JavaScript中,Document Object Model (DOM) 是...
其次,`ShowDiv.js`是JavaScript文件,它是控制遮罩层行为的核心。这个文件可能会包含以下功能: 1. **初始化**:在页面加载完成后,可能需要对遮罩层进行初始化,比如设置初始样式或者事件监听器。 2. **显示遮罩...
本资源“经典图片切换源码JavaScript”提供了一种使用纯JavaScript实现的图片轮播功能,无需依赖任何外部库如jQuery或React等。下面我们将深入探讨这个主题,解析其背后的原理和技术细节。 首先,JavaScript的事件...
在`bubble.js`或类似的脚本文件中,我们可以看到事件监听器(如`window.onload`或`DOMContentLoaded`),当页面加载完成后执行相应的函数。这些函数通常包括生成泡泡、随机位置设置、动态速度分配以及泡泡碰撞检测等...
此外,可能还会通过`<script>`标签引入外部的JavaScript文件,如jQuery库和自定义的JavaScript代码。 2. `images`:这个文件夹可能包含与登录表单相关的图像资源,比如背景图片,图标或者按钮状态变化的动画图片。...
例如,使用`<script>`标签引入外部JS文件或直接在HTML文档中编写内联脚本。 二、DOM操作 Document Object Model (DOM)是HTML和XML文档的编程接口。JavaScript通过DOM可以访问和修改网页元素。例如,通过`document....
在这个页面中,JavaScript代码可能被放在`<script>`标签内,或者是外部链接的`.js`文件中。开发者可能使用事件监听器如`addEventListener`来响应用户的交互,例如当页面加载完成或用户点击某个元素时触发特效。 ...
6. **资源管理**:项目中可能包含了Bootstrap的CSS和JS文件,以及可能的图片和其他外部资源。确保这些资源正确链接和加载是页面正常运行的关键。 通过分析这个公开源码,开发者不仅可以学习如何结合HTML、...
JavaScript代码通常被嵌入HTML文档中,或者作为外部.js文件链接到HTML页面。它通过DOM(Document Object Model)来操作网页元素,例如改变元素的样式、内容或位置。 在广告的定时显示隐藏中,我们可能会使用以下...
JavaScript代码通常位于`<script>`标签内或者外部引用的JS文件中。主要功能包括初始化状态、事件监听和处理函数。初始化状态时,会将第一张图片设为活动状态。事件监听可能包括点击按钮或自动定时器触发的事件。 4...