监听DIV元素尺寸变化
web开发过程中为了更好的实现元素自适应效果,往往需要监听DIV的尺寸变化。而DIV元素不像window对象,是没有resize事件的,我们无法直接监听DIV的resize事件。因此在需要对DIV元素进行监听时,需要采用一些特定方法完成size的监听。...
web开发过程中为了更好的实现元素自适应效果,往往需要监听DIV的尺寸变化。而DIV元素不像window对象,是没有resize事件的,我们无法直接监听DIV的resize事件。因此在需要对DIV元素进行监听时,需要采用一些特定方法完成size的监听。
方法1: 嵌入iframe方案
由于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构造方法,通过实例化该构造方法创建出监听实例,将该文件引入文件,使用方法如下:
<!DOCTYPE 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>
效果如下:
方案2 ResizeObserver
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。
使用方式也很简单:
<!DOCTYPE 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>Document</title>
</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);
最后,更多内容欢迎小伙伴关注:
更多推荐
所有评论(0)