第08章 - BOM

作者: 勤劳的悄悄 | 来源:发表于2016-02-19 09:51 被阅读57次

    8.1 window 对象

    window 对象扮演双重角色:即是访问浏览器的接口,又是 ECMAScript 规定的 Global 对象


    8.1.1 全局作用域

    在全局作用域上定义的变量和函数都会变成 window 对象的属性和方法

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

    全局变量和 window 属性的差别之一:全局变量不能通过 delete 操作从 window 对象中删除。因为用 var 添加的 window 属性,其 [[Configurable]] 特性被设置为 false,因此不能删除

    var age = 29;
    window.color = "red";
    
    //全局变量不能删除
    delete window.age;
    
    //全局属性可以删除
    delete window.color; //returns true
    alert(window.age); //29
    alert(window.color); //undefined
    

    全局变量和 window 属性的差别之二:访问不存在的全局变量会报错,访问不存在的 window 属性返回 undefined

    //oldValue 不存在,会报错
    var newValue = oldValue;
    
    //window.oldValue 属性不存在,仅仅返回 undefined
    var newValue = window.oldValue;
    

    8.1.2 窗口关系及框架

    每个框架都有自己的 window 对象,保存在 frames 中,可以通过数值索引,索引从 0 开始,顺序是从左到右、从上到下

    两个特殊的框架名称:

    • top 指向最顶层框架
    • parent 指向上层框架

    8.1.3 窗口位置

    screenLeftscreenTop 返回显示区域的坐标,除了火狐浏览器不支持,其他几种浏览器新版本都支持。

    • 谷歌浏览器、IE 浏览器和 Win10 浏览器都返回 0 和工具栏高度
    • 火狐浏览器不支持这两个属性

    screenXscreenY 返回窗口的坐标

    • 谷歌浏览器返回和 screenLeft、 screenTop 相同的值
    • 火狐和新版 IE 浏览器返回 -8 -8
    • 新版 Win10 浏览器返回 0 0

    下面这段代码可以在不同浏览器下都获得数值

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

    但是因为各种浏览器的返回值各不相同,所以无法在跨浏览器的条件下取得窗口的精确坐标


    moveTomoveBy 方法可以将浏览器移动到准确的新位置,但是大部分新浏览器不再支持中两个方法,只有 IE 还支持

    //move the window to the upper-left coordinate
    window.moveTo(0,0);
    //move the window down by 100 pixels
    window.moveBy(0, 100);
    
    //move the window to position (200, 300)
    window.moveTo(200, 300);
    //move the window left by 50 pixels
    window.moveBy(-50, 0);
    

    8.1.4 窗口大小

    innerWidth, innerHeight 在各个浏览器中均返回视口大小


    outerWidth, 和 outerHeight

    • 在谷歌浏览器中还是返回视口大小
    • 其他浏览器窗口大小

    IE 浏览器在 IE8 之前的没有提供这几个属性。虽然无法在跨浏览器的条件下取得窗口的大小,但是可以利用下面的代码取得视口的大小

    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;
        }
    }
    

    改变浏览器大小

    resizeToresizeBy 方法可以改变浏览器的大小,但是大部分新浏览器不再支持中两个方法,只有 IE 还支持

    //resize to 100 x 100
    window.resizeTo(100, 100);
    //resize to 200 x 150
    window.resizeBy(100, 50);
    //resize to 300 x 300
    window.resizeTo(300, 300);
    

    8.1.5 导航和打开窗口

    window.open 方法可以导航到一个特定的 URL ,也可以打开一个新浏览器。接受四个参数:

    • URL
    • 窗口目标
    • 特性字符创
    • 历史记录

    只有第一个参数是必须的,其他都有默认值


    弹出窗口

    下面的代码在指定框架中打开新的页面

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

    常用的目标窗口名称

    • _self
    • _parent
    • _top
    • _blank

    第三个参数可以指定浏览器的特性,比如是否隐藏工具栏地址栏等等

    设置 说明
    fullscreen "yes" or "no" 是否最大化
    height 数值
    left 数值
    location "yes" or "no"
    menubar "yes" or "no"
    resizable "yes" or "no"
    scrollbars "yes" or "no"
    status "yes" or "no"
    toolbar "yes" or "no"
    top 数值
    width 数值

    window.open 方法返回窗口对象,可以对这个对象进行操作

    var wroxWin =window.open("http://www.wrox.com/","wroxWindow",
                "height=400,width=400,top=10,left=10,resizable=yes");
    
    //resize it
    wroxWin.resizeTo(500, 500);
    
    //move it
    wroxWin.moveTo(100, 100);
    

    close 方法可以关闭窗口对象,closed 属性可以检测窗口对象是否已经关闭

    wroxWin.close();
    alert(wroxWin.closed); //true
    

    window 对象的 opener 属性保存着打开本 window 对象的那个 window 对象

    var wroxWin =window.open("http://www.wrox.com/","wroxWindow",
                "height=400,width=400,top=10,left=10,resizable=yes");
    alert(wroxWin.opener == window); //true
    

    如果将 window 对象的 opener 属性设置为 null ,则主窗口和被打开窗口分别在独立的进程中运行,两个窗口对象不再有关系

    var wroxWin =window.open("http://www.wrox.com/","wroxWindow",
                "height=400,width=400,top=10,left=10,resizable=yes");
    wroxWin.opener = null;
    

    安全限制

    由于打开窗口可能存在安全隐患,大部分浏览器都设置了很多安全限制。


    屏蔽程序

    如果打开窗口被浏览器本身屏蔽,则 window.open 方法返回 null

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

    如果打开窗口被插件或者扩展程序屏蔽,则 window.open 会抛出异常。下面的代码,无论窗口是被浏览器屏蔽,还是被扩展程序屏蔽,都可以正确处理。

    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!");
    }
    

    8.1.6 间歇调用和超时调用

    超时调用:setTimeout 先等待一段时间,然后将任务添加到执行队列中。需要注意的是:执行队列中的任务是根据调度执行的,不一定立即执行

    回调任务可以是字符串,但是不推荐这种用法,通常还是一个回调函数

    //不推荐
    setTimeout("alert(‘Hello world!’) ", 1000);
    
    //推荐用法
    setTimeout(function() {
        alert("Hello world!");
    }, 1000);
    

    setTimeout 方法返回一个标识符 ID,clearTimeout 使用这个 ID 可以取消超时调用,即不再进行超时等待,也不会向执行队列中插入任务

    
    //设置超时调用
    var timeoutId = setTimeout(function() {
        alert("Hello world!");
    }, 1000);
    
    //取消超时调用
    clearTimeout(timeoutId);
    

    间歇调用:setInterval 每隔一段时间,就向执行队列中插入任务。

    
    //不推荐用法
    setInterval("alert(‘Hello world!’) ", 10000);
    
    //推荐用法
    setInterval(function() {
        alert("Hello world!");
    }, 10000);
    

    setInterval 方法也返回一个标识符 ID,clearInterval 使用这个 ID 取消间歇调用,即不再继续向执行队列中插入新的任务,但是已经插入到执行队列中的任务会继续执行。

    var num = 0;
    var max = 10;
    var intervalId = null;
    
    function incrementNumber() {
        num++;
    
        //如果达到条件,则取消间歇调用
        if (num == max) {
            clearInterval(intervalId);
            alert("Done");
        }
    }
    
    intervalId = setInterval(incrementNumber, 500);
    

    上面的功能也可以利用递归超时调用来完成

    var num = 0;
    var max = 10;
    function incrementNumber() {
        num++;
    
        //如果满足条件则进行下一次超市调用,否则退出
        if (num < max) {
            setTimeout(incrementNumber, 500);
        } else {
            alert("Done");
        }
    }
    
    setTimeout(incrementNumber, 500);
    

    超时调用在等待一定时间、向执行队列添加任务,然后退出;而间歇调用会不断地向执行队列中添加任务,想要退出必须手动调用 clearInterval 方法。因此,应该尽可能的使用超时调用,而不是间歇调用。

    8.1.7 系统对话框

    8.2 location 对象

    location 对象是最有用的 BOM 对象之一:

    • 它保存着当前加载文档的一些有用信息
    • 可以进行导航
    • 既是 window 的属性,又是 document 的属性
    • 将 URL 进行了解析,并将各部分信息保存在自己的属性中
    属性名 例子 说明
    host "www.wrox.com:80" 主机名加端口
    hostname "www.wrox.com" 主机名
    href "http:/www.wrox.com" 当前加载页的完整 URL,location 对象的 toString() 方法返回的也是这个值
    hash "#contents" 返回 URL 中的 hase
    pathname "/WileyCDA" 返回路径或者文件名
    port "8080" 端口号
    protocol "http:" 协议字符串
    search "?q=javascript" 查询字符串

    8.2.1 解析查询字符串参数

    算法:

    • 第一步:把首字母 ? 去掉
    • 第二步:用 "&" 字符切分查询字符串,得到查询键值对
    • 第三步:将每个键值对用 "=" 切分,得到键值
    • 第四步:别忘了用 decodeURIComponent 解码
    
    function getQueryStringArgs(){
        //get query string without the initial ?
        var qs = (location.search.length > 0 ? location.search.substring(1) : ""),
        
        //object to hold data
        args = {},
        
        //get individual items
        items = qs.length ? qs.split("&") : [],
        item = null,
        name = null,
        value = null,
        
        //used in for loop
        i = 0,
        len = items.length;
        
        //assign each item onto the args object
        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;
    }
    
    //assume query string of ?q=javascript&num=10
    var args = getQueryStringArgs();
    
    alert(args["q"]); //"javascript"
    alert(args["num"]); //"10"
    
    

    8.2.2 改变位置

    location.assign 方法改变浏览器的位置

    设置 window.location 和 location.href 属性也是调用 assing 方法,效果一样

    
    location.assign("http://www.wrox.com");
    
    window.location = "http://www.wrox.com";
    location.href = "http://www.wrox.com";
    

    设置 location 对象的其他属性也可以改变浏览器位置

    
    //assume starting at http://www.wrox.com/WileyCDA/
    //changes URL to "http://www.wrox.com/WileyCDA/#section1"
    location.hash = "#section1";
    //changes URL to "http://www.wrox.com/WileyCDA/?q=javascript"
    location.search = "?q=javascript";
    //changes URL to "http://www.yahoo.com/WileyCDA/"
    location.hostname = "www.yahoo.com";
    //changes URL to "http://www.yahoo.com/mydir/"
    location.pathname = "mydir";
    //changes URL to "http://www.yahoo.com:8080/WileyCDA/
    
    

    防止产生历史记录

    location.replace() 方法可以重新定位浏览器位置,但是不产生历史记录

    
    <!DOCTYPE html>
    <html>
    <head>
        <title>You won’t be able to get back here</title>
    </head>
    
    <body>
        <p>Enjoy this page for a second, because you won’t be coming back here.</p>
        <script type="text/javascript">
            setTimeout(function () {
                location.replace("http://www.wrox.com/");
            }, 1000);
        </script>
    </body>
    </html>
    

    重新加载页面

    location.reload() 方法重新加载页面。注意:调用这个方法后,因为重新加载页面,所以之后的代码可能不会被执行。

    location.reload(); //可能会从缓存加载
    location.reload(true); //强制从服务器加载
    

    8.3 navigator 对象

    通过读取 navigator 对象的各种属性,可以获取浏览器的各种信息。具体用法可以查阅资料

    8.3.1 检测插件

    navigator 对象的 plugins 属性是个数组,其中每一项都是包含一个插件的信息

    //插件检测,在 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;
    }
    
    //检测 flash
    alert(hasPlugin(”Flash”));
    //检测 quicktime
    alert(hasPlugin(”QuickTime”));
    

    检测 IE 中的插件要使用 ActiveXObject

    //检测 Internet Explorer 插件
    function hasIEPlugin(name){
        try {
            new ActiveXObject(name);
            return true;
        } catch (ex){
            return false;
        }
    }
    
    //检测 flash
    alert(hasIEPlugin(“ShockwaveFlash.ShockwaveFlash”));
    //检测 quicktime
    alert(hasIEPlugin(“QuickTime.QuickTime”))
    

    综合使用上面两种方法可以检测各种浏览器的插件

    //检测 flash
    function hasFlash(){
        var result = hasPlugin(“Flash”);
    
        if (!result){
            result = hasIEPlugin(“ShockwaveFlash.ShockwaveFlash”);
        }
    
        return result;
    }
    
    //检测 quicktime
    function hasQuickTime(){
        var result = hasPlugin(“QuickTime”);
    
        if (!result){
            result = hasIEPlugin(“QuickTime.QuickTime”);
        }
    
        return result;
    }
    
    //检测 flash
    alert(hasFlash());
    //检测 quicktime
    alert(hasQuickTime());
    
    

    8.3.2 注册处理程序

    还不成熟,不需要了解

    8.4 screen 对象

    screen 可以获取用户显示器的各种信息,相关属性和方法请自行查阅资料

    8.5 history 对象

    每个窗口和框架都有自己的 history 对象,他是 window 的一个属性。利用 history 对象,可以在用户的浏览历史页面中跳转

    按编号跳转

    //go back one page
    history.go(-1);
    
    //go forward one page
    history.go(1);
    
    //go forward two pages
    history.go(2);
    

    按站点名字跳转

    //go to nearest wrox.com page
    history.go(“wrox.com”);
    
    //go to nearest nczonline.net page
    history.go(“nczonline.net”);
    

    向前向后跳转

    //go back one page
    history.back();
    
    //go forward one page
    history.forward();
    

    判断当前页面是否是当前窗口打开的第一个页面

    if (history.length == 0){
        //this is the first page in the user’s window
    }
    

    相关文章

      网友评论

        本文标题:第08章 - BOM

        本文链接:https://www.haomeiwen.com/subject/fvtvkttx.html