Window对象

window对象概述

window对象是浏览器的全局对象,代表浏览器窗口。

全局对象

// window是全局对象
var a = 1;
console.log(window.a);  // 1

// 全局函数
function foo() {}
console.log(window.foo);  // function foo() {}

// 全局变量(let/const不会成为window属性)
let b = 2;
const c = 3;
console.log(window.b);  // undefined
console.log(window.c);  // undefined

window对象属性

// 文档对象
console.log(window.document);

// 导航对象
console.log(window.navigator);

// 位置对象
console.log(window.location);

// 历史对象
console.log(window.history);

// 屏幕对象
console.log(window.screen);

// 窗口自身
console.log(window.window);   // window
console.log(window.self);     // window
console.log(window.top);      // 最顶层窗口
console.log(window.parent);   // 父窗口
console.log(window.frames);   // 框架集合

全局作用域

window对象提供了全局作用域。

变量声明

// var声明的变量成为window属性
var globalVar = "东巴文";
console.log(window.globalVar);  // "东巴文"

// let/const不会
let blockVar = "db-w.cn";
console.log(window.blockVar);   // undefined

// 未声明变量
undeclaredVar = "hello";
console.log(window.undeclaredVar);  // "hello"

内置对象

// 所有内置对象都是window属性
console.log(window.Array);
console.log(window.Object);
console.log(window.JSON);
console.log(window.Math);
console.log(window.Date);
console.log(window.RegExp);
console.log(window.Error);
console.log(window.Promise);
console.log(window.Map);
console.log(window.Set);

全局函数

// 全局函数
window.parseInt("123");
window.parseFloat("3.14");
window.isNaN(NaN);
window.isFinite(100);
window.encodeURI("东巴文");
window.decodeURI("%E4%B8%9C%E5%B7%B4%E6%96%87");
window.encodeURIComponent("东巴文");
window.decodeURIComponent("%E4%B8%9C%E5%B7%B4%E6%96%87");
window.eval("1 + 1");  // 不推荐使用

窗口位置与大小

获取和设置窗口的位置与大小。

窗口位置

// 窗口位置(屏幕坐标)
console.log("左边距:", window.screenX);
console.log("上边距:", window.screenY);

// 旧属性(已废弃但广泛支持)
console.log(window.screenLeft);
console.log(window.screenTop);

// 移动窗口(可能被浏览器阻止)
window.moveTo(0, 0);           // 移动到指定位置
window.moveBy(100, 100);       // 相对移动

窗口大小

// 视口大小(不包含工具栏、滚动条)
console.log("宽度:", window.innerWidth);
console.log("高度:", window.innerHeight);

// 浏览器窗口大小
console.log("外部宽度:", window.outerWidth);
console.log("外部高度:", window.outerHeight);

// 文档大小
console.log("文档宽度:", document.documentElement.clientWidth);
console.log("文档高度:", document.documentElement.clientHeight);

// 调整窗口大小(可能被浏览器阻止)
window.resizeTo(800, 600);     // 调整到指定大小
window.resizeBy(100, 100);     // 相对调整

响应式布局检测

// 检测视口大小变化
function checkViewport() {
    const width = window.innerWidth;
    
    if (width < 576) {
        console.log("手机");
    } else if (width < 768) {
        console.log("平板");
    } else if (width < 992) {
        console.log("小型桌面");
    } else if (width < 1200) {
        console.log("中型桌面");
    } else {
        console.log("大型桌面");
    }
}

window.addEventListener("resize", debounce(checkViewport, 200));
checkViewport();

窗口操作

打开、关闭和操作窗口。

打开新窗口

// window.open(url, target, features)

// 基本用法
window.open("https://db-w.cn");

// 指定目标
window.open("https://db-w.cn", "_blank");   // 新窗口
window.open("https://db-w.cn", "_self");    // 当前窗口
window.open("https://db-w.cn", "_parent");  // 父窗口
window.open("https://db-w.cn", "_top");     // 顶层窗口
window.open("https://db-w.cn", "myWindow"); // 命名窗口

// 指定特性
const newWindow = window.open(
    "https://db-w.cn",
    "_blank",
    "width=800,height=600,left=100,top=100,menubar=no,toolbar=no,location=no,status=no"
);

// 返回新窗口的引用
if (newWindow) {
    console.log("新窗口已打开");
    newWindow.close();  // 关闭新窗口
}

窗口特性

// 完整特性列表
const features = [
    "width=800",          // 宽度
    "height=600",         // 高度
    "left=100",           // 左边距
    "top=100",            // 上边距
    "menubar=yes",        // 菜单栏
    "toolbar=yes",        // 工具栏
    "location=yes",       // 地址栏
    "status=yes",         // 状态栏
    "resizable=yes",      // 可调整大小
    "scrollbars=yes",     // 滚动条
    "directories=yes",    // 目录按钮
    "copyhistory=yes"     // 复制历史
].join(",");

window.open("https://db-w.cn", "_blank", features);

关闭窗口

// 关闭当前窗口(只能关闭由脚本打开的窗口)
const newWindow = window.open("", "_blank");
newWindow.document.write("<p>新窗口</p>");

setTimeout(() => {
    newWindow.close();
}, 3000);

// 检查窗口是否已关闭
console.log(newWindow.closed);  // false
newWindow.close();
console.log(newWindow.closed);  // true

窗口焦点

const newWindow = window.open("", "_blank");

// 聚焦
newWindow.focus();

// 失焦
newWindow.blur();

// 监听焦点事件
window.addEventListener("focus", () => {
    console.log("窗口获得焦点");
});

window.addEventListener("blur", () => {
    console.log("窗口失去焦点");
});

系统对话框

浏览器提供的原生对话框。

alert

// 警告框
alert("这是一个警告");

// 没有返回值
const result = alert("警告");
console.log(result);  // undefined

confirm

// 确认框
const confirmed = confirm("确定删除吗?");
console.log(confirmed);  // true 或 false

if (confirmed) {
    deleteItem();
}

prompt

// 输入框
const name = prompt("请输入你的名字:", "默认值");
console.log(name);  // 输入的内容或 null(取消)

if (name !== null) {
    console.log("你好, " + name);
}

对话框特点

// 特点1:同步阻塞
alert("开始");
const result = confirm("继续?");
alert("结束");  // 等待confirm后执行

// 特点2:样式由浏览器控制
// 无法自定义样式

// 特点3:可能被浏览器阻止
// 在某些情况下会被阻止显示

自定义对话框

// 使用HTML创建自定义对话框
function showConfirm(message) {
    return new Promise((resolve) => {
        const dialog = document.createElement("div");
        dialog.innerHTML = `
            <div class="dialog-overlay">
                <div class="dialog-box">
                    <p>${message}</p>
                    <button class="ok">确定</button>
                    <button class="cancel">取消</button>
                </div>
            </div>
        `;
        
        dialog.querySelector(".ok").onclick = () => {
            dialog.remove();
            resolve(true);
        };
        
        dialog.querySelector(".cancel").onclick = () => {
            dialog.remove();
            resolve(false);
        };
        
        document.body.appendChild(dialog);
    });
}

// 使用
showConfirm("确定删除吗?").then(result => {
    if (result) {
        deleteItem();
    }
});

定时器

延迟执行和周期执行的定时器。

setTimeout

// 延迟执行
const timerId = setTimeout(function() {
    console.log("1秒后执行");
}, 1000);

// 传递参数
setTimeout(function(name) {
    console.log("你好, " + name);
}, 1000, "东巴文");

// 取消定时器
clearTimeout(timerId);

// 立即执行(延迟0毫秒)
setTimeout(function() {
    console.log("下一个事件循环执行");
}, 0);

setInterval

// 周期执行
let count = 0;
const timerId = setInterval(function() {
    count++;
    console.log("执行次数:", count);
    
    if (count >= 5) {
        clearInterval(timerId);
    }
}, 1000);

// 注意:实际间隔可能比设定值长

定时器返回值

// 定时器ID是数字
const id1 = setTimeout(() => {}, 1000);
const id2 = setInterval(() => {}, 1000);

console.log(typeof id1);  // "number"
console.log(typeof id2);  // "number"

// 清除所有定时器(不推荐)
// let id = setTimeout(() => {}, 0);
// while (id--) clearTimeout(id);

定时器问题

// 问题1:this指向
const obj = {
    name: "东巴文",
    greet: function() {
        setTimeout(function() {
            console.log(this.name);  // undefined(this是window)
        }, 1000);
    }
};

// 解决方案1:箭头函数
const obj1 = {
    name: "东巴文",
    greet: function() {
        setTimeout(() => {
            console.log(this.name);  // "东巴文"
        }, 1000);
    }
};

// 解决方案2:bind
const obj2 = {
    name: "东巴文",
    greet: function() {
        setTimeout(function() {
            console.log(this.name);
        }.bind(this), 1000);
    }
};

// 问题2:定时器累积
let timer;
button.addEventListener("click", function() {
    clearTimeout(timer);  // 先清除之前的
    timer = setTimeout(() => {
        console.log("点击后执行");
    }, 500);
});

递归setTimeout

// 使用递归setTimeout代替setInterval
// 更精确的间隔控制
function interval(func, delay) {
    function run() {
        func();
        setTimeout(run, delay);
    }
    setTimeout(run, delay);
}

// 或者
let timer;
function repeat() {
    console.log("执行");
    timer = setTimeout(repeat, 1000);
}

repeat();
clearTimeout(timer);  // 停止

requestAnimationFrame

用于动画的高性能定时器。

基本用法

// 浏览器重绘前调用
function animate() {
    // 更新动画
    updateAnimation();
    
    // 请求下一帧
    requestAnimationFrame(animate);
}

requestAnimationFrame(animate);

取消动画帧

const animationId = requestAnimationFrame(animate);
cancelAnimationFrame(animationId);

动画示例

const element = document.querySelector(".box");
let position = 0;

function move() {
    position += 2;
    element.style.transform = `translateX(${position}px)`;
    
    if (position < 500) {
        requestAnimationFrame(move);
    }
}

requestAnimationFrame(move);

时间戳

let startTime = null;

function animate(timestamp) {
    if (!startTime) startTime = timestamp;
    
    const elapsed = timestamp - startTime;
    const progress = elapsed / 1000;  // 秒
    
    console.log("已过时间:", progress.toFixed(2), "秒");
    
    if (progress < 5) {
        requestAnimationFrame(animate);
    }
}

requestAnimationFrame(animate);

requestAnimationFrame vs setTimeout

// requestAnimationFrame优势
// 1. 与浏览器刷新率同步(通常60fps)
// 2. 页面不可见时自动暂停
// 3. 更流畅的动画效果

// setTimeout动画
function animateWithSetTimeout() {
    update();
    setTimeout(animateWithSetTimeout, 16);  // 约60fps
}

// requestAnimationFrame动画
function animateWithRAF() {
    update();
    requestAnimationFrame(animateWithRAF);
}

性能对比

特性 setTimeout requestAnimationFrame
时间精度 可能不准 与刷新率同步
页面隐藏 继续执行 自动暂停
节能
动画流畅度 一般 更好

下一步

掌握了Window对象后,让我们继续学习:

  1. Location对象 - 学习URL操作
  2. History对象 - 学习历史记录管理
  3. 其他BOM对象 - 学习Navigator和Screen

东巴文(db-w.cn) - 让编程学习更简单

🎯 东巴文寄语:window对象是浏览器环境的全局对象,掌握窗口操作、定时器和动画API是前端开发的基础技能。在 db-w.cn,我们帮你深入理解BOM编程!