Window对象


Window对象

Window对象及其在客户端JavaScript中所扮演的核心角色:它是客户端 JavaScript程序的全局对象。Window对象是以窗口命名的。

计时器

setTimeout( )和setinterval( )可以用来注册在指定的时间之后单次或重复调用的函数。因为它们都是客户端JavaScript中重要的全局函数,所以定义为Window对象的方法,但作为通用函数,其实不会对窗口做什么事情。

Window对象的setTimeout( )方法用来实现一个函数在指定的毫秒数之后运行。setTimeout( )返回一个值,这个值可以传递给clearTimeout( )用于取消这个函数的执行。

setinterval( )和setTimeout( )一样,只不过这个函数会在指定毫秒数的间隔里重复调用:

setinterval(updateClock, 60000); // 每60秒调用一次updateClock()

和setTimeout( )一样,setlnterval( )也返回一个值,这个值可以传递给 clearlnterval( ),用于取消后续函数的调用。

下例定义的应用函数会在等待指定的时间之后,开始重复调用某个函数,然后又过了一段时间之后取消函数调用。该例子演示了setTimeout( )、setlnterval( )和clearinterval( )的用法。

例:定时器应用函数
/*
 * 安排函数f()在未来的调用模式
 * 在等待了若干毫秒之后调用f()
 * 如果设置了interval并没有设置end参数,则对f()调用将不会停止
 * 如果没有设置interval和end,只在若干毫秒后调用f()一次
 * 只有指定了f(),才会从start=0的时刻开始
 * 注意,调用invoke()不会阻塞,它会立即返回
 */
 
function invoke(f, start, interval, end) { 
    if (!start) start = 0; 
    if (arguments.length <= 2) 
        setTimeout(f, start); 
    else { 
        setTimeout(repeat, start); 
        function repeat() { 
            var h = setInterval(f, interval);
            // 在end毫秒后停止调用,前提是end已经定义了 
            if (end) setTimeout(function() { clearInterval(h); }, end);
        }
    }
}    

由于历史原因,setTimeout( )和setInterval( )的第一个参数可以作为字符串传入。如果这么做,那这个字符串会在指定的超时时间或间隔之后进行求值(相当于执行eval( ))。 除前两个参数之外,HTML5规范(除IE之外的所有浏览器)还允许setTimeout( )和setlnterval( )传入额外的参数,并在调用函数时把这些参数传递过去。然而,如果需要支持IE的话,就不要应用此特性了。

如果以0毫秒的超时时间来调用setTimeout( ),那么指定的函数不会立刻执行。相反,会把它放到队列中,等到前面处于等待状态的事件处理程序全部执行完成后,再“立即”调用它。

浏览器定位和导航

Window对象的location属性引用的是Location对象,它表示该窗口中当前显示的文档的URL,并定义了方法来使窗口载入新的文档。

Document对象的location属性也引用到Location对象:

window.location === document.location // 总是返回true

Document对象也有一个URL属性,是文档首次载入后保存该文档的URL的静态字符串。如果定位到文档中的片段标识符(如#table-of-contents),Location对象会做相应的更新,而document.URL属性却不会改变。

解析 URL

Window对象的location属性引用的是Location对象,它表示该窗口中当前显示的文档的URL。Location对象的href属性是一个字符串,后者包含URL的完整文本。Location对象的toString( )方法返回href属性的值,因此在会隐式调用toString( )的情况下,可以使用location代替location.href。

这个对象的其他属性 protocol,host,hostname,port,pathname和search,分别表示URL的各个部分。它们称为“URL分解”属性,同时被Link对象(通过HTML文档中的元素创建)支持。

Location对象的hash和search属性比较有趣。如果有的话,hash属性返回URL中的“片段标识符”部分。search属性也类似,它返回的是问号之后的URL,这部分通常是某种类型的査询字符串。一般来说,这部分内容是用来参数化URL并在其中嵌入参数的。虽然这些参数通常用于运行在服务器上的脚本,但在启用JavaScript的页面中当然也可以使用它们。下例展示了一个通用函数urlArgs( )的定义,可以用这个函数将参数从URL的search属性中提取出来。该例子用到了decodeURIComponent( ),后者是在客户端JavaScript定义的全局函数。

例:提取URL的搜索字符串中的参数
/*
 * 这个函数用来解析来自URL的査询串中的name=value参数对
 * 它将name=value对存储在一个对象的属性中,并返回盘对象
 * 这样来使用它
 *
 * var args = urlArgs(); // 从URL中解析参数
 * var q = args.q || ""; // 如果参数定义了的话就使用参数,否则使用一个默认值
 * var n = args.n ? parseInt(args.n) : 10;
 */
function urlArgs() {
    var args = {};                                // 定义一个空对象
    var query = location.search.substring(1);     // 查找到查询串,并去掉'?'
    var pairs = query.split("&");                 // 对于每个片段
    for(var i = 0; i < pairs.length; i++) {       // 查找"name=value"
    var pos = pairs[i].indexOf('=');              // 如果没有找到的话,就跳过
        if (pos == -1) continue;                  // 提取name
        var name = pairs[i].substring(o,pos);     // 提取value 
        var value = pairs[i].substring(pos+1);    // 对value进行解码
        value = decodeURIComponent(value);        // 存储为属性
        args[name] = value;
    }
    return args;                                  // 返回解析后的参数
}

载入新的文档

Location对象的assign( )方法可以使窗口载入并显示你指定的URL中的文档。replace( )方法也类似,但它在载入新文档之前会从浏览历史中把当前文档删除。如果脚本无条件地载入一个新文档,replace( )方法可能是比assgin( )方法更好的选择。否则,“后退” 按钮会把浏览器带回到原始文档,而相同的脚本则会再次载入新文档。如果检测到用户的浏览器不支持某些特性来显示功能齐全的版本,可以用location.replace( )来载入静态的HTML版本。

// 如果浏览器不支持XMLHttpRequest对象
// 则将其重定向到一个不需要Ajax的静态页面
if (!XMLHttpRequest) location.replace("staticpage.html");

注意,在这个例子中传入replace( )的是一个相对URL。相对URL是相对于当前页面所在的目录来解析的,就像将它们用于一个超链接中。

除了assgin( )和replace( )方法,Location对象还定义了reload( )方法,后者可以让浏览器重新载入当前文档。

使浏览器跳转到新页面的一种更传统的方法是直接把新的URL赋给location属性:

location = "http://www.oreilly.com"; // 在此网站购买书!

还可以把相对URL赋给location,它们会相对当前URL进行解析:

location = "page2.html";	// 载入下一个页面

纯粹的片段标识符是相对URL的一种类型,它不会让浏览器载入新文档,但只会使它滚动到文档的某个位置。#top标识符是个特殊的例子:如果文档中没有元素的ID是“top”,它会让浏览器跳到文档开始处。

location = "#top";	// 跳转到文档的顶部 

Location对象的URL分解属性是可写的,对它们重新赋值会改变URL的位置,并且导致浏览器载入一个新的文档(如果改变的是hash属性,则在当前文档中进行跳转):

location.search = "?page=" + (pagenum+1); // 载入下一个页面

浏览历史

Window对象的history属性引用的是该窗口的History对象。History对象是用来把窗口的浏览历史用文档和文档状态列表的形式表示。History对象的length属性表示浏览历史列表中的元素数量,但出于安全的因素,脚本不能访问已保存的URL。(如果允许,则任意脚本都可以窥探你的浏览历史。)

History对象的back( )和forward( )方法与浏览器的“后退”和“前进”按钮一样:它们使浏览器在浏览历史中前后跳转一格。第三个方法——go( )接受一个整数参数,可以在历史列表中向前(正参数)或向后(负参数)跳过任意多个页。

history.go(-2);    // 后退两个历史记录,相当于单击“后退”按钮两次

如果窗口包含多个子窗口(比如