从父窗口调用子窗口的方法
这是一个BOM问题,我这里指的子窗口(child window)是指从一个窗口通过window.open或iframe技术所创建的window对象,当然,父窗口(parent window)就是创建子窗口的原始窗口。网上总是有许多介绍从子窗口调用父窗口的方法的文章,但没有讲如何从父窗口调用子窗口方法,这里晒一晒最近做项目摸索出的小窍门,看代码吧:
var childWin, interval,
callFunc = function(){
if(childWin.childFunc){ //childFunc表示试图调用的存在于子窗口的函数
childWin.childFunc();
window.clearInterval(interval);
}
};
interval = window.setInterval(callFunc,300);
childWin = window.open('some-url', 'some-windowname');
由于window.open是异步执行的,子页面的加载需要一定时间,也就是说childFunc并不是马上就会出现,所以做了一个300ms的轮循来检查childFunc的可用性。当然,由于安全因素,此方法只适用于两个页面主域相同的情况。
My first Safari 5 bug
听说Safari5比Firefox快1倍,甚至比Chrome还要快一点(3%)。我也迫不及待地将Safari更新至最新版本(Safari for Windows)。最近试用时发现了一个bug,现发布在此,看看大家有无此现象。
该bug的现象是:通过与页面交互而产生的阻塞(block)窗口并不能阻止用户继续对页面内容进行操作,例如:在我的测试页面中,点击彩色的区块可以产生一个alert对话框,按照正确的处理方式,在关闭此对话框之前我们将不能对页面进行操作,然而事实不是这样,你仍然可以通过鼠标激发每个彩色区块的hover状态、可以继续点击彩色区块弹出alert对话框、可以点击页面上的链接(Link 1),你甚至可以穿过对话框点击一个看不见的链接(Link 2),不信你试试,很疯狂吧?目前我知道的能回到正常轨道的方法是:用鼠标点击一下页面上还没有绑定事件的区域。
我刚刚提到,这个bug的出现需要与页面交互,例如在页面加载完成后自动弹出的alert并没有问题;同时,这个bug同样存在于promt和confirm函数。
虽然alert、promt、confirm如今已经用得很少了,但当这个bug出现时,还是会造成更差的使用体验和安全隐患的。
IE6 resize event bug 解决方案
最近写组件时碰到一个问题:对window对象监听resize事件,当浏览器窗口大小发生改变时,在IE6和IE7下监听函数会被执行多次,这与我们期望的执行一次可不吻合。更可怕的是,在某些DTD下,DOM中某个元素区块的大小发生变化时也会激发window的resize监听函数,且在IE6和IE7下看我的例子。在这个例子里,当点击”Zoom In”或”Zoom Out”改变红框大小时,激发了window的resize事件,不过元素的位置移动不会导致这个bug,不信点击”Move”按钮移动绿框试试,以上这些奇怪的效果IE7同样存在。至于浏览器窗口大小发生改变时监听函数反复执行的错误就与DTD没有关系了。为了防止函数多次执行,每次window的resize事件发生时,我们可以判断一下浏览器窗口大小是否改变了,只有真的改变时我们才执行监听函数,Javascript代码大概会是这样:
...
var width = document.documentElement.clientWidth,
height = document.documentElement.clientHeight;
window.onresize = function(){
if(width != document.documentElement.clientWidth ||
height = document.documentElement.clientHeight){
resizeFunc();
}
width = document.documentElement.clientWidth;
height = document.documentElement.clientHeight;
}
...
为什么不加一个浏览器检测呢,那样在非IE浏览器下就可以用常规写法了。可是据我测试,风头不小的Chrome也会犯这个错误。所以,还是以防万一吧。
用YQL帮助显示Twitter消息
我们经常看到一些Blog或者内容发布站点会将自己的Twitter消息显示在网站的某个位置(比如边栏),这些功能大多都是由后台程序(如PHP)来完成,若没有个人可管理的服务器或者不支持运行后台程序将无法使用;使用JavaScript版的则需要浏览器端能正常访问Twitter数据源,但由于某些网络原因也无法实现。
今天自己动手写了一个基于YQL和JavaScript的简单脚本,可以帮助人们实现显示个人Twitter消息的需求,本页面边栏的“Tweets”就是使用它来实现的。所以只要你的站点可以运行JavaScript,并且能访问YAHOO! API ;那么就放心地将下面的代码嵌入到你想在自己站点上显示Twitter 的地方吧,如下:
<script type=”text/javascript” src=”http://swayweb.com/labs/twitter_timeline.js”>id:swaydeng,limit:5,style:false</script>
其中’swaydeng’替换成你的TwitterId,limit代表你打算显示twitter的条数(小于等于20),style表示嵌入的twitter消息框是否需要加入CSS样式,目前是false。
就是这么简单,欢迎使用。
1px Dotted Border Bug In Chrome3.0
这是一个关于浏览器对CSS属性border的解析问题。在IE6下,当把边框(border-width)设置为1像素并且边框样式(border-style)设置为dotted时,IE6通常会渲染成虚线(dashed)而不是我们想要的点线(dotted),这就是古老的1px Dotted Border Bug In Internet Explorer 6,好消息是在IE6以后的版本里修复了这个bug。
然而最近做测试时发现,以上提到的IE6的bug很不幸地转移到了Chrome上,具体现象是:在Chrome3.0下,当把边框(border-width)设置为1像素并且边框样式(border-style)设置为dotted时,无论长短,线段中部都会有一段实线,只有当border-width大于1px时才正常,很奇怪;补充一点,同样使用WebKit引擎的Safari3.2并不存在这个错误。
本人的测试环境:操作系统是WinXp Pro,屏幕分辨率是1280×800,浏览器是Chrome3.0.195.33。我在想,这难道是Chrome的一个渲染bug?模仿IE,先称此bug为1px Dotted Border Bug In Chrome3。
Notepad++目录插件:Explorer plugin
除了Windows自带的文本编辑器notepad,我还用UltraEdit、Notepad++、Editplus,UltraEdit业界口碑很好,但由于中文用户需要处理较多编码问题,我个人觉得UltraEdit对编码处理并不是很方便;Editplus运行飞快,尤其对一些超大文本的处理比Notepad++强很多,而且其“目录窗口”对于管理复杂结构文件目录很有用,但是在符号配对方面,其仅仅支持括号配对而不支持标签配对,这对于经常编辑XML、HTML文档的人员很不利(当然也有强人不需要);Notepad++是我最喜欢的编辑器,除了其官方介绍的等等优点以外,我个人很喜欢其标签配对功能、灵活的编码选择和硬朗的外观,虽然处理超大文本常常假死,但我可以勉强用以上提到的Editplus替代,唯一让我遗憾的是Notepad++没有类似Editplus和UltraEdit都具备的“目录窗口”。今天,对于我,以上问题不再是问题了,Notepad++是支持插件的,一款插件帮我解决了难题,它就是Explorer plugin,它让我们的Notepad++也拥有“目录窗口”,变得更加完美。
现在Explorer plugin的最新版本是Version1.8.2,下载后解压可得到文件Explorer.dll,将其放在 “Notepad++安装目录/plugins”下,重启Notepad++会发现工具栏多了一个叫Explorer的按钮,点击之,即可看到期待已久的“目录窗口”。
对input 使用focus()函数(兼容Firefox和IE)
我们有时会有这样的需求:当页面加载完成后自动将光标定位到某个输入框上,起到引导和方便用户之功效,如谷歌首页、Gmail登陆界面等;原理较简单,通常可以用一段Javascript略微控制,如
...
window.onload = function(){
document.getElementById('term').focus(); //假设页面中需要赋予焦点的input的id为'term';
}
...
以上代码可以解决input框初始值为空的情况,假如初始值不为空,如我们引导用户输入一个网址,使初始值为’http://’,这时HTML可能是这样:
... ...
如果再试图用上面的Javascript代码来赋予焦点,会发现在Firefox下光标停在input框内文字的末尾,而在IE6下却停在了input框内文字的开头处,通常,Firefox的执行结果使我们所希望的。要想让IE6得到像Firefox一样的结果,以下是我的解决办法:
...
window.onload = function(){
var term = document.getElementById('term');
term.focus();
term.value = term.value; //关键就是多加了这一句;
}
...
跨浏览器Ext版网页漂浮广告JavaScript函数
今天浙大门户系统提出一个需求,用户登录后希望网页上可以漂浮一个小图片,提醒同学可以做在线咨询,我一听,这不就是本人最讨厌的网页广告吗,可没办法,人家给钱,你就是奴才。
在网上一搜,这类脚本铺天盖地,基本是一样的,纯JS写成,拷过来一用,静态页面时IE和Firefox都正常,改成JSP后在IE下还好,Firefox下就不行了,该飘的东西一动不动,改了半天没改出来,想想咱们门户每次加载都带上了Ext库,咱们也别浪费了,我就用Ext写了个跨浏览器的漂浮JavaScript函数,在JSP下通过IE、Firefox及Safari测试,Chrome应该也没问题。函数源码如下:
function floatInfo(id, distance, per){
var flagH = 0;
var flagW = 0;
var distance4L = distance;
var avaiH = document.body.clientHeight - id.getHeight();
var avaiW = document.body.clientWidth - id.getWidth();
var task = {run: function(){
id.setTop(id.getTop() + distance);
flagH += distance;
if(flagH >= avaiH || flagH <= (-avaiH)) {
distance = (-distance);
flagH = 0;
}
id.setLeft(id.getLeft() + distance4L);
flagW += distance4L;
if(flagW >= avaiW || flagW <= (-avaiW)) {
distance4L = (-distance4L);
flagW = 0;
}
},
interval: per
}
Ext.TaskMgr.start(task);
}
传入参数id代表网页上要漂浮元素的id;distance是数字,代表一次移动多少像素;per也是数字,代表多长时间移动一次,其中1000代表1秒,数字越小移动越快。使用方式如下:
<script type="text/javascript">
Ext.onReady(function(){
var id = Ext.get('float_dis');
floatInfo(id,10,300);
})
</script>
虽然用Ext写这种东西是有点杀鸡焉用牛刀的味道,但谁叫本人对跨浏览器的脚本编程这么差呢。