作者:寒水寺一禅
转发链接:https://segmentfault.com/a/1190000023111128
目录
那些不常见,但却非常实用的JS知识点(上)本篇
一、window
window 对象表示一个包含 DOM 文档的窗口,其 document 属性指向窗口中载入的 DOM 文档 。
1、window 属性和方法
在有标签页功能的浏览器中,每个标签都拥有自己的 window 对象;也就是说,同一个窗口的标签页之间不会共享一个 window 对象。
1.1、几个浏览器的高度
window.screen.height==window.screen.availHeight
表示手机的屏幕高度,在一部手机中是固定的。不同浏览器打开,都不会变。
window.innerHeight==document.documentElement.clientHeight
表示浏览器中,除去顶部地址栏,下部工具栏之外,暴露给用户,可以看得见的中间区域。也就是实际的网页浏览高度,不同浏览器不同。
document.body.clientHeight
body 元素的高度。
如果设置 body 的 height:30px; 那么这个属性就是 30。
下面是示意图,在 pc 端同理
1.2、window.performance
Web Performance API 允许网页访问某些函数来测量网页和 Web 应用程序的性能,包括 Navigation Timing API 和高分辨率时间数据。
performance.now()
该方法返回一个 DOMHighResTimeStamp 对象,该对象表示从某一时刻(译者注:某一时刻通常是 navigationStart 事件发生时刻)到调用该方法时刻的毫秒数。
1.3、devicePixelRatio
返回当前显示设备的物理像素分辨率与 CSS 像素分辨率之比。
物理像素分辨率表示,你的电脑的硬件部分,在出场时,已经确定。
而 css 像素分辨率,则可以动态调整。
当电脑显示设置为 100%时,物理像素分辨率和 css 像素分辨率是相等的。即 devicePixelRatio 为 1
window.devicePixelRatio //1
而如果你将电脑设置为 150%;或者在电脑设置 100%时,同时将浏览器分辨率调成 150%,那么 devicePixelRatio 都为 1.5
window.devicePixelRatio //1.5
你可以将 devicePixelRatio 为 1.5 理解为,1px 的 css 样式,占用了电脑硬件屏幕分辨率的 1.5 个 dpi,所以肉眼看起来电脑上的文字更大些。
这种放大的效果在某些情况下,会导致 html 中的元素失真,典型的便是 canvas 变得模糊。
下面是矫正代码
//size为原本的大小
let scale = window.devicePixelRatio;
canvas.width = Math.floor(size * scale);
canvas.height = Math.floor(size * scale);
1.4、base64 编码/解码
window.btoa() 编码为 base64
window.atob() 解码
let encodedData = window.btoa("Hello, world"); // 编码
let decodedData = window.atob(encodedData); // 解码
1.5、requestAnimationFrame / cancelAnimationFrame()
window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。
回调函数执行次数通常是每秒 60 次,但在大多数遵循 W3C 建议的浏览器中,回调函数执行次数通常与浏览器屏幕刷新次数相匹配。但是却和 setInterval(),不同,因为 setInterval 设置的秒,并不一定准确在对应秒后执行,而是需要看是否有其他资源在执行,如果有,则等待。实际可能大于等于设置的秒数,而 requestAnimationFrame 会准确的按照浏览器渲染的频率想匹配
1.6、getSelection()
此方法不必传入具体的 dom,选中哪个区域或者光标在哪个输入框, 此方法会获取到那个 dom。 返回一个selection对象
window.getSelection();
1.7、scroll() / scrollBy() / scrollTo()
scroll()滚动至文档中的绝对位置(类似于 css 中的 display:absolute), scrollBy()滚动指定的距离(类似于 css 中的 display:relative)
scrollTo 和 scroll 一致。
window.scroll({
top: 100,
left: 100,
behavior: 'smooth' //表示是否平滑的过渡还是即可调到指定位置,同css属性scroll-behavior
});
window.scrollBy({
top: 100,
left: 100,
behavior: "smooth"
});
scroll() scrollBy() scrollTo()合称为 scrollOptions API
2、window 事件
通常在定义 window 中的事件时,有两种方式:
window.onXXX = function(){};
window.addEventListener("XXX", ()=>{}, {capture:true, once:true, passive:true});
那么这两种方式有区别吗? 有区别,但也没区别。
因为虽然定义的方式不同,可最终都会走到事件中。
但是又有区别,尤其在多个组件中,同时定义相同的事件,那么 window.onXXX 会后面定义的把前面定义的相同事件覆盖掉。最终只会执行最后定义的那个。而 window.addEventListener 不同,定义几个,执行几次,而且还可以在 options 中设置 once,capture,passive 等选项。
以 passive 为例,它可以忽略事件的默认行为,不会阻止它。当你在 js 操作时,html 中会立马响应到。最典型的可以使得触摸事件和 scroll 事件不再卡顿,非常流畅。
通常有 XXX 方式,那么对应也会有 onXXX
2.1、onbeforeunload
当窗口即将被卸载(关闭)时,会触发该事件.此时页面文档依然可见,且该事件的默认动作可以被取消.
需要注意的是,点击浏览器标签页的 x 号前,如果没有对页面进行过任何“操作”,则不会弹框直接关闭,如果进行过操作,则会弹出确认框。
这里所指的“操作”包括,但不限于,input 输入,打开 console,复制页面的一段文字等等。
window.onbeforeunload = () => {
let isIE = xxxxxxxx; //忽略通过user-agent判断ie浏览器的方法
if (isIE) {
return "The system may be not save your changes.";
} else {
return false; //其他浏览器会弹出自己的文字,如上图。是中文
}
};
2.2、onhashchange
当 一个窗口的 hash (URL 中 # 后面的部分)改变时就会触发 hashchange 事件(参见 location.hash)。
window.onhashchange = (newURL, oldURL)=>{
//newURL 当前页面新的URL
//oldURL 当前页面旧的URL
};
2.3、onload / DOMContentLoaded
DOMContentLoaded 致 html 页面加载完毕就会触发,至于一些异步资源的比如 img,video 等等,它不关心。
而 onload 表示除了 html 加载完,img,video 等也加载完,才执行
window.addEventListener("load", function () {
});
window.addEventListener("DOMContentLoaded", function () {
});
看到没: JavaScript event that fires when the DOM is loaded, but before all page assets are loaded (CSS, images, etc.). 说的再清楚不过了
2.4、onmouseover、onmouseout / onmouseenter、onmouseleave
onmouseover、onmouseout:鼠标移动到自身时候会触发事件,同时移动到其子元素身上也会触发事件 onmouseenter、onmouseleave:鼠标移动到自身是会触发事件,但是移动到其子元素身上不会触发事件
onmouseover 和 onmouseout 支持性一致
onmouseenter 和 onmouseleave 支持性一致
2.5、onscroll / onwheel
onwheel 事件在鼠标滚轮在元素上下滚动时触发,必须滚轮要转,至于页面滚不滚动,它不关心。
onscroll 事件在元素滚动条在滚动时触发,必须滚动条存在且上下运动。
触发方式有:滚轮滚动,鼠标按住滚动条拖动,键盘上下键滚动,js 脚本去滚动如 scrollTo,scrollBy,scrollByLines, scrollByPages 等。
在这里有个特殊,在手机端,虽然没有鼠标,但是手指触摸上下滚动,也是触发 onscroll 的。
什么? 支持率这么一点点? 大大出乎我的意料
2.6、copy 事件/cut 事件/ paste 事件
window 的复制/剪切, 粘贴事件。
window.addEventListener("copy", function (e) {
//将复制的数据,存入到剪切板中
e.clipboardData.setData("abc", "Hello, world!");
e.preventDefault();
});
window.addEventListener("paste", function (e) {
//再从剪切板中取出数据
let data = e.clipboardData.getData("abc");
e.preventDefault();
});
这三个事件支持性一致
2.7、error 事件
当资源加载失败或无法使用时,会在 Window 对象触发 error 事件。例如:script 执行时报错。
window.addEventListener('error', (event) => {
});
2.8、orientationchange 事件
orientationchange 事件在设备的纵横方向改变时触发。
window.addEventListener("orientationchange", function() {
});
pc 上几乎都不支持,这也能理解,毕竟 pc 上是使用 resize 的,只有手机才会使用 横竖屏。
2.9、rejectionhandled 事件 / unhandledrejection 事
当 Promise 被 rejected 且有 rejection 处理器时会在全局触发 rejectionhandled。
当 Promise 被 reject 且没有 reject 处理器的时候,会触发 unhandledrejection 事件;
window.addEventListener("rejectionhandled", event => {
}, false);
window.addEventListener("unhandledrejection", event => {
});
function getName() {
return Promise.reject("error");
}
let p = getName(); //触发unhandledrejection
setTimeout(() => {
p.catch((err) => {}); //触发rejectionhandled
}, 1000);
2.10、storage 事件
当 localStorage 被修改时,将触发 storage 事件。
注意:
- 只有在同域名的不同文件之间,才能够监听到,
- 同一个文件中,是监听不到的(合理,同一个文件直接拿就行了,用 storage 监听多此一举)
- 通过 iframe 引入的另一个站点,也可以监听到
2.11、online 事件 / offline 事件
- online 当网络连接时,触发,
- offline 当网络断开时触发
- online 和 offline 支持性一致
本篇未完结,请见下一篇
推荐JavaScript学习相关文章
《学习 jQuery 源码整体架构,打造属于自己的 js 类库》
《Angular v10.0.0 正式发布,不再支持 IE9/10》
《「实践」浏览器中的画中画(Picture-in-Picture)模式及其 API》
《「多图」一文带你彻底搞懂 Web Workers (上)》
《「多图」一文带你彻底搞懂 Web Workers (中)》
《webpack4主流程源码解说以及动手实现一个简单的webpack(上)》
《webpack4主流程源码解说以及动手实现一个简单的webpack(下)》
《前后端全部用 JS 开发是什么体验(Hybrid + Egg.js经验分享)上》
《前后端全部用 JS 开发是什么体验(Hybrid + Egg.js经验分享)中》
《前后端全部用 JS 开发是什么体验(Hybrid + Egg.js经验分享)下》
《一文带你搞懂 babel-plugin-import 插件(上)「源码解析」》
《一文带你搞懂 babel-plugin-import 插件(下)「源码解析」》
《教你如何使用内联框架元素 IFrames 的沙箱属性提高安全性?》
《细说DOM API中append和appendChild的三个不同点》
《NodeX Component – 滴滴集团 Node.js 生态组件体系「实践」》
《浅谈浏览器架构、单线程js、事件循环、消息队列、宏任务和微任务》
《了不起的 Webpack HMR 学习指南(上)「含源码讲解」》
《了不起的 Webpack HMR 学习指南(下)「含源码讲解」》
《图解 Promise 实现原理(二):Promise 链式调用》
《图解 Promise 实现原理(三):Promise 原型方法实现》
《图解 Promise 实现原理(四):Promise 静态方法实现》
《使用Service Worker让你的 Web 应用如虎添翼(上)「干货」》
《使用Service Worker让你的 Web 应用如虎添翼(中)「干货」》
《使用Service Worker让你的 Web 应用如虎添翼(下)「干货」》
《一个轻量级 JavaScript 全文搜索库,轻松实现站内离线搜索》
《细品269个JavaScript小函数,让你少加班熬夜(一)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(二)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(三)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(四)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(五)「值得收藏」》
《细品269个JavaScript小函数,让你少加班熬夜(六)「值得收藏」》
《手把手教你7个有趣的JavaScript 项目-上「附源码」》
《手把手教你7个有趣的JavaScript 项目-下「附源码」》
《JavaScript 使用 mediaDevices API 访问摄像头自拍》
《一文彻底搞懂JavaScript 中Object.freeze与Object.seal的用法》
《可视化的 JS:动态图演示 – 事件循环 Event Loop的过程》
《可视化的 js:动态图演示 Promises & Async/Await 的过程》
《Pug 3.0.0正式发布,不再支持 Node.js 6/8》
《通过发布/订阅的设计模式搞懂 Node.js 核心模块 Events》
《「速围」Node.js V14.3.0 发布支持顶级 Await 和 REPL 增强功能》
《JavaScript 已进入第三个时代,未来将何去何从?》
《前端上传前预览文件 image、text、json、video、audio「实践」》
《深入细品 EventLoop 和浏览器渲染、帧动画、空闲回调的关系》
《推荐13个有用的JavaScript数组技巧「值得收藏」》
《36个工作中常用的JavaScript函数片段「值得收藏」》
《一文了解文件上传全过程(1.8w字深度解析)「前端进阶必备」》
《手把手教你如何编写一个前端图片压缩、方向纠正、预览、上传插件》
《JavaScript正则深入以及10个非常有意思的正则实战》
《前端开发规范:命名规范、html规范、css规范、js规范》
《100个原生JavaScript代码片段知识点详细汇总【实践】》
《手把手教你深入巩固JavaScript知识体系【思维导图】》
《一个合格的中级前端工程师需要掌握的 28 个 JavaScript 技巧》
《身份证号码的正则表达式及验证详解(JavaScript,Regex)》
《127个常用的JS代码片段,每段代码花30秒就能看懂-【上】》
《深入浅出讲解JS中this/apply/call/bind巧妙用法【实践】》
《干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)》
《面试中教你绕过关于 JavaScript 作用域的 5 个坑》
作者:寒水寺一禅
转发链接:https://segmentfault.com/a/1190000023111128
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/10357.html