Ajax 板


LINE

※ 引述《liaosankai (低温烘焙)》之铭言: : 关於这个问题,我也是有相同的经验。最主要是因为javascript虽然可以单独 : 写成一个js档,再透过<script>标签读入,来达成某个程度上的程式码管理, : 但是你必须清楚的知道每个独立的js档案是否有用到其他js档,如果有则必须 : 一并为需要的JS档加上<script>标签来读入。而不是像一般的程式语言有汇入 : 其他档案的语法,像c++的include或java的import可以使用,所以当一个专案 : 变得很大的时候,通常最後为了能让网页正确执行,都会把所有js档全部读入 : 或全部集中成一个js档,但日後的如果有更新,势必要再把所有档案集中压缩 : 一次。 : 针对这个问题我尝试用过动态产生<script>来模拟import的方法,但是很遗憾 : 的,javascript是个直译式的语言,所以他并不会等待<script>建立完成才继 : 续下一段程式码,以下面为例子,假设Include函式实作了一个功能: : 建立<scirpt>,指定参数为url,并将<script>加入<head>的相关程式码。 : global.js 定义了某些变数: : ---------------------------------------------------------------- : var name = 'Kai'; : ---------------------------------------------------------------- : index.html 的javascript内容: : ---------------------------------------------------------------- : <script src="http://localhost/js/Include.js"></script> : <script> : function sayHello()[ : alert('hello, ' + name); : } : Include('http://localhost/js/global.js'); : sayHello(); : </script> : ---------------------------------------------------------------- : 我们尝试呼叫位於另一个js档案所宣告的name变数,你期望应该看到的是 : hello, Kai : 但是浏览器会很残酷的跟你说没有这个东东,跑出变数未定义的大错误,因为 : sayHello()并不会等待 Include()的完成,就会立刻执行,这结果相当令人沮 : 丧,但是如果你尝试延迟执行函式: : setTimeout('sayHello()', 1000); : 你就能看到与预期相符的结果,表示档案确实是有被读入,也有完成程式码的 : 执行,但是我们没办法限制程式码的执行顺序。 : 最後透过不同的逻辑方式,我尝试成功实作了档案汇入的机制,当然在规则上 : 有其一定的限制,但在执行上确实能达到档案组织管理的好处,不妨可以参考 : 看看或互相交流讨论,提供更好的意见 : 专案位置 : http://code.google.com/p/jclassscript/ Include('http://localhost/js/global.js'); 这有个专用名词 On-Demand Javascript 这在javascript的领域里是一门很高深的学问 意思即在 javascript程式码片段 在需要的时候才载入 举凡 按下一个button的时候 在event handler中 才去载入一个动画的.js 在login的画面 按下submit 才去载入整个login.js 为什麽要这样做 无非是降低频宽的使用量 以及使用者的流畅性 如果把javascript打包成一整包 在第一页就载入 那麽第一页可能要花上数分钟 尤其是一些 framework 可能是非常fat的 而每一页的button 有可能使用者并不都会去按 那麽载入一个完整的js 无疑是另外一种浪费 想像一下把fckeditor整个编辑器载入要花多少时间 若是使用者根本没有编辑文件 那麽这个载入就太笨了 On-Demand Javascript在 Ajax Design Patterns一书第六章有完整的介绍 这跟import的差距是非常大的import是在compiler之前 而On-Demand则是在解译之後 以下提供一段程式码供各位参考 function LoadScript( url ){ var httpRequest = createXMLHttpRequest(); httpRequest.open("GET",url,false); httpRequest.send(null); //send要加null否则ff不work var script = httpRequest.responseText; //以下适用各种浏览器ondemand js 解决方法从ajaxian获得解答 //IE对eval()完全无法建置在全域下 所以改用execScript if (window.execScript) { window.execScript(script); // eval in global scope for IE } else { with(window) { window.eval(script); } } } function createXMLHttpRequest() { try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {} try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {} try { return new XMLHttpRequest(); } catch(e) {} alert("XMLHttpRequest not supported"); return null; } 其中重要的关键在 httpRequest.open("GET",url,false); 我是用false 所以程式码一定在完整回传之後 javascript才会做下一件事 而不是非同步呼叫 当然啦如果想要背景载入 也可以用非同步的方式 : <script> : function sayHello()[ : alert('hello, ' + name); : } : Include('http://localhost/js/global.js'); : sayHello(); : </script> 这段程式并不会不能执行 function在载入的时机是死的 直到加了()才会执行 所以 sayHello() {...........} 这段并不会在载入时机执行 问题出在sayHello(); 如果将sayHello();直接写在javascript 当然javascript哪时候载入 就会哪时候执行到 因此必须将sayHello(); 写在onload的时机 onload发生在所有页面及js载入後 只需把程式改成 window.onload = init; function init() { Include('http://localhost/js/global.js'); sayHello(); } 那麽先载入的function sayHello也是正常的 有关载入时机请参阅ppk on javascript 4-E 另外Include('http://localhost/js/global.js'); 改成 Include('http://localhost/js/global.js?' + ( new Date() * 1) ); 会更好 加了一个不断随时间改变的querystring 会使的url变的不同 那麽.js档 就会是最新的啦 因为浏览器的判断是否要重新载入网页 是依照网址是否相同 我通常在网页的开始只载入依些基本的util.js 还有上述段LoadScript utility 其他的功能都分散在各小段的js档 直到使用者要用到时才呼叫 --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 203.70.98.144
1F:→ ileadu:以现在的速度 载第一页就要数分钟有点夸大了 是数秒钟 09/26 08:01
2F:推 s25g5d4:我都用Math.round(Math.random() * 1000) 09/26 09:37
3F:→ TonyQ:而且如果搭配把script 放在 </body> 前 对大部分页面来讲 09/26 13:26
4F:→ TonyQ:几乎是无感(除非你倚赖js做进场动画...)。而且比起每次都 09/26 13:26
5F:→ TonyQ:要分开读取档案,打成一包的traffic 搭配cache效果反而更好. 09/26 13:26
6F:→ TonyQ:另外舅是通常大部分状况下,重新载入是不需要,多是给版本号 09/26 13:28
7F:→ TonyQ:要用这个作法,我比较推荐 using.js 。 09/26 13:28







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:e-shopping站内搜寻

TOP