JS监听窗口变化和元素变化

2019-10-12 admin

resize事件

简介

可用来监听window对象的变化

应用:根据窗口改变rem

// 基准大小
const baseSize = 41.4;
// 设置 rem 函数
function setRem(width) {
  // 当前页面宽度相对于 414 宽的缩放比例,可根据自己需要修改。
  const scale = width / 414;
  // 设置页面根节点字体大小
  document.documentElement.style.fontSize = baseSize * Math.min(scale, 2) + 'px';
}
window.addEventListener('resize', debounce(setRem));

需要注意的是resize是高频事件,可使用debounce防止多次触发

MutationObserver

简介

  • MutationObserver(callback)为构造函数,可用于实例化监听DOM节点变化的观察器

  • 出自DOM3规范

  • 实例对象拥有三个方法:

    • observe(element, options)开始观察节点,发生变化时触发回调(先放到消息队列里
    • disconnect()停止观察器,直到再次调用observe()
    • takeRecords()将消息队列里未处理的变化通知全部删除并返回

详细参考MDN:MutationObserver

使用

<!DOCTYPE html>
<html>
<head>
    <title>Mutation Observer</title>
    <style type="text/css">
        .box {
            width: 100px;
            height: 100px;
            background-color: red;
        }

        .child{
            width: 50px;
            height: 50px;
            background-color: blue;
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="child"></div>
    </div>

    <script type="text/javascript">
        const { log } = console;

        let MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;

        // box观察器的回调
        let boxCallback = (mutationList) => {
            log('box callback is called');
            for (let mutation of mutationList) {
                log(mutation);
                log(mutation.target);
                log('oldValue: ' + mutation.oldValue);
                log('');
            }
        };

        // 用于text观察器的回调
        let textCallback = (mutationList) => {
            log('text callback is called');
            for (let mutation of mutationList) {
                log(mutation);
                log(mutation.target);
                log('oldValue: ' + mutation.oldValue);
                log('');
            }
        };

        // 用于处理takeRecords()接收到的变化
        let takeRecordsCallback = (mutationList) => {
            log('take records callback is called');
            for (let mutation of mutationList) {
                log(mutation);
                log(mutation.target);
                log('oldValue: ' + mutation.oldValue);
                log('');
            }
        };

        let observer_box = new MutationObserver(boxCallback); // 此回调是异步的

        let observer_text = new MutationObserver(textCallback);

        let box = document.querySelector('.box');
        observer_box.observe(box, {
            childList: true,
            attributes: true,
            subtree: true,
            attributeFilter: ['style'],
            attributeOldValue: true // 开启后oldValue会记录变化,初始为null
        });

        box.style.width = '200px'; // MutationRecord {type: "attributes", oldValue: null, ...}
        box.style.width = '400px'; // MutationRecord {type: "attributes", oldValue: "width: 200px;", ...}

        box.appendChild(document.createElement('div')); // MutationRecord {type: "childList", oldValue: null, ...}

        let child = document.querySelector('.child');

        child.style.width = '100px'; // MutationRecord {type: "attributes", oldValue: null, ...}
        child.style.width = '200px'; // MutationRecord {type: "attributes", oldValue: "width: 100px;", ...}

        var mutations = observer_box.takeRecords(); // 将上面的MutationRecord都获取了,由于callback都是异步的,故上面的的callback未执行

        if (mutations) {
              takeRecordsCallback(mutations);
        }

        // log('observer_box will disconnect')
        // observer_box.disconnect();

        setTimeout(() => {
            log('observer_box will disconnect')
            observer_box.disconnect();
        }, 0);

        let textNode = document.createTextNode('1');
        child.appendChild(textNode); // MutationRecord {type: "childList", target: div.child, ...}

        // characterData需要用在text或comment元素才有效果
        observer_text.observe(textNode, {
            characterData: true,
            characterDataOldValue: true // oldValue初始为text的值
        });

        textNode.appendData('2'); // MutationRecord {type: "characterData", target: text, oldValue: "1"}
        textNode.appendData('3'); // MutationRecord {type: "characterData", target: text, oldValue: "12"}

    </script>
</body>
</html>

需要注意的是:

  • MutationObserver接受的callback执行是异步的,元素更变一般是同步代码,更变后callback会放入消息queue,等待当前一轮事件循环的结束才会执行
  • takeRecords()不是异步的,故可以取到当前在消息queue的元素变化
  • characterData参数只有在元素是textcomment类型时才有效果

参考

[转载]原文链接:https://segmentfault.com/a/1190000020658855

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-77201.html

文章标题:JS监听窗口变化和元素变化

相关文章
Node.js 2014这一年发生了什么
Node.js 的 2014 年充满了不幸和争议. 这一年 Noder 们经历了太多的伤心事, 经历了漫长的等待, 经历了沉重的分裂之痛. 也许 Noder 们不想回忆14年 Node.js land 发生的事情, 但正因为痛才更有铭记的价...
2015-11-12
JavaScript实现PC手机端和嵌入式滑动拼图验证码三种效果
PC和手机端网站滑动拼图验证码效果源码,同时包涵了弹出式Demo,使用ajax形式提交二次验证码所需的验证结果值,嵌入式Demo,使用表单形式提交二次验证所需的验证结果值,移动端手动实现弹出式Demo三种效果 首先要确认前端使用页面,比如...
2017-03-17
Vue获取DOM元素样式和样式更改示例
在 vue 中用 document 获取 dom 节点进行节点样式更改的时候有可能会出现 ‘style’ is not definde的错误,这时候可以在 mounted 里用 $refs 来获取样式,并进行更改: &lt;template...
2017-03-13
Vue.js组件tab实现选项卡切换
本文实例为大家分享了vue插件tab选项卡的具体代码,供大家参考,具体内容如下 效果图: 代码如下: &lt;!DOCTYPE html&gt; &lt;html lang=&quot;en&quot;&gt; &lt;head&gt; ...
2017-03-13
jsdom 中文文档(纯翻译)
jsdom是一个纯粹由 javascript 实现的一系列 web标准,特别是 WHATWG 组织制定的DOM和 HTML 标准,用于在 nodejs 中使用。大体上来说,该项目的目标是模拟足够的Web浏览器子集,以便用于测试和挖掘真实世界...
2018-05-14
React.js编程思想
JavaScript框架层出不穷,在很多程序员看来,React.js是创建大型、快速的Web应用的最好方式。这一款由Facebook出品的JS框架,无论是在Facebook还是在Instagram中,它的表现都非常出色。 使用React.j...
2015-11-12
从2014年的发展来展望JS的未来将会如何
&lt;font face=&quot;寰�杞�闆呴粦, Arial, sans-serif &quot;&gt;2014骞达紝杞�浠惰�屼笟鍙戝睍杩呴€燂紝鍚勭�嶈��瑷€灞傚嚭涓嶇┓锛屼互婊¤冻鐢ㄦ埛涓嶆柇鍙樺寲鐨勯渶姹傘€傝繖浜涜��...
2015-11-12
three.js实现围绕某物体旋转
话不多说,请看代码: 可以拖动右上角观察变化 &lt;!DOCTYPE html&gt; &lt;html lang=&quot;en&quot; style=&quot;width: 100%; height:100%;&quot;&gt...
2017-02-17
JavaScript教程:JS中的原型
Keith Peters 几年前发表的一篇博文,关于学习没有“new”的世界,其中解释了使用原型继承代替构造函数。两者都是纯粹的原型编码。 标准方法(The Standard Way) 一直以来,我们学习的在 JavaScript 里创建对...
2015-11-12
JS中的语音合成——Speech Synthesis API
JS中的语音合成——Speech Synthesis API 简介 HTML5中和Web Speech相关的API实际上有两类,一类是“语音识别(Speech Recognition)”,另外一个就是“语音合成(Speech Synthes...
2018-05-17
回到顶部