学习window.open()及问题分析
以前对window.open()理解的不透彻,最近因为产品需要,重新学习了一下,以下为一些收获和问题总结:
调用方式:window.open(url , winName , style);
url:弹出窗口的路径【必选】
winName:弹出窗口的名字【可选】
style:弹出窗口的样式(类型为字符串,结构如“attr1=xxx1,attr2=xxx2”,不能有空格,关于这个参数的可选值网上很多,在此不做赘述。需要注意的是其中很多属性在浏览器中表现差异较大,建议对窗口样式要求不高时选择window.open)【可选】
通过代码创建一个简单的窗口:
window.open("Content.html",'windowopen',"width=400px,height=400,left=500,top=100")
可以看到同样的样式在不同浏览器中的表现是不同的,以下是测试中考虑到的一些条件及实际测试结果(T为支持,空为不支持):
关于浏览器阻止弹出新窗口
不同浏览器对js控制自动弹出的window会进行拦截,但如果是用户主动触发标签发生的事件则不会阻止,所以如果是正当作用的弹框,大可以放心的通过用户行为触发事件。
关于弹窗数量
function openWin() {
return window.open("Content.html","windowopen","width=400px,height=400,left=500,top=100"); } $(".btn1").click(function() { subPage = openWin(); });
以上代码表示,点击按钮btn1,弹出一个名为windowopen的窗口
1)同名的窗口会在同一个弹窗中弹出,所以以上代码中的btn1不管点击多少次(已弹出的窗口不关闭),都不会再弹出第二个弹窗,只是刷新弹窗中的页面
2)如果想每次点击都弹出新的弹窗(已弹出的窗口不关闭),可以在winName上加一个随机数,保证每次弹出的弹窗名不同(需要注意的是winName不可过长,否则IE8/9会报错)
3)也可以实现点击一次,弹出多个弹窗,前提是几个弹窗的winName不同,否则只会弹出一个弹窗,代码如下:
function openWin() { window.open("Content.html","windowopen1","width=400px,height=400,left=500,top=100"); window.open("Content.html","windowopen2","width=400px,height=400,left=500,top=100"); } $(".btn1").click(function() { openWin(); });
关于父子页面间访问
子页面(Content.html)->父页面(OpenWin.html):
子父页面分别属于两个窗体,【子页面】中可以通过window或self访问自身元素,可以通过window.opener访问打开子窗口的父窗口中的元素。
在子窗体控制台打印window.opener,返回的是父窗口的window对象
父页面(OpenWin.html)->子页面(Content.html):
【父页面】中可以通过window访问自身元素,可以通过window.open()方法的返回值,访问子页面中的元素(需要注意的是,要想获取子窗口的window对象,子窗口必须处于弹出状态,否则获取的返回值为undefined),代码如下:
var subPage = null;//子窗口返回值
function openWin() { return window.open("Content.html", 'windowopen', "width=400px,height=400,left=500,top=100"); }
//打开子窗口
$(".btn1").click(function() { subPage = openWin();
});
//获取子窗口 $(".btn1_get").click(function() { if (subPage) { console.log(subPage); }
});
可以看到控制台输出的结果就是子窗口的window对象。
=========在此插播测试父子页面间访问是出现的一个问题============
条件:父子页面引入jQuery文件,并在父页面的某个标签上通过$jq.data("key1","val1")存入数据,希望从子页面访问该标签上的数据
子页面代码:
但实际输出结果为空对象,为毛?
受高人指点过后,发现自己犯了一个错误,jQuery被引入后,会将自己的命名空间挂在window对象中,jQuery提供的所有方法都在其命名空间下,而$jq.data("key1","val1")的数据实际并不是存储在调用它的$jq上,而是存储在window.jQuery.cache对象中:
而父页面和子页面分别从属于其各自的两个window对象,也就是说,我在父页面中使用$jq.data("key1","val1")存储的数据,只存在于父窗体的jQuery.cache中,而如下代码实际上使用的是当前window(子窗体)中的jQuery,而子窗体中的jQuery中并没有存储父窗体中的信息。
正确的写法为:
============完毕============
关于beforeunload事件
beforeunload:可以用在BODY, FRAMESET, window元素上,顾名思义,表示在页面卸载前执行,具体执行时机如下:
·关闭浏览器窗口
·通过地址栏或收藏夹前往其他页面的时候
·点击返回,前进,刷新,主页其中一个的时候
·点击 一个前往其他页面的url连接的时候
·调用以下任意一个事件的时候:click,document write,document
open,document close,window close ,window navigate ,window
NavigateAndFind,location replace,location reload,form submit.
·当用window open打开一个页面,并把本页的window的名字传给要打开的页面的时候。
·重新赋予location.href的值的时候。
·通过input type=”submit”按钮提交一个具有指定action的表单的时候。
可以通过DOM0级事件绑定为该事件绑定一个函数:
window.onbeforeunload = function (e) { return "呵呵不让你关"; }
该事件可以返回一个字符串,作为卸载页面前提示用户确认卸载的提示语(该返回值在火狐无效,被直接无视)
后面又测试了使用DOM2级事件绑定为该事件绑定一个函数:
实际测试发现,只有IE和safari支持该绑定方式,此外,为window绑定多个beforeunload事件,仅第一次绑定的函数被执行了,故建议在对beforeunload事件进行绑定时,使用DOM0级绑定。