Chrome 4.0.249.0
今天用chrome测试公司的项目页面,发现了个比较严重的问题。 Main页面里面有 iframe, 所有的操作都在iframe 内。 问题就在这里了,如果 执行iframe 里面有 history.back(-1) 。那么整个main页面都会 退回到上一页。而不是 iframe内的页面退回上一页。按chorme 的退后按钮,结果都是一样。 同测 FF IE 都没这个问题。 即使iframe内改成 self.history.back 也同样不行。 真神奇了..
到底是 Chrome 的bug.. 还是代码问题.. 没搞懂。
闭包这个词看过很多网站都有说。大家说的方法都大致一样。 今天看了一些大陆的文章,看到我头晕眼花,没看懂它的真正意识。 找了篇 Mozilla 关于闭包运用的文章。 讲述的比较系统易懂。
闭包的运用
闭包(Closure)经常会被认为是 JavaScript 的高级机能,但了解闭包是精通语言的必要之事。
思考以下的函数︰
function init() {
var name = "Mozilla";
function displayName() {
alert(name);
}
displayName();
}
init() 函数建立了称为 name 的局域变量,然后定义了称为 displayName() 的函数。displayName() 是内部的函数 – 他是在 init() 内部定义的,而且只在函数本体内部才可使用。displayName() 没有他自己的局域变量,但会重复使用在外部函数里所宣告的 name 变量。
本例只会做一点事 – 试试执行代码看会发生什么。这是词汇作用域的范例︰在 JavaScript 中,变量的作用域是由他自己在原始码中的位置所定义的,且内部的函数能够存取宣告于外部作用域的变量。
现在思考下例︰
function makeFunc() {
var name = "Mozilla";
function displayName() {
alert(name);
}
return displayName;
}
var myFunc = makeFunc();
myFunc();
如果你执行这个代码,将会发生和前一个 init() 例子完全相同的效果︰字符串 "Mozilla" 将会被显示在 JavaScript 的警告方框中。其中的不同点 – 以及有趣的一点 – 是内部的 displayName() 函数会在执行之前从外部的函数所返回。
代码的运作看起来也许很不直觉。通常说,在函数内部的局域变量只存在于函数执行的期间。一旦 makeFunc() 执行完毕,预期不再需要 name 变量是很合理的。由于代码仍旧以预期般的运作,很明显情况并不如此。
对于这个难题的解答是 myFunc 已经变成闭包了。闭包是一种特殊的对象,其中结合了两样东西︰函数,和函数所建立的环境。环境由任意的局域变量所组成,这些变量是由在闭包建立的时间点上存在于作用域里的所有变量。既然如此,myFunc 就是结合了 displayName 函数和闭包建立之后就存在的 "Mozilla" 字符串这两者的闭包。
这里还有更为有趣的范例 – makeAdder 函数︰
function makeAdder(x) {
return function(y) {
return x + y;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
print(add5(2)); // 7
print(add10(2)); // 12
在这个范例中,我们已经定义了函数 makeAdder(x),可接受单一参数 x,并返回新的函数。返回的函数会接受单一参数 y,并返回 x 和 y 的合。
就本质而言,makeAdder 是函数的制造机 – 他会建立可以把指定的值和他们的参数相加的函数。在上例中,我们使用了我们的函数制造机来建立两个新的函数 – 一个给他自己的参数加上 5,另一个则加上 10。
add5 和 add10 两个都是闭包。他们共享相同的函数本体的定义,但保存了不同的环境变量。在 add5 的环境中,x 是 5。至于互有关连的 add10,x 是 10。
实用的闭包
该是抛开理论的时候了 – 但是闭包真的有用吗?让我们思考闭包潜在的用处。闭包让你把一些数据(环境)和可操作数据的函数联系在一起。这一点明显和面向对象程序设式并行不悖,对象可让我们把一些数据(对象的属性)和一个以上的方法联系在一起。
因此,如果通常你会在某个地方使用附有单一方法的对象,你可以在这些地方使用闭包。
视情况你可能会想这样做,这在 Web 上尤其常见。我们写在 Web 上的 JavaScript 代码多半是以事件为基础 – 我们定义了一些行为,然后把这些行为和由使用者所触发的事件(如 click 或 keypress)连系在一起。我们的代码通常被连系为 Callback︰在响应事件时,所执行的单一函数。
这里有个实际的例子︰假如我们希望在页面上加入可以调整页面文字的按钮。以像素为单位,指定 body 元素的 font-size 是一个方法,然后以 em 为单位,设定在页面上(如页眉)的其他元素的大小︰
body {
font-family: Helvetica, Aria, sans-serif;
font-size: 12px;
}
h1 {
font-size: 1.5em;
}
h2 {
font-size: 1.2em;
}[/code]
我们的交互式文字大小按钮可以改变 body 元素的 font-size 属性,拜相对单位之赐,接着对其他的元素做调整。
JavaScript 代码︰
function makeSizer(size) {
return function() {
document.body.style.fontSize = size + 'px';
};
}
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
现在 size12、size14 和 size16 这些函数可分别调整 body 文字的大小为 12、14 和 16 像素。我们可以把代码和按钮(本例中使用的是连结)连系在一起,如下︰
function setupButtons() {
document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;
}
<a href="#" id="size-12">12</a>
<a href="#" id="size-14">14</a>
<a href="#" id="size-16">16</a>
使用闭包模拟私有的方法
像 Java 这类语言可以把方法宣告为私有的,意思是这些方法只能被同一类别的其他方法所呼叫。
JavaScript 并不提供做这些事的原生方式,但可以使用闭包来模拟私有方法。私有方法不只是对限制代码的存取这方面有用︰同时也是管理你的全局命名空间的强大方式,把非必要的方法堆在公开的界面里。
这里是如何使用闭包来定义可以存取私有函数和变量的公开函数︰
var Counter = (function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
}
})();
alert(Counter.value()); /* 显示 0 */
Counter.increment();
Counter.increment();
alert(Counter.value()); /* 显示 2 */
Counter.decrement();
alert(Counter.value()); /* 显示 1 */
在此完成了很多事。在上一个范例中,每一个闭包都有他自己的环境;此处我们建立了由三个函数所共享的单一环境︰Counter.increment、Counter.decrement、Counter.value。
共享的环境是建立在无名函数的本体内,无名函数一经定义就会开始执行。环境内含两个私有项︰称作 privateCounter 的变量,以及称作 changeBy 的函数。这两个私有项都不能在无名函数外部被直接存取。相对的,必须由三个公开的函数来存取这些私有项,这三个函数是从无名函数的封装器所返回的。
这三个公开的函数共享闭包的同一个环境。感谢 JavaScript 的词汇作用域,这三个函数都能存取 privateCounter 变量和 changeBy 函数。
按照这个方式来运用闭包,可以得到通常是附加在面向对象程序设计里的数据隐藏和封装的好处。
在循环中建立闭包︰常见的错误
在 JavaScript 1.7 引入 let 关键词以前,闭包常见的问题出现在当闭包是在循环内部建立的时候。思考以下的例子︰
<p id="help">这里会显示有用的提示</p> <p>E-mail: <input type="text" id="email" name="email"></p> <p>姓名: <input type="text" id="name" name="name"></p> <p>年龄: <input type="text" id="age" name="age"></p>
function showHelp(help) {
document.getElementById('help').innerHTML = help;
}
function setupHelp() {
var helpText = [
{'id': 'email', 'help': '你的 e-mail 地址'},
{'id': 'name', 'help': '你的完整姓名'},
{'id': 'age', 'help': '你的年龄(你必须大于 16 岁)'}
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.help);
}
}
}[/code]
helpText 数组定义了三个有用的提示,每一个都和文件中的输入字段的 ID 连系在一起。循环会在这些定义里巡回一圈,给每一个显示相关连的说明的方法使用 onfocus 事件。
如果你试着执行这个代码,你会发现他并不如预期般的运作。不管你把焦点放在哪一个字段上,都会显示关于你的年龄的讯息。
这其中的原因是代入给 onfocus 的函数是闭包;这些闭包是由函数的定义和从 setupHelp 函数的作用域所捕捉到的环境所组成的。这三个闭包已经建立了,但每一个都共享同一个环境。每次执行 onfocus 的 Callback 的时候,循环执行的是他自己的闭包,以及指向 helpText 列表中的最后一项的变量 item(由三个闭包所共享)。
本例的解决方法是使用更多的闭包︰特别是使用稍早已描述过的函数制造机︰
function showHelp(help) {
document.getElementById('help').innerHTML = help;
}
function makeHelpCallback(help) {
return function() {
showHelp(help);
};
}
function setupHelp() {
var helpText = [
{'id': 'email', 'help': '你的 e-mail 地址'},
{'id': 'name', 'help': '你的完整姓名'},
{'id': 'age', 'help': '你的年龄(你必须大于 16 岁)'}
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = makeHelpCallback(item.help);
}
}
这次就如预期般运作。而不是所有的 Callback 都共享单一的环境,makeHelpCallback 给每一个 help 建立新的环境,此处的 help 参照了相对应的 helpText 数组的字符串。
如果你使用 JavaScript 1.7 以上的版本,你可以使用 let 关键词建立具有区块层级作用域的变量来解决这个问题︰
for (var i = 0; i < helpText.length; i++) {
let item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.help);
}
}
let 关键词使 item 变量改用具有区块层级的作用域来建立,导致 for 循环每一次反复都能建立新的参考。意思是每一个闭包都会捕捉到个别的变量,解决因为共享同一环境所引起的问题。
效能的考虑
如果并没有特定的任务需要用到闭包,且闭包对 Script 的效能会有负面的影响,因此在其他函数的内部里建立不必要的函数是很不智的。
例如,当建立新的对象或类别时,通常应该要把方法和对象的原型连系在一起,而不是在对象的建构子中定义。这其中的理由是,每当呼叫建构子的时候,就要把方法代入(也就是每一个对象正在建立的时候)。
思考以下不切实际的例子︰
function MyObject(name, message) {
this.name = String(name);
this.message = String(message);
this.getName = function() {
return this.name;
};
this.getMessage = function() {
return this.message;
};
}
上面的代码并未从闭包的行为中取得好处,应该改用重整过的形式︰
function MyObject(name, message) {
this.name = String(name);
this.message = String(message);
}
MyObject.prototype = {
getName: function() {
return this.name;
},
getMessage: function() {
return this.message;
}
};
或者是︰
function MyObject(name, message) {
this.name = String(name);
this.message = String(message);
}
MyObject.prototype.getName = function() {
return this.name;
};
MyObject.prototype.getMessage = function() {
return this.message;
};
今天无聊,逛了下Jquery 插件超市,看到个 Tagger插件。 现在我们写Blog,填写 Tag的时候,多数都是用分号逗号方式隔开。而这个插件使用了input 数组的方式。原理使用相同的name:<input type="text" name="test[]"/>
接收的时候,会以数组的形式接收。 看看具体的 Demo
今日好得意,群里面讨论到1024×768分辨率下,页面的宽度做几大为适合。
某人就话1003,在全屏情况下就是满屏的。没错,这个是理论值!当你机器的分辨率是1024*768下,而且系统是默认XP,IE 唔可以装任何插件,FF唔可以装ALL in One 等插件,全屏的时候系唔会出现横滚动条。但是事实上要满足这个条件系唔可能的。
如果真的使用理论值来做页面,那么那些装了插件,或者喜欢将收藏夹放左边栏的人。就永远都看到那个讨人厌横滚动条。
根据目前国外比较流行的 960grid- http://960.gs/ ,大部分视觉很good网站都是用 960px 来做页面的。为什么用960px来做?可以去佢官方度睇下。有D人就话拉. 用960px系被人洗脑了,做栅格化。 我都无语中… 有本事你米搞个999px去洗人家脑咯。
另外就系1003px系一个理论值,你可以用1003去做页面,但是只要页面稍微多1px出来,特别是多人同时做一个页面噶时候,咁你就屙撚。所以最好就唔好老点人用1003啦.. 唔系就同中国电信一样:E8套餐6M,下载就上唔500K,因为事实系4+2M。
另外发现就系企业能不能做高端市场,唔系由企业话事,系由员工去话事。讲唔埋就发烂咂闹人点做高端市场。
div 垂直居中这个话题搜索引擎一堆,方法也有好几种。下面介绍一种比较快捷的方法。
假如 box 的高和宽为100px
.centered_div { width: 100px; height: 100px; position: absolute; top: 50%; left: 50%; margin-left: -50px; margin-top: -50px; background: red; }
假如 box的宽度为500px 高度为200px
.centered_div { width:500px; height: 200px; position: absolute; top: 50%; left: 50%; margin-left: -250px; margin-top: -100px; background: red; }
最近在研究 greenmonkey ,发现 userscripts.org 里面提供了很多网站的一些 script。
回归正题,jquery 如何判断DOM 是否存在..
if($("#test").length>0) 或者 if($("#test").size()>0)
传统的iframe 自适应高度
<iframe id="frame_content" src="frame_content.html" scrolling="no" frameborder="0" onload="this.height=this.contentWindow.document.documentElement.scrollHeight"></iframe>
这种是针对 frame内容已静态输出了高度。而当frame页面有 dom 操作改变了页面高度的时候,怎么办?
参考了 口碑UED 的一片文章,使用的方法是setInterval 不断刷新frame框架页面,让frame内容页面高度改变时调整高度。 而为了避免影响性能,可以通过 iframe内的页面对dom操作改变了高度的时候,再去执行父级调整iframe高度。
最后代码:
<iframe id="frame_content" src="iframe_content.html" scrolling="no" frameborder="0" onload="this.height=this.contentWindow.document.documentElement.scrollHeight"></iframe>
<script type="text/javascript">
function reinitIframe(){
var iframe = document.getElementById("frame_content");
try{
var bHeight = iframe.contentWindow.document.body.scrollHeight;
var dHeight = iframe.contentWindow.document.documentElement.scrollHeight;
var height = Math.max(bHeight, dHeight);
iframe.height = height;
}catch (ex){}
}
// window.setInterval("reinitIframe()", 200);
</script>
<!--在iframe_contnet.html 页面,当对DOM操作的时改变了高度,就加入下面代码。 -->
window.parent.reinitIframe();
在这里强烈屌7 x独份子,搞到我们很多网站都上不到。正扑街含家产! 为了可以正常使用社交网站的服务,提供修改hosts方法访问。那些暴动份子看了死全家!
修复 Facebook YouTube fs2you twitter 等一些常用网站。高级用户自己看吧.. 把不需要的删了。
添加下面到 system32/drivers/etc/host 文件
124.40.42.105 www.facebook.com
124.94.101.133 cachefile13.fs2you.com
124.94.101.133 file13.fs2you.com
124.94.101.146 cachefile25.fs2you.com
124.94.101.146 file25.fs2you.com
125.46.41.27 cachefile18.fs2you.com
125.46.41.27 file18.fs2you.com
125.91.11.223 cachefile19.fs2you.com
125.91.11.223 file19.fs2you.com
127.0.0.1 activate.adobe.com
128.121.146.101 assets0.twitter.com
128.121.146.101 assets1.twitter.com
128.121.146.101 static.twitter.com
128.121.146.228 twitter.com
128.121.146.228 www.twitter.com
128.121.146.229 assets2.twitter.com
128.121.146.229 assets3.twitter.com
203.208.33.100 gdata.youtube.com
203.208.39.104 www.youtube.com
208.80.152.2 en.wikipedia.org
208.80.152.2 wikipedia.org
208.80.152.2 www.wikipedia.org
208.80.152.2 zh.wikipedia.org
209.85.225.136 mt2.google.com
218.75.151.10 cachefile15.fs2you.com
218.75.151.10 file15.fs2you.com
218.75.151.4 cachefile11.fs2you.com
218.75.151.4 file11.fs2you.com
221.204.246.115 cachefile14.fs2you.com
221.204.246.115 file14.fs2you.com
221.204.246.79 cachefile3.fs2you.com
221.204.246.79 file3.fs2you.com
222.169.230.101 dyn.www.fs2you.com
222.169.230.98 cachefile2.fs2you.com
222.169.230.98 file2.fs2you.com
281.201.39.38 klinoneshoes.info
58.211.75.31 cachefile12.fs2you.com
58.211.75.31 file12.fs2you.com
58.211.75.49 cachefile8.fs2you.com
58.211.75.49 file8.fs2you.com
58.218.209.126 cachefile16.fs2you.com
58.218.209.126 file16.fs2you.com
58.218.209.49 cachefile.fs2you.com
58.218.209.49 file.fs2you.com
59.32.232.195 cachefile1.fs2you.com
59.32.232.195 file1.fs2you.com
59.53.48.134 cachefile20.fs2you.com
59.53.48.134 file20.fs2you.com
59.53.48.136 cachefile21.fs2you.com
59.53.48.136 file21.fs2you.com
59.53.48.144 cachefile22.fs2you.com
59.53.48.144 file22.fs2you.com
59.53.48.172 cachefile24.fs2you.com
59.53.48.172 file24.fs2you.com
60.2.139.27 cachefile5.fs2you.com
60.2.139.27 file5.fs2you.com
61.134.84.238 cachefile9.fs2you.com
61.134.84.238 file9.fs2you.com
61.139.106.204 cachefile23.fs2you.com
61.139.106.204 file23.fs2you.com
61.150.85.80 cachefile4.fs2you.com
61.150.85.80 file4.fs2you.com
61.156.40.181 cachefile10.fs2you.com
61.156.40.181 file10.fs2you.com
61.157.152.173 cachefile17.fs2you.com
61.157.152.173 file17.fs2you.com
61.166.111.227 cachefile26.fs2you.com
61.166.111.227 file26.fs2you.com
61.174.62.131 cachefile7.fs2you.com
61.174.62.132 file7.fs2you.com
61.184.189.10 cachefile6.fs2you.com
61.184.189.10 file6.fs2you.com
64.211.21.152 b.static.ak.facebook.com203.208.39.104 youtube.com
64.233.161.104 help.youtube.com
64.233.161.104 maps.l.google.com
64.233.161.136 mt1.google.com
64.233.161.147 map.google.com
64.233.161.147 www.google.com
64.233.161.190 mt0.google.com
64.233.161.93 mt.l.google.com
64.233.169.17 googlemail.l.google.com
65.74.185.41 help.twitter.com
65.74.185.41 twitter.zendesk.com
66.102.1.103 www.l.google.com
66.102.1.83 mail.google.com
69.192.34.110 s-static.ak.facebook.com
69.63.176.59 secure-media-sf2p.facebook.com
69.63.176.69 secure-profile.facebook.com
69.63.178.13 ssl.facebook.com
69.63.180.173 login.facebook.com
72.14.247.111 pop.gmail.com
74.125.113.101 docs.google.com
74.125.113.101 spreadsheets.google.com
74.125.113.147 scholar.google.com
74.125.45.100 google.com
74.125.91.113 groups.l.google.com
74.125.91.118 upload.youtube.com
74.125.91.136 picasaweb.google.com
74.125.93.101 books.google.com
74.125.93.102 groups.google.com
74.125.93.102 id.google.com
74.125.93.102 id.l.google.com
74.125.93.102 insight.youtube.com
74.125.93.111 smtp.gmail.com
74.125.93.136 khm.google.com
74.125.93.99 news.google.com
96.6.122.57 profile.ak.facebook.com
rayfile.com fs2you.com
www.rayfile.com www.fs2you.com
XHTML 2 Working Group Expected to Stop Work End of 2009, W3C to Increase Resources on HTML 5
2009-07-02: Today the Director announces that when the XHTML 2 Working Group charter expires as scheduled at the end of 2009, the charter will not be renewed. By doing so, and by increasing resources in the Working Group, W3C hopes to accelerate the progress of HTML 5 and clarify W3C’s position regarding the future of HTML. A FAQ answers questions about the future of deliverables of the XHTML 2 Working Group, and the status of various discussions related to HTML. Learn more about the HTML Activity.

reply