下是一個簡單的C語言實現(xiàn)Windows消息窗口的示例代碼:
```c
#include <windows.h>
#include <stdio.h>
// 定義消息處理函數(shù)
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CLOSE:
printf("Close button clicked.\n");
break;
case WM_DESTROY:
// 窗口銷毀消息
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
// 注冊窗口類
WNDCLASS wc = {0};
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszClassName = "MyWindowClass";
RegisterClass(&wc);
// 創(chuàng)建窗口
HWND hwnd = CreateWindow("MyWindowClass", "My Window",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300,
NULL, NULL, hInstance, NULL);
// 顯示窗口
ShowWindow(hwnd, nCmdShow);
// 進入消息循環(huán)
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
```
以上代碼創(chuàng)建了一個名為“My Window”的窗口,并在窗口中處理了關閉按鈕的單擊事件。在窗口銷毀時,窗口也會被銷毀。
請注意,這只是一個簡單的示例代碼,您可以根據(jù)自己的需求進行修改和完善。
、引入js
<script type="text/javascript" src="js/jquery-2.0.0.min.js"></script>
2、html代碼
<script type="text/javascript">
$(function(){
var Fireworks = function(){
var self = this;
var rand = function(rMi, rMa){return ~~((Math.random()*(rMa-rMi+1))+rMi);}
var hitTest = function(x1, y1, w1, h1, x2, y2, w2, h2){return !(x1 + w1 < x2 || x2 + w2 < x1 || y1 + h1 < y2 || y2 + h2 < y1);};
window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){window.setTimeout(a,1E3/60)}}();
self.init = function(){
self.canvas = document.createElement('canvas');
self.canvas.width = self.cw = $(window).innerWidth();
self.canvas.height = self.ch = $(window).innerHeight();
self.particles = [];
self.partCount = 150;
self.fireworks = [];
self.mx = self.cw/2;
self.my = self.ch/2;
self.currentHue = 30;
self.partSpeed = 5;
self.partSpeedVariance = 10;
self.partWind = 50;
self.partFriction = 5;
self.partGravity = 1;
self.hueMin = 0;
self.hueMax = 360;
self.fworkSpeed = 4;
self.fworkAccel = 10;
self.hueVariance = 30;
self.flickerDensity = 25;
self.showShockwave = true;
self.showTarget = false;
self.clearAlpha = 25;
$(document.body).append(self.canvas);
self.ctx = self.canvas.getContext('2d');
self.ctx.lineCap = 'round';
self.ctx.lineJoin = 'round';
self.lineWidth = 1;
self.bindEvents();
self.canvasLoop();
self.canvas.onselectstart = function() {
return false;
};
};
self.createParticles = function(x,y, hue){
var countdown = self.partCount;
while(countdown--){
var newParticle = {
x: x,
y: y,
coordLast: [
{x: x, y: y},
{x: x, y: y},
{x: x, y: y}
],
angle: rand(0, 360),
speed: rand(((self.partSpeed - self.partSpeedVariance) <= 0) ? 1 : self.partSpeed - self.partSpeedVariance, (self.partSpeed + self.partSpeedVariance)),
friction: 1 - self.partFriction/100,
gravity: self.partGravity/2,
hue: rand(hue-self.hueVariance, hue+self.hueVariance),
brightness: rand(50, 80),
alpha: rand(40,100)/100,
decay: rand(10, 50)/1000,
wind: (rand(0, self.partWind) - (self.partWind/2))/25,
lineWidth: self.lineWidth
};
self.particles.push(newParticle);
}
};
self.updateParticles = function(){
var i = self.particles.length;
while(i--){
var p = self.particles[i];
var radians = p.angle * Math.PI / 180;
var vx = Math.cos(radians) * p.speed;
var vy = Math.sin(radians) * p.speed;
p.speed *= p.friction;
p.coordLast[2].x = p.coordLast[1].x;
p.coordLast[2].y = p.coordLast[1].y;
p.coordLast[1].x = p.coordLast[0].x;
p.coordLast[1].y = p.coordLast[0].y;
p.coordLast[0].x = p.x;
p.coordLast[0].y = p.y;
p.x += vx;
p.y += vy;
p.y += p.gravity;
p.angle += p.wind;
p.alpha -= p.decay;
if(!hitTest(0,0,self.cw,self.ch,p.x-p.radius, p.y-p.radius, p.radius*2, p.radius*2) || p.alpha < .05){
self.particles.splice(i, 1);
}
};
};
self.drawParticles = function(){
var i = self.particles.length;
while(i--){
var p = self.particles[i];
var coordRand = (rand(1,3)-1);
self.ctx.beginPath();
self.ctx.moveTo(Math.round(p.coordLast[coordRand].x), Math.round(p.coordLast[coordRand].y));
self.ctx.lineTo(Math.round(p.x), Math.round(p.y));
self.ctx.closePath();
self.ctx.strokeStyle = 'hsla('+p.hue+', 100%, '+p.brightness+'%, '+p.alpha+')';
self.ctx.stroke();
if(self.flickerDensity > 0){
var inverseDensity = 50 - self.flickerDensity;
if(rand(0, inverseDensity) === inverseDensity){
self.ctx.beginPath();
self.ctx.arc(Math.round(p.x), Math.round(p.y), rand(p.lineWidth,p.lineWidth+3)/2, 0, Math.PI*2, false)
self.ctx.closePath();
var randAlpha = rand(50,100)/100;
self.ctx.fillStyle = 'hsla('+p.hue+', 100%, '+p.brightness+'%, '+randAlpha+')';
self.ctx.fill();
}
}
};
};
self.createFireworks = function(startX, startY, targetX, targetY){
var newFirework = {
x: startX,
y: startY,
startX: startX,
startY: startY,
hitX: false,
hitY: false,
coordLast: [
{x: startX, y: startY},
{x: startX, y: startY},
{x: startX, y: startY}
],
targetX: targetX,
targetY: targetY,
speed: self.fworkSpeed,
angle: Math.atan2(targetY - startY, targetX - startX),
shockwaveAngle: Math.atan2(targetY - startY, targetX - startX)+(90*(Math.PI/180)),
acceleration: self.fworkAccel/100,
hue: self.currentHue,
brightness: rand(50, 80),
alpha: rand(50,100)/100,
lineWidth: self.lineWidth
};
self.fireworks.push(newFirework);
};
self.updateFireworks = function(){
var i = self.fireworks.length;
while(i--){
var f = self.fireworks[i];
self.ctx.lineWidth = f.lineWidth;
vx = Math.cos(f.angle) * f.speed,
vy = Math.sin(f.angle) * f.speed;
f.speed *= 1 + f.acceleration;
f.coordLast[2].x = f.coordLast[1].x;
f.coordLast[2].y = f.coordLast[1].y;
f.coordLast[1].x = f.coordLast[0].x;
f.coordLast[1].y = f.coordLast[0].y;
f.coordLast[0].x = f.x;
f.coordLast[0].y = f.y;
if(f.startX >= f.targetX){
if(f.x + vx <= f.targetX){
f.x = f.targetX;
f.hitX = true;
} else {
f.x += vx;
}
} else {
if(f.x + vx >= f.targetX){
f.x = f.targetX;
f.hitX = true;
} else {
f.x += vx;
}
}
if(f.startY >= f.targetY){
if(f.y + vy <= f.targetY){
f.y = f.targetY;
f.hitY = true;
} else {
f.y += vy;
}
} else {
if(f.y + vy >= f.targetY){
f.y = f.targetY;
f.hitY = true;
} else {
f.y += vy;
}
}
if(f.hitX && f.hitY){
self.createParticles(f.targetX, f.targetY, f.hue);
self.fireworks.splice(i, 1);
}
};
};
self.drawFireworks = function(){
var i = self.fireworks.length;
self.ctx.globalCompositeOperation = 'lighter';
while(i--){
var f = self.fireworks[i];
self.ctx.lineWidth = f.lineWidth;
var coordRand = (rand(1,3)-1);
self.ctx.beginPath();
self.ctx.moveTo(Math.round(f.coordLast[coordRand].x), Math.round(f.coordLast[coordRand].y));
self.ctx.lineTo(Math.round(f.x), Math.round(f.y));
self.ctx.closePath();
self.ctx.strokeStyle = 'hsla('+f.hue+', 100%, '+f.brightness+'%, '+f.alpha+')';
self.ctx.stroke();
if(self.showTarget){
self.ctx.save();
self.ctx.beginPath();
self.ctx.arc(Math.round(f.targetX), Math.round(f.targetY), rand(1,8), 0, Math.PI*2, false)
self.ctx.closePath();
self.ctx.lineWidth = 1;
self.ctx.stroke();
self.ctx.restore();
}
if(self.showShockwave){
self.ctx.save();
self.ctx.translate(Math.round(f.x), Math.round(f.y));
self.ctx.rotate(f.shockwaveAngle);
self.ctx.beginPath();
self.ctx.arc(0, 0, 1*(f.speed/5), 0, Math.PI, true);
self.ctx.strokeStyle = 'hsla('+f.hue+', 100%, '+f.brightness+'%, '+rand(25, 60)/100+')';
self.ctx.lineWidth = f.lineWidth;
self.ctx.stroke();
self.ctx.restore();
}
};
};
self.bindEvents = function(){
$(window).on('resize', function(){
clearTimeout(self.timeout);
self.timeout = setTimeout(function() {
self.canvas.width = self.cw = $(window).innerWidth();
self.canvas.height = self.ch = $(window).innerHeight();
self.ctx.lineCap = 'round';
self.ctx.lineJoin = 'round';
}, 100);
});
$(self.canvas).on('mousedown', function(e){
self.mx = e.pageX - self.canvas.offsetLeft;
self.my = e.pageY - self.canvas.offsetTop;
self.currentHue = rand(self.hueMin, self.hueMax);
self.createFireworks(self.cw/2, self.ch, self.mx, self.my);
$(self.canvas).on('mousemove.fireworks', function(e){
self.mx = e.pageX - self.canvas.offsetLeft;
self.my = e.pageY - self.canvas.offsetTop;
self.currentHue = rand(self.hueMin, self.hueMax);
self.createFireworks(self.cw/2, self.ch, self.mx, self.my);
});
});
$(self.canvas).on('mouseup', function(e){
$(self.canvas).off('mousemove.fireworks');
});
}
self.clear = function(){
self.particles = [];
self.fireworks = [];
self.ctx.clearRect(0, 0, self.cw, self.ch);
};
self.canvasLoop = function(){
requestAnimFrame(self.canvasLoop, self.canvas);
self.ctx.globalCompositeOperation = 'destination-out';
self.ctx.fillStyle = 'rgba(0,0,0,'+self.clearAlpha/100+')';
self.ctx.fillRect(0,0,self.cw,self.ch);
self.updateFireworks();
self.updateParticles();
self.drawFireworks();
self.drawParticles();
};
self.init();
}
var fworks = new Fireworks();
});
</script>
3、展示效果
內(nèi)容是《Web前端開發(fā)之Javascript視頻》的課件,請配合大師哥《Javascript》視頻課程學習。
多窗口和窗體:
可以打開多個瀏覽器窗口,每個窗口都是獨立的;
一個瀏覽器窗口可能包含多個標簽頁;每個標簽頁都是獨立的上下文,都是獨立的window對象,而且相互之間互不干擾;
但是窗口也并不總是和其他窗口完全沒有關系;一個窗口或標簽頁中的腳本可以打開新的窗口或標簽頁,如此,這些多窗口或標簽頁就可以互相操作;
打開窗口:
window.open()方法,打開一個新的瀏覽器窗口、標簽頁,導航到一個指定的URL;
語法:window.open(url,name,features,replace);url為打開新窗口的url,name為窗口目標,features設置窗口特性參數(shù)列表,replace為Boolean值,指定是否用新窗口替換當前頁面;
一般使用第一個參數(shù),如果也省略該參數(shù)或使用空字符串,則會打開一個空頁面的URL about:blank;
如果使用第二個參數(shù),而且該參數(shù)是已有窗口或框架的名稱,就會在該窗口或框架中加載指定的URL;否則彈出新窗口,并將新窗口的name命名為該參數(shù),如果省略此參數(shù),則會使用指定的“_blank”打開一個新的、未命名的窗口;
第二個參數(shù)也可以是:_self、_parent、_top、_blank;
窗口的名字也可作為<a>和<form>元素上target屬性的值,用來表示引用的文檔或提交處理的頁面;
<script>
window.open("https://www.zeronetwork.cn/","myWindow");
</script>
<a href="https://www.google.cn/" target="myWindow">baidu.com</a>
窗口特性屬性:
第三個參數(shù)是一個逗號分隔的設置字符串,表示在新窗口中都顯示哪些特性;如果省略,則以默認的形式呈現(xiàn);
字符串格式為:設置使用鍵值對,且全部使用逗號分隔,而且不能有空格;
window.open("https://www.zeronetwork.cn/","myWindow",
"width=400,height=400,top=50,left=50,resizable=yes");
顯式指定這些特性,打開的應該是新窗口,而不是新標簽頁;這個參數(shù)是非標準的,而且HTML5也主張瀏覽器應該忽略它;
另外,出于安全考慮,瀏覽器包含對可能指定的功能的限制,如,通常不允許指定一個太小的或者位于屏幕之外的窗口,并且一些瀏覽器不允許創(chuàng)建一個沒有狀態(tài)欄的窗口;
第四個參數(shù)只有在設置了第二個參數(shù)命名的是一個已存在的窗口時才有用;它是一個布爾值,聲明了由第一個參數(shù)指定的URL是替換掉窗口瀏覽歷史的當前記錄(true)還是應該在窗口瀏覽歷史中創(chuàng)建一個新的記錄(false),默認為false;
window.open()會返回一個window對象,用于操作新創(chuàng)建的窗口;該引用可以操作新窗口的內(nèi)容,從而就可以在一個窗口中控制另一個窗口的內(nèi)容,例如向一個新開的瀏覽器窗口中輸出內(nèi)容;
var w = window.open(); // 打開一個新的空白窗口
w.document.write("<h2>零點網(wǎng)絡</h2>");
w.alert("詳情請進入https://www.zeronetwork.cn/");
w.location = "https://www.zeronetwork.cn/";
某些瀏覽器在默認情況下可能不允許針對主瀏覽器窗口調整大小或移動,但不允許針對通過open()創(chuàng)建的窗口調整大小或移動,如:
var newWindow = window.open("https://www.zeronetwork.cn/","myWindow",
"width=400,height=400,top=50,left=50,resizable=yes");
newWindow.resizeTo(600,600);
newWindow.moveTo(200,200);
注:有些瀏覽器默認不允許這樣操作;
窗口opener屬性:
opener屬性是新窗口對打開它的原始窗口的引用;即指向調用window.open()的窗口或框架;但只在彈出窗口的最外層window對象(top)中有定義;
var newWindow = window.open("https://www.zeronetwork.cn/","myWindow",
"width=400,height=400,top=50,left=50,resizable=yes");
console.log(newWindow.opener === window); // true
<!-- 主窗口 -->
<input type="text" id="selectCity" placeholder="選擇" />
<script>
var selectCity = document.getElementById("selectCity");
selectCity.onclick = function(){
var newWin = window.open("select.html","newWin","width=400,height=400");
}
</script>
<!-- 新窗口 -->
<select id="city">
<option value="beijing">北京</option>
<option value="nanjing">南京</option>
<option value="anhui">安徽</option>
</select>
<script>
var city = document.getElementById("city");
city.onchange = function(){
window.opener.document.getElementById("selectCity").value = city.options[city.selectedIndex].value;
window.close();
}
</script>
有些瀏覽器(如IE8和Chrome)會在獨立的進程中運行每個標簽頁,當一個標簽頁打開另一個標簽頁時,如果兩個window對象之間需要彼此通信,那么新標簽頁就不能運行在獨立的進程中。在Chrome中,將新創(chuàng)建的標簽頁的opener屬性設置為null,即表示在單獨的進程中運行新標簽頁。
newWindow.opener = null;
標簽頁之間的聯(lián)系一旦切斷,將沒有辦法恢復。
window.close()關閉窗口:
對于主窗口,如果沒有得到用戶的允許是不能關閉它的;但彈出窗口可以不經(jīng)用戶允許可以關閉自己;
窗口關閉后,窗口的引用仍然存在,可以使用window.closed屬性檢測,但在實際場景中沒有多大用處;
function openWin(){
var newWindow = window.open("https://www.zeronetwork.cn/","myWindow",
"width=400,height=400,top=50,left=50,resizable=yes");
newWindow.document.write("<h2>零點網(wǎng)絡</h2>");
function closeWin(){
newWindow.close();
//alert(newWindow.closed);
if(newWindow.close)
alert("已關閉");
}
setTimeout(closeWin,3000);
}
openWin();
注:document對象也有close()方法,為了避免混淆,所以調用close()方法時,要顯式調用,即使用window.close();
安全限制:
大多數(shù)瀏覽器針對彈出窗口實施了多方面的安全限制,如:不允許在屏幕之外創(chuàng)建彈出窗口,不允許將彈出窗口移動到屏幕之外,不允許關閉狀態(tài)欄等;不允許關閉地址欄,默認情況下不允許移動彈出窗口或調整其大小;或者部分瀏覽器不支持修改狀態(tài)欄,始終顯示地址欄等;
通常,對于open()方法只有當用戶手動單擊按鈕或超鏈接時才會調用;如果嘗試在瀏覽器初始載入時開啟一個彈出窗口時,通常會被屏蔽;
彈出窗口屏蔽程序:
大多數(shù)瀏覽器都內(nèi)置有彈出窗口屏蔽程序,如果沒有內(nèi)置,可以安裝第三方實用工具;內(nèi)置屏蔽會使window.open可能返回null,第三方會返回錯誤;通過需要檢測其返回值;
// 內(nèi)置的屏蔽程序
var newWin = window.open("https://www.zeronetwork.cn/","_blank");
if(newWin == null){
alert("彈窗被阻止!");
}
// 第三方
var blocked = false;
try{
var newWin = window.open("https://www.zeronetwork.cn/","_blank");
if(newWin == null)
blocked = true;
}catch(e){
blocked = true;
}
if(blocked){
alert("彈窗被屏蔽");
}
彈出窗口通信:
主窗口向新窗口傳值,直接為新窗口window對象添加成員,如:
// 主窗口
var newWin = window.open("select.html","_blank");
var person = {
name:"wangwei",
sex: true,
age: 18
}
newWin.person = person;
// 新窗口
document.write("姓名:",person.name);
document.write("性別:",person.sex);
document.write("年齡:",person.age);
新窗口向主窗口傳值,通過window.opener獲取原始窗口的屬性或者html元素;
<!-- 主窗口 -->
<div id="mydiv"></div>
<script>
var newWin = window.open("select.html","_blank");
function showDiv(str){
var mydiv = document.getElementById("mydiv");
mydiv.innerHTML = str;
}
</script>
<script>
// 新窗口
var str = "零點網(wǎng)絡";
window.opener.showDiv(str);
window.close();
</script>
通過普通的get傳值;
// 主窗口
function putId(id){
window.open("select.html?id=" + encodeURIComponent(id),"putWin");
}
putId("1002");
// 新窗口
var id = location.search;
id = id.split("=");
console.log(id[1]);
document.write(decodeURIComponent(id[1]));
框架窗口:
如果頁面使用了框架集合(包含frameset和iframe),則每個框架都由它自己的window對象表示,并存放在frames集合中;
與相互獨立的標簽頁或窗口不同,框架窗口之間并不是相互獨立的;
每個window對象都有一個name屬性,其中包含框架的名稱;
<frameset rows="100,*">
<frame src="top.html" name="topFrame" />
<frameset cols="50%,50%">
<frame src="left.html" name="leftFrame" />
<frame src="right.html" name="rightFrame" />
</frameset>
</frameset>
在frames集合中,可用數(shù)字(下標從0開始,從左到右,從上到下)訪問;即可以使用frames[0]表示第1個子窗口、frames[1]表示第2個子窗口;
可使用名稱對框架進行訪問,該名稱就是該框架的name屬性,如 window.frames[“topFrame”]引用;
也可以window.topFrame 使用架框的名字訪問;
window.onload = function(){
console.log(frames);
var topFrame = frames[0];
console.log(topFrame);
console.log(topFrame.name);
var leftFrame = window.frames["leftFrame"];
console.log(leftFrame.name);
console.log(window.rightFrame.name);
}
可使用frames.length 取得框架集合長度;
如果是內(nèi)聯(lián)框架,那就更簡單了,如:
<iframe src="right.html" name="myFrame" width="200" height="200"></iframe>
<script>
console.log(frames);
console.log(frames[0].name);
</script>
對于頂級窗口的window對象來說,可以看作為由若干個子窗口組成的窗口數(shù)組,也就是說可以把window對象當作為窗口的集合,如:
console.log(window.length);
console.log(window[0]);
但在實際場景中,最好還是使用frames來代替window,因為frames顯得更清晰些;
對于<iframe>元素,如果設置了id,也可以通過document.getElementById()方法獲取,如:
var myframe = document.getElementById("myframe");
console.log(myframe);
myframe.src = "one.html";
<iframe>元素有contentWindow屬性,引用該窗體的window對象,所以此窗體的window對象就是:
var mywin = document.getElementById("myframe").contentWindow;
console.log(mywin);
mywin.document.write("是內(nèi)聯(lián)框架window對象");
可以進行反向操作,通過window對象的frameElement屬性,來獲取該窗體的<iframe>元素;表示頂級窗口的window對象的frameElement屬性為null,窗體中的window對象的frameElement屬性不是null;
var myframe = document.getElementById("myframe");
var mywin = myframe.contentWindow;
console.log(mywin.frameElement);
console.log(mywin.frameElement === myframe);
console.log(window.frameElement);
// 在one.html會返回<iframe id="myframe" src="one.html"></iframe>
console.log(window.frameElement);
盡管可以通過document.getElementById()和contentWindow屬性來獲取窗口中的子窗體的引用,但在實際場景中,用的還是比較少,主要還是使用frames屬性來訪問;
top對象:
可以使用top引用最頂層(外層)框架,就是瀏覽器窗口;使用它可以確保在一個框架中正確的訪問另一個框架;
// 框架集頁面
window.onload = function(){
console.log(frames);
console.log(top);
console.log(top === frames); // true
console.log(top === window); // true
console.log(frames === window); // true
}
// 框架頁面
console.log("topFrame:",frames);
console.log("topFrame:",top);
console.log("topFrame:",top === frames); // false
因此,使用top訪問框架時,也可以如下:
console.log(top[0].name);
console.log(top["topFrame"].name);
console.log(top.topFrame.name);
console.log(top.frames[0].name);
console.log(top.frames["topFrame"].name);
console.log(top.frames === frames); // true
parent對象:
與top相對的另一個window對象是parent,其指的當前框架的直接上層框架,即父框架;
parent在不同的位置指不同的對象;在某些情況下,parent有可能等于top,但在沒有框架的情況下,parent一定等于top(此時,它們都等于window),如:
<!-- frameset.html -->
<frameset rows="100,*">
<frame src="top.html" name="topFrame" />
<frameset cols="50%,50%">
<frame src="left.html" name="leftFrame" />
<frame src="right.html" name="rightFrame" />
</frameset>
</frameset>
<!-- right.html -->
<frameset cols="50%,50%">
<frame src="one.html" name="oneFrame" />
<frame src="two.html" name="twoFrame" />
</frameset>
// one.html中的代碼
var parentFrame = window.parent;
console.log("從one.html中訪問:",parentFrame.name); // rightFrame
parentFrame.frames[1].document.write("<h2>框架訪問</h2>");
// top.html中的代碼
var parentFrame = window.parent;
console.log("top:", parentFrame.name);
console.log("top:", parentFrame.length);
console.log("top:", parentFrame.frames.length);
console.log("top:", parentFrame === top); // true
console.log("top:", parentFrame.frames[1].name);
parentFrame.frames[1].document.write("<h2>是left頁面嗎?</h2>");
注:除非最頂層的窗口是通過window.open()打開的,否則其window對象的name屬性不會包含任何值;
self對象:
指向當前window自身,即self和window可以互換使用;
引入self的目的只是為了與top和parent對象對應起來;
對于頂級窗口,parent == self; // true
注:所有的這些對象都是window對象的屬性,可以通過window.parent、window.top等形式訪問;同時,這也意味著可以將不同層次的window對象連接起來,如:window.parent.parent.frames[0];
窗口交互:
對于一個復雜的框架,窗口之間可以相互訪問,它主要包括對框架自身的引用、父窗口對子窗口的引用、子窗口對父窗口及其他窗口的引用、對頂級窗口的引用;
在使用框架的情況下,瀏覽器中會存在多個Global對象,即每個窗口都會有自己的執(zhí)行上下文,在每個框架中定義的全局變量會自動成為框架中window對象的屬性;
<!-- right.html -->
<div id="myDiv"></div>
<div id="imgDiv"></div>
<script>
function showImg(){
var imgDiv = document.getElementById("imgDiv");
var img = document.createElement("img");
img.src = "images/1.jpg";
imgDiv.appendChild(img);
}
</script>
// 框架集頁面
window.onload = showDiv;
function showDiv(){
var rightFrame = parent[2];
var myDiv = rightFrame.document.getElementById("myDiv");
myDiv.innerHTML = "<h2>零點網(wǎng)絡</h2>";
}
<!-- top.html -->
<h2>Top頁面</h2>
<div><button id="showBtn">顯示圖片</button>
<button id="closeBtn">關閉圖片</button></div>
<script>
window.onload = function(){
var showBtn = document.getElementById("showBtn");
var closeBtn = document.getElementById("closeBtn");
var rightFrame = top[2];
showBtn.onclick = rightFrame.showImg;
closeBtn.onclick = closeImg;
}
function closeImg(){
var rightFrame = top.rightFrame;
var imgDiv = rightFrame.document.getElementById("imgDiv");
imgDiv.innerHTML = "";
}
</script>
對于構造函數(shù),它也是函數(shù),所以當用構造函數(shù)和相關的原型對象定義一個自定義類時,這個類只在一個單獨的窗口中定義;子窗口也可以引用這個類;
對于內(nèi)置類來說,和自定義類就有所不同了;內(nèi)置的類都會在所有的窗口中自動預定義,即每個窗口的window對象都包含原生類型的構造函數(shù),因此每個框架一套自己的構造函數(shù),這些構造函數(shù)一一對應,但并不相等;如:top.Object并不等于top.frames[0].Object,這個問題會影響到對跨框架傳遞的對象使用instanceof操作符;
WindowProxy對象:
window對象是客戶端Javascript的全局變量;但是從技術上來看,并不是這樣的;Web瀏覽器每次向窗口或窗體中載入新的內(nèi)容,它都會開始一個新的JavaScript執(zhí)行上下文,包含一個新創(chuàng)建的全局對象;但是當多個窗口或窗體在使用時,有一個重要的概念,盡管窗體或窗口載入了新的文檔,但是引用窗體或窗口的window對象還仍然是一個有效的引用;
所以客戶端Javascript有兩個重要的對象;客戶端全局對象處于作用域鏈的頂級,并且是全局變量和函數(shù)所定義的地方;事實上,全局對象會在窗口或窗體載入新內(nèi)容時被替換;
而我們稱之為“window對象”的對象實際上不是全局對象,而是全局對象的一個代理;每次查詢或設置window對象的屬性時,就會在窗口或窗體的當前全局對象上查詢或設置相同的屬性;
HTML5規(guī)范稱這個代理對象為WindowProxy;由于它的代理行為,除了有更長的生命周期之外,代理對象表現(xiàn)得像真正的全局對象;如果可以比較兩個對象,那么區(qū)分它們會很困難;但是事實上,沒有辦法可以引用到真正的客戶端全局對象;全局對象處于作用域鏈的頂端,但是window、self、top、parent以及窗體的屬性全部返回代理對象;window.open()也返回代理對象;甚至頂級函數(shù)里this的值也是代理對象,而不是真正的全局對象;
Web前端開發(fā)之Javascript-零點程序員-王唯
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。