web开发过程中为了更好的实现元素自适应效果,往往需要监听DIV的尺寸变化。而DIV元素不像window对象,是没有resize事件的,我们无法直接监听DIV的resize事件。因此在需要对DIV元素进行监听时,需要采用一些特定方法完成size的监听。
由于iframe元素包含一个window对象,我们可以在要监听的div元素上嵌入一个iframe元素,使其高度和宽度设置为100%,将DIV元素撑满,当DIV尺寸变化时,iframe也会随之变化,我们可以通过监听iframe的resize事件完成间接对DIV元素尺寸变化的监听。
由此思路编辑js文件如下:
- (function () {
- var self = this;
- /**
- * 元素尺寸构造函数
- * @param {Object} el 监听元素选择器
- */
- function ElementResize(eleSelector) {
- if (!(this instanceof ElementResize)) return;
- if (!eleSelector) return;
- this.eleSelector = eleSelector;
- this.el = document.querySelector(eleSelector);
- this.queue = [];
- this.__init(); //globel init
- }
-
- /**
- * 初始化对象,创建iframe并绑定其window的resize
- *
- */
- ElementResize.prototype.__init = function () {
- var iframe = this.crateIElement();
- this.el.style.position = "relative";
- this.el.appendChild(iframe);
- this.bindEvent(iframe.contentWindow);
- };
-
- /**
- * 设置元素样式
- * @param {HTMLObject} el
- * @param {Object} styleJson
- */
- ElementResize.prototype.setStyle = function (el, styleJson) {
- if (!el) return;
- styleJson = styleJson || {
- opacity: 0,
- position: "absolute",
- left: 0,
- top: 0,
- width: "100%",
- height: "100%",
- "z-index": "-999",
- };
- var styleText = "";
- for (key in styleJson) {
- styleText += key + ":" + styleJson[key] + ";";
- }
- el.style.cssText = styleText;
- };
-
- /**
- * 创建元素
- * @param {Object} style
- */
- ElementResize.prototype.crateIElement = function (style) {
- var iframe = document.createElement("iframe");
- this.setStyle(iframe);
- return iframe;
- };
-
- /**
- * 绑定事件
- * @param {Object} el
- */
- ElementResize.prototype.bindEvent = function (el) {
- if (!el) return;
- var _self = this;
- el.addEventListener("resize", function () {
- _self.runQueue();
- },
- false
- );
- };
-
- /**
- * 运行队列
- */
- ElementResize.prototype.runQueue = function () {
- var queue = this.queue;
- for (var i = 0; i < queue.length; i++) {
- typeof queue[i] === "function" && queue[i].apply(this);
- }
- };
-
- /**
- * 监听
- * @param {Object} cb 回调函数
- */
- ElementResize.prototype.listen = function (cb) {
- if (typeof cb !== "function")
- throw new TypeError("cb is not a function!");
- this.queue.push(cb);
- };
- /**
- * 解除监听
- *
- */
- ElementResize.prototype.unListen = function () {
- this.queue = [];
- };
-
- self.ElementResize = ElementResize;
- })();
该文件构建了一个ElementResize构造方法,通过实例化该构造方法创建出监听实例,将该文件引入文件,使用方法如下:
- html>
- <html>
- <head>
- <meta charset="utf-8" />
- <title>DIV尺寸监听title>
- <script src="./divResizeObserver.js">script>
- head>
- <body>
- <button onclick="listenResize()">监听变化button>
- <button onclick="unListenResize()">解除监听button>
- <button onclick="changeSize()">改变尺寸button>
- <div id="content">
- div尺寸变更监听
- div>
- <script type="text/javascript">
- var eleResize = new ElementResize("#content");
- //执行监听
- function listenResize(){
- eleResize.listen(function () {
- console.count("listener1触发");
- });
- eleResize.listen(function () {
- console.count('listener2触发');
- });
- }
- //监听调用
- listenResize();
-
- //解除监听
- function unListenResize(){
- eleResize.unListen();
- }
- //宽高变化
- function changeSize(){
- var el = document.querySelector("#content");
- el.style.width = Math.floor(Math.random() * 900) + "px";
- el.style.height = Math.floor(Math.random() * 500) + "px";
- }
- script>
- <style type="text/css">
- #content {
- background:blue;
- max-width: 100%;
- max-height: 100%;
- overflow: auto;
- text-align:center;
- }
- html,
- body {
- height: 100%;
- width: 100%;
- margin:0;
- }
- style>
- body>
- html>
效果如下:

ResizeObserver 接口可以监听到 Element 的内容区域或 SVGElement的边界框改变。
该对象提供三种方法:
取消和结束目标对象上所有对 Element或 SVGElement 观察。
ResizeObserver.observe()
https://developer.mozilla.org/zh-CN/docs/Web/API/ResizeObserver/observe
开始观察指定的 Element或 SVGElement。
ResizeObserver.unobserve()
https://developer.mozilla.org/zh-CN/docs/Web/API/ResizeObserver/unobserve
结束观察指定的Element或 SVGElement。
使用方式也很简单:
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Documenttitle>
- head>
- <body>
- <button onclick="change()">更改button>
- <div id="test" class="test" >
-
- div>
- <script>
- function change(){
- let el = document.querySelector('#test');
- // el.style.width =Math.floor(Math.random()* 1000) + 'px';
- el.style.height =Math.floor(Math.random() * 1000 ) + 'px';
- }
- window.onload = function(){
- // 尺寸监听
- const resizeObserver = new ResizeObserver(entries => {
- console.count("resize变化啦");
- });
- const someEl = document.querySelector('#test');
- resizeObserver.observe(someEl);
-
- }
- script>
-
- <style>
- .test{
- width:100%;
- height:100%;
- min-height:100px;
- background:red
- }
- style>
- body>
- html>
效果:

该对象的方法使用非常方便,缺点是浏览器兼容性不好:

那是不是就不能使用了呢,我们可以使用一个github上的ResizeObserver Polyfill。
安装:
npm install resize-observer-polyfill --save-dev
使用方式:
-
-
- import ResizeObserver from 'resize-observer-polyfill';
-
- const ro = new ResizeObserver((entries, observer) => {
- for (const entry of entries) {
- const {left, top, width, height} = entry.contentRect;
-
- console.log('Element:', entry.target);
- console.log(`Element's size: ${ width }px x ${ height }px`);
- console.log(`Element's paddings: ${ top }px ; ${ left }px`);
- }
- });
-
- ro.observe(document.body);
最后,更多内容欢迎小伙伴关注:
