好久没有研究JS了,近期这个项目,前端用到了JS,对界面要求较高,单位又没有打算专门找前端人员,这样前端方面的工作就落到俺们的身上了,不过也好,对JS重新看看,温故温故,这几天学习了JS中闭包相关的知识点,这里整理下,与大家分享下,大鸟请忽略O(∩_∩)O~
开始了:
事实上,通过使用闭包,我们可以做很多事情。比如模拟面向对象的代码风格;更优雅,更简洁的表达出代码;在某些方面提升代码的执行效率。
第一点、缓存
来看一个例子,设想我们有一个处理过程很耗时的函数对象,每次调用都会花费很长时间,那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,如果找不到,则进行计算,然后更新缓存并返回值,如果找到了,直接返回查找到的值即可。闭包正是可以做到这一点,因为它不会释放外部的引用,从而函数内部的值可以得以保留。
2 02. var cache = {},
3 03. count = [];
4 04. return {
5 05. attachSearchBox : function(dsid){
6 06. if(dsid in cache){//如果结果在缓存中
7 07. return cache[dsid];//直接返回缓存中的对象
8 08. }
9 09. var fsb = new uikit.webctrl.SearchBox(dsid);//新建
10 10. cache[dsid] = fsb;//更新缓存
11 11. if(count.length > 100){//保正缓存的大小<=100
12 12. delete cache[count.shift()];
13 13. }
14 14. return fsb;
15 15. },
16 16.
17 17. clearSearchBox : function(dsid){
18 18. if(dsid in cache){
19 19. cache[dsid].clearSelection();
20 20. }
21 21. }
22 22. };
23 23.})();
24 24.
25 25.CachedSearchBox.attachSearchBox("input1");
这样,当我们第二次调用CachedSearchBox.attachSerachBox(“input1”)的时候,我们就可以从缓存中取道该对象,而不用再去创建一个新的searchbox对象。
第二点、实现封装
先来看一个关于封装的例子,在person之外的地方无法访问其内部的变量,而通过提供闭包的形式来访问:
2 02. //变量作用域为函数内部,外部无法访问
3 03. var name = "default";
4 04.
5 05. return {
6 06. getName : function(){
7 07. return name;
8 08. },
9 09. setName : function(newName){
10 10. name = newName;
11 11. }
12 12. }
13 13.}();
14 14.
15 15.print(person.name);//直接访问,结果为undefined
16 16.print(person.getName());
17 17.person.setName("abruzzi");
18 18.print(person.getName());
19 19.
20 20.得到结果如下:
21 21.
22 22.undefined
在丰富的Dojo框架库中,Dojo Core 提供了一个 io 包,由两个对象组成:dojo.io.iframe 和 dojo.io.script,Dojo 的官方说明把他们描述成“高级传输层(advanced ajax transport layer)”。使用 dojo.io.iframe 同样可以跟服务器交互,但是它的实现思路是有别于 XHR 对象的。dojo.io.iframe 的使用方式、参数与 xhrGet 非常相似。如xhrGet 中的from,url,handleAs,load 等参数在这里也存在,但有一处不同的是 method,method 表示 dojo.io.iframe 将以何种 HTTP Method 来发送请求。
疑问:
- dojo.io.iframe 是如何工作的呢?
- 除了 XHR 对象之外还有什么方法可以实现表单的异步提交?
其实这一切都很简单,dojo.io.iframe 首先会创建一个隐藏的 iframe 并插入到父页面的最后,然后设置此 iframe 的 src 属性为dojo-module-path/resources/blank.html(dojo-module-path 指 dojo 包所在的目录),iframe 页面的 onload 事件的处理函数被设置为父窗体的回调函数。接下来就是在 iframe 页面中发送请求,并接收服务器的响应。当 iframe 接收到服务器的反馈并加载完之后,父窗体的回调函数即被调用。
疑问:
那么dojo.io.iframe有哪些函数呢?
- create(fname, onloadstr, uri) 用来在页面中创建 iframe。
所创建 iframe 的名字,setSrc 和 doc 函数据此引用创建的 iframe
onloadstrString表示 iframe 加载完成后执行的回调函数
uriStringiframe 请求的资源,当 uri 为空时,将加载dojo-module-path/resources/blank.html
- doc(iframeNode) 获取指定的 iframe 页面的 DOM 根节点,有了它可以对 iframe 页面进行任意的操作。
- setSrc(iframe, src, replace) 设置指定的 iframe 的 src 属性,这将导致 iframe 页面重新加载。
dojo.io.iframe 采用了不同的思路实现了“异步”发送请求,但是 dojo.io.iframe 使用并不多,因为当页面中多处需要异步通信时,在页面中创建很多的 iframe 并不是好的注意。在能使用 xhr 框架的地方尽量使用 xhr 框架,唯一值得使用 iframe 的地方是发送文件。
疑问:
来个例子呗?
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>dojo.iframe笔记 --http://www.cnblogs.com/f-ye</title>
<!-- import css -->
<link href="/Dojoroot/dojo/resources/dojo.css" rel="stylesheet" type="text/css" />
<link href="/Dojoroot/dijit/themes/soria/soria.css" rel="stylesheet" type="text/css" />
<!-- import js -->
<script type="text/javascript" src="/Dojoroot/dojo/dojo.js" data-dojo-config="parseOnLoad: false, async:true"></script>
</head>
<body >
<div>
<label>教程文件</label>
<form id="uploadForm" method="post" enctype="multipart/form-data">
<input id="courseFile" name="courseFile" type="file" />
</form>
</div>
<div>
<input type="button" value="上传" onclick="DoUpload()"
【1、最基本的js弹出对话框窗口代码】
这是最基本的js弹出对话框,其实代码就几句非常简单:
<!--
window.open ("page.html")
-->
</script>
因为这是一段javascripts代码,所以它们应该放在<script LANGUAGE="javascript">标签和</script>之间。<!-- 和-->是对一些版本低的浏览器起作用,在这些老浏览器中不会将标签中的代码作为文本显示出来。要养成这个好习惯啊。
window.open ("page.html") 用于控制弹出新的窗口page.html,如果page.html不与主窗口在同一路径下,前面应写明路径,绝对路径(http://)和相对路径(../)均可。用单引号和双引号都可以,只是不要混用。
这一段代码可以加入HTML的任意位置,<head>和</head>之间可以,<body>间</body>也可以,越前越早执行,尤其是页面代码长的页面,这种js弹出对话框想早点弹出就尽量往前放。
【2、增加属性设置的js弹出对话框代码】
下面再说一说js弹出对话框窗口属性的设置。只要再往上面的代码中加一点东西就可以了。
我们来定制这个js弹出对话框弹出的窗口的外观,尺寸大小,弹出的位置以适应该页面的具体情况。
<!--
window.open("page.html", "newwindow","height=100, width=400, top=0,left=0,toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no,status=no")
//写成一行
-->
</script>
参数解释:
<script LANGUAGE="javascript"> js脚本开始;
window.open 弹出新窗口的命令;
"page.html" 弹出窗口的文件名;
"newwindow" 弹出窗口的名字(不是文件名),非必须,可用空""代替;
height=100 窗口高度;
width=400 窗口宽度;
top=0 窗口距离屏幕上方的象素值;
left=0 窗口距离屏幕左侧的象素值;
toolbar=no 是否显示工具栏,yes为显示;
menubar,scrollbars 表示菜单栏和滚动栏。
resizable=no 是否允许改变窗口大小,yes为允许;
location=no 是否显示地址栏,yes为允许;
status=no 是否显示状态栏内的信息(通常是文件已经打开),yes为允许;
</script> js脚本结束
【3、用函数控制js弹出对话框窗口】
下面是一个完整js弹出对话框的代码。
<head>
<script LANGUAGE="javascript">
<!--
function openwin() { window.open ("page.html", "newwindow", "height=100, width=400, toolbar=
no, menubar=no, scrollbars=no, resizable=no, location=no, status=no")
//写成一行
}
//-->
</script>
</head>
<body onload="openwin()">
...任意的页面内容...
</body>
</html>
这里定义了一个函数openwin(),函数内容就是打开一个窗口。在调用它之前没有任何用途。
怎么调用呢?
方法一:浏览器读页面时弹出窗口;
方法二:浏览器离开页面时弹出窗口;
方法三:用一个连接调用:
注意:使用的“#”是虚连接。
方法四:用一个按钮调用:
【4、同时弹出2个窗口的js弹出对话框】
对源代码稍微改动一下:
<!--
function openwin()
{window.open ("page.html", "newwindow", "height=100, width=100,top=0,left=0,toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no")
//写成一行
window.open ("page2.html","newwindow2", "height=100, width=100, top=100, left=100,toolbar=no,menubar=no, scrollbars=no, resizable=no, location=no, status=no")
//写成一行
}
//-->
</script>
为避免弹出的2个窗口覆盖,用top和left控制一下弹出的位置不要相互覆盖即可。最后用上面说过的四种方法调用即可。
注意:2个js弹出对话框窗口的name(newwindows和newwindow2)不要相同,或者干脆全部为空。
【5、主窗口打开文件1.htm,同时弹出小窗口page.html】
如下代码加入主窗口<head>区:
<!--
function op