javascript 知识点整理 06 BOM

这部分内容的整理都来自于《js高级程序设计》

BOM

window对象(全局作用域,框架,大小,位置,新打开窗口,弹出框,延时调用与超时调用)

location对象(属性,位置方法,截取方法)

navigator对象

screen对象

history对象(历史记录,跳转方法)

window

全局作用域

  • window对象既是浏览器提供的一个接口,也是ECMAScript规定的Global对象,所以在全局环境下声明的变量和函数都是window对象的属性和方法

    1
    2
    name = "lwy";
    console.log(name == window.name); //true
  • 直接在全局环境下声明的变量不能被delete删除,而为window对象添加的属性可以被delete删除

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var foo = "foo";
    window.bar = "bar";
    console.log(delete foo);//false
    console.log(delete bar);//true
    console.log(delete window.foo);//false
    console.log(delete window.bar);//true
    //ie9以下使用delete删除属性会抛出错误
  • 使用var关键字声明的window属性,其[[configurable]]会被设置为false,所以无法对它进行删除。直接声明的话则不会


窗口关系及框架

  • window 每个框架都有自己的window对象

    • 页面中包含多个框架时,每一个window对象都将拥有一套自己的构造函数,互相并不对等

      1
      window.Object == window.frames[0].Object; //false
  • frames 每个框架都保存在window的frames数组中

  • name 每个框架的window对象都有一个name属性,指向框架的名称

  • top 指向最外层的顶层框架,也就是浏览器窗口

  • parent 指向框架的包含框架集

  • self 指向框架自身


窗口位置

这部分内容的整理都来自于《js高级程序设计(第三版)》,但是在实际操作过程中(Mac系统,2016年1约29日,除IE以外的最新版本浏览器),下述的部分跨浏览器兼容问题已经被统一

获取位置

  • screenX 浏览器相对屏幕左侧的位置
  • screenY 浏览器相对屏幕顶部的位置

MDN社区中对window对象的属性介绍里没有包含下列属性

  • screenLeft
  • screenTop

《js高级程序设计(第三版)》:IE, opera中使用screenLeft和screenTop,获取的是viewport左侧和顶部的位置

  • 跨浏览器兼容问题
    1
    2
    3
    4
    var leftPos = (typeof window.screenLeft == "number") ?
    window.screenLeft : window.screenX ;
    var topPos = (typeof window.screenTop == "number") ?
    window.screenTop : window.screenY ;

设置位置

浏览器可能会禁用这些方法

  • moveTo() 接受x,y两个轴上的绝对像素值(新的位置)
  • moveBy() 接受x,y两个轴上的相对像素值(要移动的距离)


窗口大小

这部分内容的整理都来自于《js高级程序设计(第三版)》,但是在实际操作过程中(Mac系统,2016年1约29日,除IE以外的最新版本浏览器),下述的部分跨浏览器兼容问题已经被统一

获取大小

  • innerWidth innerHeight 返回viewport的大小,包含滚动条(如果有的话)

  • outerWidth outerHright 返回浏览器窗口的大小

  • document.documentElement.clientWidth clientHeight 返回viewport的大小

  • document.body.clientWidth clientHeight 返回viewport的大小
    适用于IE6下混杂模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var inWid = window.innerWidth;
var inHei = window.innerHeight;
var str1 = "innerWidth:" + inWid + ", innerHeight:" + inHei;
console.log(str1);
var outWid = window.outerWidth;
var outHei = window.outerHeight;
var str2 = "outerWidth:" + outWid + ", outerHeight:" + outHei;
console.log(str2);
var clientWid = document.documentElement.clientWidth;
var clientHei = document.documentElement.clientHeight;
console.log(clientWid + "," + clientHei);
var bodyClientWid = document.documentElement.clientWidth;
var bodyClientHei = document.documentElement.clientHeight;
console.log(bodyClientWid + "," + bodyClientHei);

设置大小

浏览器可能会禁用这些方法

  • resizeTo() 新的宽度和高度
  • resizeBy() 与原宽高的差


导航与打开窗口

属性、方法

  • window.open()

    传入四个参数,url, name, stringFeature, boolean

    • 第一个参数即要打开的新窗口的url

    • 第二个参数即要打开的新窗口的名称

      • 如果设定的名称是当前窗口中的框架的名称,则在框架中打开
      • 如果是已有窗口的名称,则在该窗口中打开
      • 如果无法匹配上述框架或窗口,则新建窗口打开并以此命名
      • 也允许使用_top _parent _self _blank这四个特殊名称
    • 第三个参数为特性字符串

      • width height 新窗口的大小
      • left top 新窗口的位置
      • resizable 设置新窗口是否可以缩放
      • location 是否显示地址栏
      • menubar 是否显示菜单栏
      • toolbar 是否显示工具栏
      • scrollbars 是否显示滚动条(实测火狐可以设置,其他的都被禁用了)
      • status 显示状态信息
      • fullscreen IE设置全屏
    • 第四个参数是一个表示新页面是否取代浏览器历史记录中当前加载页面的布尔值。仅在新页面不在打开新窗口的情况下可用

  • close()

    • 关闭新打开的窗口
      1
      2
      var newWindow = window.open("http://www.google.com", "google", "width=400,height=400, left=500, top=500");
      newWindow.close();//关闭该窗口
  • closed属性
    用以检测某窗口是否被关闭

  • opener属性
    新创建的窗口对象持有这个属性,并且回指打开该窗口的原始窗口对象

安全限制

出于安全考虑,window.open()的大部分属性特征都被禁用了,如location, status

屏蔽新弹出窗口

  • 如果新弹出窗口被屏蔽,则window.open()有可能会返回null

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var blocked = false;
    try{
    var newWindow = window.open(url, name, stringFeature);
    if(newWindow == null) {
    blocked = true;
    }
    } catch(ex) {
    blocked = ture;
    }
    if (blocked) {
    console.log("this new window is blocked");
    }
    //如果窗口被屏蔽,open一般会抛错,所以用try-cacth块保证代码执行


间歇调用与超时调用

与eval不同,间歇调用与超时调用调用的代码是在全局环境下运行的,所以this指向window

间歇调用

  • setInterval
  • clearInterval

超时调用

  • setTimeout
  • clearTimeout

  • 使用clearTimeout可以立即清除执行setTimeout的队列,这一点在动画实现的时候必须注意,因为很有可能上一个超时调用还未执行结束,又开始执行一个新的超时调用,容易导致问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// 移动元素
function moveElem(elemClass, final_x, final_y, interval){
//获取元素
var elem = document.getElementsByClassName(elemClass)[0];
// 验证假设
if(elem.movement) {
clearTimeout(elem.movement);
}
if (!elem.style.left) {
elem.style.left = "0px";
}
if (!elem.style.top) {
elem.style.top = "0px";
}
// 获取当前位置
var xpos = parseInt(elem.style.left);
var ypos = parseInt(elem.style.top);
var dist = 0;
// 判断
if (xpos == final_x && ypos == final_y) { return ture};
if (xpos < final_x){
dist = Math.ceil(final_x - xpos) / 10;
xpos += dist;
}
if (xpos > final_x){
dist = Math.ceil(xpos - final_x) / 10;
xpos -= dist;
}
if (ypos < final_y){
dist = Math.ceil(final_y - ypos) / 10;
ypos += dist;
}
if (ypos > final_y){
dist = Math.ceil(ypos - final_y) / 10;
ypos -= dist;
}
// 移动
elem.style.left = xpos + "px";
elem.style.top = ypos + "px";
var repeat = "moveElem('" + elemClass + "'," + final_x + "," + final_y + "," + interval +")";
elem.movement = setTimeout(repeat, interval);
}


系统对话框

alert

confirm

  • 接受一个字符串型参数,为显示在验证框上的文字

  • 点击确认会返回true

  • 点击取消会返回false

prompt

  • 接受两个字符串型参数,第一个为显示在输入框之上的提示文字,第二个为输入框中的默认文字(可以为空)

  • 点击确认会返回输入的文本(如果有默认文本,同时用户没有输入,则返回默认文本)

  • 点击取消会返回null

print

find


location

属性

href pathname
host hostname port
hash search protocal

位置方法

  • 直接为location对象的href, host, hostname, port, hash赋值,可以改变浏览器的位置

    1
    location.href = "new url";
  • 直接为window.location赋值,也可以改变浏览器的位置

  • assign() 调用location的assign()方法

    1
    location.assign("new url");

除了直接修改location.hash之外,修改其他的属性或者调用assign方法,都会在浏览器历史记录中生成一条新的记录,并在当前页面重载新的url,且用户可以通过工具栏中的后退返回至上一个页面
高版本的浏览器中,修改location.hash也会生成一条新的历史记录

  • replace() 调用replace方法会重载新的url,但是用户不能通过工具栏中的后退返回至上一个页面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    //假如我们需要使用下面这种很笨的方法进行重定向……
    var text = document.getElementById("id");
    var count = 5,
    min = 0;
    function redirect() {
    text.textContent = count;
    count--;
    if(count >= min) {
    setTimeout(redirect, 1000);
    } else {
    text.textContent = "即将重定向至……";
    var rst = "location.replace('new url')";
    setTimeout(rst, 1000);
    }
    }
    setTimeout(redirect,1000)

截取字符串

location对象截取字符串参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function getQueryStringArgs() {
var qs = (location.search.length > 0 ? location.search.slice(1) : "");
var args = {};
var items = qs.length ? qs.split("&") : [];
var item = null,
name = null,
value = null;
var i = 0,
len = items.length;
for (i = 0; i < len; i++) {
item = items[i].split("=");
name = decodeURIComponent(item[0]);
value = decodeURIComponent(item[1]);
if(name.length) {
args[name] = value;
}
};
return args;
}


属性

插件检测

navigator.plugins属性

plugins数组每一项都包含下列属性:

  • name 插件的名称
  • desciption 插件的描述
  • filename 插件的文件名
  • length 插件所处理的MIME类型的数量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//检测插件
//非IE
function hasPlugin(name) {
name = name.toLowercase();
for(var i = 0; i < navigator.plugins.length; i++) {
if(navigator.plugins[i].name.toLowercase().indexOf(name) != -1){
return true;
}
}
return false;
}
//IE
function hasIEplugin(name) {
try {
new ActiveXObejct(name);
return true;
} catch (ex) {
return false;
}
}
function hasProperPlugin(name, filename) {
var rst = hasPlugin(name);
if(!rst){
rst = hasIEplugin(filename);
}
return rst;
}


screen


history

history对象保存着当前窗口打开以来的所有历史记录,处于安全考虑不会保存url的具体信息

跳转方法

  • history.go() 传入正数或负数,向前后跳转到指定页面
  • history.back() 后退
  • history.foward() 前进

页面数记录

  • history.length 该属性保存了当前页面打开过的页面数量

  • 当前页面是否是第一次被打开

    1
    2
    3
    if(history.length == 0) {
    statement
    }