乐趣区

关于javascript:javascript高级程序设计读书笔记六

第 8 章 BOM——浏览器对象模型

  1. window 对象——BOM 的外围

BOM 的外围对象是 window,它示意浏览器的一个实例。
因为 window 对象同时扮演着 ECMAScript 中 Global 对象的角色,因而所有全局作用域中申明的变量、函数都会变成 window 对象的属性和办法。

var age = 29;
function sayAge(){alert(this.age);
}
alert(window.age);     //29
sayAge();              //29
window.sayAge();       //29

抛开全局变量会成为 window 对象的属性不谈,定义全局变量与在 window 对象上间接定义属性还是有一点差异:全局变量不能通过 delete 操作符删除,而间接在 window 对象上定义的属性能够。

窗口地位:

var leftPos = (typeof window.screenLeft == "number") ? window.screenLeft : window.screenX;
var topPos = (typeof window.screenTop == "number") ? window.screenTop : window.screenY;

窗口大小:
跨浏览器确定一个窗口的大小不是一件简略的事。各个浏览器对窗口大小有不同的定义,即便雷同的属性,在各个浏览器中体现的也不同。
尽管最终无奈确定浏览器窗口自身的大小,但却能够获得页面视口的大小。

var pageWidth = window.innerWidth,
    pageHeight = window.innerHeight;
if(typeof pageWidth != "number"){if(document.compatMode == "CSS1Compat"){
        pageWidth = document.documentElement.clientWidth;
        pageHeight = document.documentElement.clientHeight;
    }else{
        pageWidth = document.body.clientWidth;
        pageHeight = document.body.clientHeight;
    }
}

window.open()办法 既能够导航到一个特定的 URL, 也能够关上一个新的浏览器窗口。
这个办法能够接管 4 个参数:要加载的 URL、窗口指标、一个个性字符串以及一个示意新页面是否取代浏览器历史记录中以后加载页面的布尔值。

window.open("http://www.baidu.com/", "topFrame");
// 等同于 <a href="http://www.baidu.com" target="topFrame"></a>

第三个参数是一个都喊宰割的设置字符串,示意在新窗口中都显示那些个性。

window.open("http://www.wrox.com/","wroxWindow","height=400,window=400,top=10,left=10,resizable=yes");
// 这行代码会关上一个新的能够调整大小的窗口,窗口初始大小为 400*400 像素,并且距屏幕上沿和右边各 10 像素。

对于浏览器的主窗口,如果没有失去用户的容许是不能敞开它的,然而弹出窗口也就是通过 window.open()关上的弹出窗口,能够调用 top.close()在不经用户容许的状况下敞开本人。

然而有个问题:大多数浏览器都内置有弹出窗口屏蔽程序。用户能够将绝大多数不想看到的弹出窗口屏蔽掉。
在弹出窗口被屏蔽时,能够思考两种可能性。
如果是浏览器内置的屏蔽程序阻止的弹出窗口,那么 window.open()很可能会返回 null;如果是浏览器扩大或其余程序阻止的弹出窗口,window.open()会抛出谬误。
因而想要精确地检测出弹出窗口是否被屏蔽,必须在检测返回值的同时,将对 window.open()的调用封装在一个 try-catch 块中

var blocked = false;
try{var wroxWin = window.open("http://www.wrox.com","_blank");
    if(wroxWin == null){blocked = true;}
}catch (ex) {blocked = true;}
if(blocked){alert("The popup was blocked!");
}

间歇调用和超时调用
JavaScript 是单线程语言,但它容许通过设置超时值和间隙工夫值来调用代码在特定的时刻执行。
超时调用须要应用 window 对象的 setTimeout()办法,它承受两个参数:要执行的代码和以毫秒示意的工夫—即在执行代码前须要期待多少毫秒。

setTimeout(function(){alert(“Hello world!”);
}, 1000);

第一个参数通常是一个函数,第二个参数是一个示意期待多长时间的毫秒数,但通过该工夫后指定的代码不肯定会执行。
setTimeout()的第二个参数通知 JavaScript 再过多长时间把当前任务增加到队列中,如果队列是空的,那么增加的代码会立刻执行;如果队列不是空的,那么它就要等后面的代码执行完了当前再执行。
要勾销尚未执行的超时调用打算,能够调用 clearTimeout()办法。

// 设置超时调用
var timeoutId = setTimeout(function(){alert(“Hello world!”);
}, 1000);
// 留神:把它勾销
clearTimeout(timeoutId);     // 在设置超时调用之后马上又调用了 clearTimeout(),后果就跟什么也没产生一样。

只有是在指定的工夫尚未过来之前调用 clearTimeout(),就能够齐全勾销超时调用。
间歇调用须要应用 window 对象的 setInterval()办法,它会依照执行的工夫距离反复执行代码,直至间歇调用被勾销或者页面被卸载。

setInterval(function(){alert(“Hello world!”);
}, 10000);

勾销间歇调用的重要性要远远高于勾销超时调用,因为在不加干预的状况下,间歇调用将会始终执行到页面卸载。

var num = 0;
var max = 10;
var intervalId = null;
function incrementNumber(){
 num++;
 // 如果执行次数达到了 max 设定的值,则勾销后续尚未执行的调用
 if(num == max){clearInterval(intervalId);
  alert(“Done”);
 }
}
intervalId = setInterval(incrementNumber, 500);

变量 num 每半秒钟递增一次,当递增到最大值时就会勾销先前设定的间歇调用。
这个模式也能够应用超时调用来实现。

var num = 0;
var max = 10;
function incrementNumber(){
 num++;
 // 如果执行次数达到了 max 设定的值,则设置另一次超时调用
 if(num < max){setTimeout(incrementNumber, 500);
 }else{alert(“Done”);
 }
}
setTimeout(incrementNumber, 500);

零碎对话框
浏览器通过 alert()、confirm()和 prompt()办法能够调用零碎对话框向用户显示音讯。
它们的外观由操作系统及(或)浏览器设置决定,而不是由 CSS 决定。
此外,通过这几句歌办法关上的对话框都是同步和模仿的,也就是说,显示这些对话框的时候代码会进行执行,而关掉这些对话框后代码又会复原执行。

alert(“Hello world!”);
confirm(“Are you sure?”);
prompt(“What’s your name?”,”her”);

2.location 对象
location 是最有用的 BOM 对象之一,它提供了与以后窗口中加载的文档无关的信息,还提供了一些导航性能。

尽管通过下面的属性能够拜访到 location 对象的大多数信息,但其中拜访 URL 蕴含的查问字符串的属性并不不便。为此能够像上面这样创立一个函数来解析查问字符串,返回蕴含所有参数的一个对象:

function getQueryStringArgs(){
 // 获得查问字符串并去掉结尾的问号
 var qs = (location.search.length > 0 ? location.search.substring(1) :“”),
 // 保留数据的对象
 args = {},
 // 获得每一项
 items = qs.length ? qs.split(“&”) : [],
 item = null,
 name = null,
 value = null,
 // 在 for 循环中应用
 i = 0,
 len = items.length;
 // 一一将每一项增加到 args 对象中
 for(i=0;i<len;i++){item = items[i].split("=");
    name = decodeURLComponent(item[0]);
    value = decodeURLComponent(item[1]);
    if(name.length){args[name] = value;
    }
 }
 return args;
}

// 假如查问字符串是?q=javascript&num=10
var args = getQueryStringArgs();
alert(args["q"]);   //"javascript"
alert(args["name"]);  //"10"

在扭转浏览器地位的办法中,最罕用的设置 location.href 属性。

// 假如初始 URL 为 http://www.wrox.com/WileyCDA/

// 跳转到 http://www.wrox.com
location.href = "http://www.wrox.com";

// 将 URL 批改为 "http://www.wrox.com/WileyCDA/#section1"
location.hash = "#section1";

// 将 URL 批改为 "http://www.wrox.com/WileyCDA/?q=javascript"
location.search = "?q=javascript";

// 将 URL 批改为 "http://www.yahoo.com/WileyCDA/"
location.hostname = "http://www.yahoo.com";

// 将 URL 批改为 "http://www.yahoo.com/mydir/"
location.pathname = "mydir";

// 将 URL 批改为 "http://www.yahoo.com:8080/WileyCDA/"
location.port = "8080";

每次批改 location 的属性 (hash 除外),页面都会以新 URL 从新加载。
上述任何一种形式批改 URL 之后,浏览器的历史记录中就会生成一条新纪录,因而用户通过单击 ” 后退 ” 按钮都会导航到前一个页面。
要禁用这种行为,能够通过 replace() 办法 ,不会再历史记录中生成新纪录。
reload() 办法,作用是从新加载以后显示的页面。
如果要强制从服务器从新加载,则须要像上面这样子为该办法传递参数 true。

location.reload();    // 从新加载(有可能从缓存中加载)location.reload(true);   // 从新加载(从服务器从新加载)

位于 reload()调用之后的代码可能会也可能不会执行,这要取决于网络提早或系统资源等因素。为此最好将 reload()放在代码最初一行。

3.history 对象
history 对象保留着用户上网的历史记录,从窗口被关上的那一刻算起。
出于平安方面的思考,开发人员无奈得悉用户浏览过的 URL。
应用 go()办法能够在用户的历史记录中任意跳转,能够向后也能够向前。

history.go(-1);// 后退一页
history.go(1);// 后退一页
history.go(2);// 后退两页
history.go("wrox.com");// 跳转到最近的 wrox.com 页面
history.back();// 后退一页
history.forward();// 后退一页

也能够给 go()办法传递一个字符串参数,会跳转到历史记录中蕴含该字符串的第一个地位,可能后退可能后退,看哪个地位最近,如果历史记录中不蕴含该字符串,则什么都不做。
确定用户是否一开始就关上了你的页面

if(history.length == 0){// 这应该是用户关上窗口后的第一个页面}

小结
浏览器对象 (BOM) 以 window 对象为依靠,示意浏览器窗口以及页面可见区域。
在应用框架时,每个框架都有本人的 window 对象以及所有构造函数及其他函数的正本,每个框架都保留在 frames 汇合中,能够通过地位或通过名称来拜访。
top 对象始终指向最外围的框架,也就是整个浏览器窗口。
parent 对象示意蕴含以后框架的框架,而 self 对象则回指 window。
应用 location 对象能够通过编程形式来拜访浏览器的导航系统。实质性相应的属性,能够逐段或整体性地批改浏览器的 URL。
调用 replace()办法能够导航到一个新 URL,同时该 URL 会替换浏览器历史记录中以后显示的页面。
navigator 对象提供了与浏览器无关的信息。

明天就先到这儿咯,明天上班晚,就先啃到这儿啦

退出移动版