react window onresize 问题_JavaScript(12) Window 对象

BOM

浏览器对象模型. 把浏览器当成一个对象来看待. 用于和浏览器窗口进行交互.

例如: 后退页面, 刷新页面, 修改窗口大小等.

注意:

BOM 是缺乏标准的.

JS 有 ECMA 标准, DOM 有 W3C 标准. 而 BOM 取决于各个浏览器具体的实现.

BOM 比 DOM 更大.

a2f4389624e22bf37b8a214583b4855f.png

Window 对象

基本概念

window 是 BOM 中的顶层节点对象.

document 其实是 window 对象中的一个属性. 也可以写作 window.document.

window 在我们开发中有两层用途:

  1. 作为 js 代码和浏览器交互的接口.

  2. 作为 js 代码的全局命名空间. 所谓的 "全局变量" 其实就是 window 的一个属性.

 a = 10;console.log(window.a);function hello() {    alert('hello');}window.hello();

平时是用这些变量和函数的时候可以省略 window.

像 alert 等函数其实都是 window 的方法.

窗口加载事件

如果把 script 标签写到页面结构上面, 则无法正确获取到对应的元素.

因为浏览器会从上到下解析 html 的结构. 执行到 document.querySelector('button') 时浏览器还没有读取到

button 标签, 此时是无法获取到 button 对象的.

 <script>    var button = document.querySelector('button');    button.onclick = function () {        alert('hello');    }script><button>点我一下button>

010329ed84a64722228d22fd68b050a5.png

为了解决这个问题, 就可以使用 load 事件

  • load 事件, 会在页面完全加载完毕时触发.

 <script>    window.onload = function () {        var button = document.querySelector('button');        button.onclick = function () {            alert('hello');        }    }    // 或者使用    window.addEventListener('load', function () {        var button = document.querySelector('button');        button.onclick = function () {            alert('hello');        }    });script><button>点我一下button>
  • DOMContentLoaded 事件, 会在页面 DOM 加载完就执行, 不必等待 CSS, 图片等其他资源加载. (IE9以上支持)

 <script>           window.addEventListener('DOMContentLoaded', function () {        var button = document.querySelector('button');        button.onclick = function () {            alert('hello');        }    });script><button>点我一下button>

注意, 这种方式只能使用 addEventListener, 不能使用 onDOMContentLoaded 的方式进行.

  • pageshow 事件. 和 load 事件基本类似. 但是在 firefox 上, 浏览器会缓存前进后退的页面, 此时前进后退时不会触发 load 事件, 但是能触发 pageshow 事件.

调整窗口大小事件

  • resize 事件会在窗口大小发生变化时触发.

  • window.innerWidth/window.innerHeight 来获取到当前屏幕的尺寸.

 <script>    window.onresize = function() {        console.log(window.innerWidth, window.innerHeight);    }script>

基于这种方式可以实现响应式布局.

"响应式布局" 指的是根据屏幕的尺寸决定页面的排列方式.

比如是 PC 端, 屏幕比较宽, 就可以横版排列. 如果是手机端, 屏幕比较窄, 就可以竖版排列.

 <div>    我是一个区域div><style>    div {        background-color: red;        height: 300px;    }style><script>    window.onresize = function () {        var div = document.querySelector('div');        if (window.innerWidth >= 1000) {            div.style.width = '600px';        } else {            div.style.width = '300px';        }    }script>

定时器

相当于一个闹钟. 设定一定的时间之后, 触发对应的函数.

setTimeout
 var timeoutID = window.setTimeout(function[, delay]);var timeoutID = window.setTimeout(function[, delay, arg1, arg2, ...]);
  • delay 的单位为 ms. 可以省略. 省略则默认值为 0. (立刻执行)

  • arg1, arg2, ... 是给 function 传递的参数. (低于IE9不支持)

  • 返回值是该定时器的标识符(就是个名字), 用来区分多个定时器.

 <script>    var timer = window.setTimeout(function () {        alert('hello');    }, 5000);script>

代码示例: 3s 钟后关闭广告界面

此处的广告直接使用一张图片表示了.

clearTimeout

用于停止 setTimeout 定时器.

window.clearTimeout(timeoutID);
  • 参数就是 setTimeout 的返回值.

停止定时器
setInterval
var intervalID = scope.setInterval(func, delay, [arg1, arg2, ...]);
  • delay 的单位为 ms. 可以省略. 省略则默认值为 0. (立刻执行)

  • arg1, arg2, ... 是给 function 传递的参数. (低于IE9不支持)

  • 返回值是该定时器的标识符(就是个名字), 用来区分多个定时器.

用法和 setTimeout 非常相似.

区别: setInterval 是每隔 delay 时间都会执行一次(周期性执行), 而 setTimeout 只执行一次.

可以看到每隔一秒打印一次 hehe 的值.

代码示例: 3秒钟后关闭广告, 关闭过程中显示一个倒计时.

还剩 3 秒自动关闭广告

注意, 这里一定要先给 div 中设置好初始值, setInterval 的第一次执行要等 delay 时间到才会触发.

clearInterval
停止计数

this 的指向问题

this 始终指向调用函数的对象.

1) 如果是一个全局函数或者是注册到定时器中的函数, this 指向 window

function hello() {
console.log(this);
}
hello();
setTimeout(hello, 500);

2) 如果函数是一个方法, 则指向该方法所属对象

function hello() {
console.log(this);
}
var obj = {
name: '张三',
say: hello
}
obj.say();

形如 btn.addEventListener('click', fn) 这样的代码, 其实就相当于是给 btn 增加了方法 fn.

所以 fn 内部的 this 就指向 btn 对象.

3) 如果是构造函数, 则 this 指向被新创建出的实例.

function Cat() {
this.name = '小黑';
this.type = '中华田园';
this.miao = function () {
alert('喵');
}
console.log(this);
}
var cat = new Cat();

同步和异步

一个代码
console.log('1');
setTimeout(function () {
console.log('2');
}, 0);
console.log('3');
// 执行结果
1
3
2

虽然 setTimeout 的第二个参数是 0, 但是仍然在 console.log('3'); 之后执行的.

同步任务和异步任务

同步任务都在主线程上执行.

异步任务是通过回调函数的方式执行的.

异步任务的类型:

  • 普通事件: click, mousemove等

  • 资源加载: load, DOMContentLoaded等

  • 定时器: setTimeout, setInterval

异步任务会放到一个任务队列中.

JS 执行时会先把所有的同步任务都执行完, 然后再检查异步任务是否可以执行.

此时我们发现, while 是一个死循环, 这个死循环导致页面无法正常加载, 也就更无法响应点击事件.

事件循环

JS 是一个只能单线程执行的语言. 使用事件循环的机制实现了异步任务.

288093fa5d925853c3c1260016dad7b8.png

理解事件循环的过程

1) 关键要素:

  • 主线程: 执行同步任务的线程. 当遇到异步任务时, 则把异步任务交给异步处理进程.

  • 异步处理进程: 用来管理异步任务, 判断该异步任务是否已经到了可以执行的时机. 如果时机成熟, 则放到回调队列中执行.

  • 回调队列/消息队列: 放置待执行的回调函数的队列. 主线程在完成自己已有的同步任务之后, 就会从回调队列中取异步任务来执行.

2) 类比:

  • 主线程可以想象成是一个高速公路, 上面跑过的一辆一辆车, 就是执行的一个一个任务.

  • 如果发生了交通事故, 那么相关车辆就不能立刻往下跑了, 而应该要进入应急车道, 同时通知 110 来处理(110 就是异步处理进程)

  • 110 来事故现场定责, 处理完毕后, 警察会判定哪个车可以继续跑, 哪个车要被暂时扣下. 警察说 "张三你的车可以走了", 就相当于把该任务放到回调队列中. 张三真的把车开走的时候, 就相当于通过主线程来从回调队列中取了一个任务继续执行(还是要通过公路往前走)

另外可以参考知乎帖子: "男朋友的大脑是单线程的怎么办"

参考 https://www.zhihu.com/question/358389988

location 对象

location 的属性

是 window 对象的一个重要属性. 用来获取或者设置当前页面的 url.

url 就是网址. 格式形如:

ddc7a9249902316b33af4f28cc3d9a60.png

location 对象的主要属性也就是围绕着 url 的结构来展开的.

  • Location.href 包含整个URL的一个DOMString

  • Location.protocol 包含URL对应协议的一个DOMString,最后有一个":"。

  • Location.host 包含了域名的一个DOMString,可能在该串最后带有一个":"并跟上URL的端口号。

  • Location.hostname 包含URL域名的一个DOMString

  • Location.port包含端口号的一个DOMString

  • Location.pathname 包含URL中路径部分的一个DOMString,开头有一个“/"。

  • Location.search 包含URL参数的一个DOMString,开头有一个“?”

  • Location.hash包含块标识符的DOMString,开头有一个“#”。

  • Location.username包含URL中域名前的用户名的一个DOMString

  • Location.password包含URL域名前的密码的一个 DOMString

  • Location.origin 只读包含页面来源的域名的标准形式DOMString

这些属性中我们重点关注 href 和 search

console.log(window.location);

1be511af29394204213bd31cd7830c97.png

代码示例: 点击跳转到其他页面(不使用 a 标签)

点我跳转

代码示例: 5秒后跳转到其他页面

5 秒后跳转

注意: 通过 location.href 的方式进行跳转没有历史记录, 不能使用后退功能.

location 的方法
  • assign: 跳转到一个新的链接. 带有历史记录.

  • replace: 替换当前页面. 相当于 location.href.

  • reload: 刷新页面(F5). 参数为 true , 则相当于强制刷新 (ctrl+F5)

访问服务器的时候很多资源会被缓存在浏览器. 强制刷新就是不使用缓存, 强行去服务器重新获取数据. ```

点我使用 assign点我使用 replace点我使用 reload

navigator 对象

表示浏览器的对象. 包含了一些浏览器的信息.

navigator 的属性

  • userAgent: 包含了浏览器版本和操作系统版本.

console.log(navigator.userAgent);
// 结果
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36

基于这个字段可以判定当前用户是 PC 端还是移动端.

function IsPC(){  
var userAgentInfo = navigator.userAgent;
var Agents = new Array("Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod");
var flag = true;
for (var v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) { flag = false; break; }
}
return flag;
}

history 对象

  • foward():  前进

  • back(): 后退

  • go(): 参数为 1 表示前进一步. 参数为 -1 表示后退一步.

demo.html

demo2前进

demo2.html

后退

本地存储

数据存储在浏览器中.  

sessionStorage
  • 容量: 5M

  • 按照键值对的方式来使用. (key 和 value 都只能是字符串).

  • 生命周期为关闭浏览器窗口: 关闭浏览器页面数据就没了. 刷新页面不丢失.

基本操作:

  1. setItem: 如果 key 不存在就创建新的. 存在就修改对应的 value

  2. getItem: 按照 key 来找 value

  3. removeItem: 按照 key 来删除

  4. clearItem: 删除所有 key.

插入获取删除清空
localStorage
  • 容量: 20M

  • 按照键值对的方式来使用. (key 和 value 都只能是字符串).

  • 生命周期为永久生效.

  • 同一个浏览器中的多个窗口之间可以共享.

基本操作(和 sessionStorage 一致):

  1. setItem: 如果 key 不存在就创建新的. 存在就修改对应的 value

  2. getItem: 按照 key 来找 value

  3. removeItem: 按照 key 来删除

  4. clearItem: 删除所有 key.

 <input type="text" id="key"><input type="text" id="value"><button id="set">插入button><button id="get">获取button><button id="remove">删除button><button id="clear">清空button><script>    var k = document.querySelector('#key');    var v = document.querySelector('#value');    var setBtn = document.querySelector('#set');    setBtn.addEventListener('click', function () {        localStorage.setItem(k.value, v.value);    });    var getBtn = document.querySelector('#get');    getBtn.addEventListener('click', function () {        var value = localStorage.getItem(k.value);        console.log(value);    });    var removeBtn = document.querySelector('#remove');    removeBtn.addEventListener('click', function () {        localStorage.removeItem(k.value);    });    var clearBtn = document.querySelector('#clear');    clearBtn.addEventListener('click', function () {        localStorage.clear();    });script>

注意: 所有页面都共用 localStorage , 这就意味着容易和其他的网页的存储数据冲突. 尤其谨慎使用 clear 方法.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值