Motivation

响应式网站/Web应用程序 根据视口大小调整内容展示方式。这通常通过CSS和media查询来完成。当CSS表现不好我们会使用Javascript。

比如document.addEventListener("resize",fun)或者Element的onresize属性。通过监听window.resize事件,Javascript DOM操作与视口大小保持同步。

但你会意识到,这甚至不包括在窗口未被调整大小但元素改变其大小的情况。例如,添加新的子元素,设置元素的display样式none或类似的操作会改变元素,其兄弟或祖先的大小。

随着响应式Web应用程序的普及,对响应式组件的需求也会增加。这些组件也需要有对resize事件做出响应。不幸的是,Web平台目前不提供组件跟踪其大小的方法。

Current workarounds

一些应用程序实施自制的调整大小通知框架(例如:Polymer)。这种方法容易出错,难以维护,并且需要每个组件都实施自制方法。

其他人巧妙的通过可以代替调整事件的事件来调整内容(例如:<a href="https://github.com/wnr/element-resize-detector">element-resize-detector</a>)。目前最优秀的方法都使用类似的技巧:

在组件中插入一个绝对定位的子项,并且以发出滚动事件的方式制作子项,或者在父项大小更改时制作window.resize。

绝对定位的子项方法在ShadowDOM或React等框架中不起作用。

这些方法都不可取。它们在正确性,代码复杂性和性能方面都失败了。

在当今的Web平台上无法复制ResizeObserver功能。

这就是为什么ResizeObserver是一个有用的原始API。它对任何观察到的元素的大小的变化作出反应,与导致变化的原因无关。它还为您提供访问观察元素的新大小。

API

提到的“Observer”后缀的API共享一个简单的API设计。ResizeObserver也不例外。

您创建一个ResizeObserver 对象并将回调传递给构造函数。回调将被赋予一个数组ResizeOberverEntries- 每个观察元素一个条目 - 包含元素的大小

var ro = new ResizeObserver( entries =>{for(let entry of entries) {
const cr=entry.contentRect;
console.log('Element:', entry.target);
console.log(`Element size: ${cr.width}px x ${cr.height}px`);
console.log(`Element padding: ${cr.top}px ; ${cr.left}px`);
}
});//Observe one or multiple elements
ro.observe(someElement);

Usage examples

以下是使用ResizeObserver在画布内绘制椭圆的示例。

<canvas style="width:10%;height:10%"></canvas>
<canvas style="width:20%;height:20%"></canvas>
functiondrawEllipse(entry) {
let ctx= entry.target.getContext('2d');
let rx= Math.floor(entry.contentRect.width / 2);
let ry= Math.floor(entry.contentRect.height / 2);
ctx.beginPath();
ctx.clearRect(0,0, entry.contentRect.width,entry.contentRect.height);
ctx.ellipse(rx, ry, rx, ry,0, 0, 2 *Math.PI);
ctx.stroke();
}//ResizeObserver delegates action to Element's handleResize method
let ro = new ResizeObserver( entries =>{for(let entry of entries) {if(entry.target.handleResize)
entry.target.handleResize(entry);
}
});//Set up observations
var canvases = document.querySelectorAll('canvas');for(let canvas of canvases) {
canvas.handleResize=drawEllipse;
ro.observe(canvas);
}

内联框架可以检测其大小何时发生变化,并通知父窗口。

let ro = new ResizeObserver(entries =>{
let idealSize=computeIdealSize();
window.parent.postMessage({
name:"iframeResize",
width: idealSize.width,
height: idealSize.height
},'*');
});
ro.observe(document.body);

当新消息到达时,我们如何让聊天窗口滚动到底部?ResizeObserver解决方案将所有消息保存在不断增长的中div,并观察其大小。当新消息到达时,滚动到底部。
完整的例子 详细讨论了用户滚动的处理。

.chat {
overflow: scroll;
}<div class="chat"> <!-- chat has the scrollbar -->
<div class="chat-text"> <!-- chat-text contains chat text -->
<div>jack: hi </div>
<div>jill: hi </div>
</div>
</div
let ro = new ResizeObserver( entries =>{for(let e of entries) {
let chat=e.target.parentNode;
chat.scrollTop= chat.scrollHeight -chat.clientHeight;
}
});
ro.observe(document.querySelector('.chat-text'))

How

Performance

调整通知的大小可以有很高的频率。Observer API避免了事件捕获/泡泡的开销。

框架作者可以在ResizeObserver之上提供一个开发友好的“基于事件”的API,以避免注册太多的观察者。

Notice

通知传送顺序

当多个ResizeObservers注册时,通知应按注册顺序传送。

回调变更集应按注册顺序列出元素。

内联元素

内联元素不应该生成调整大小通知。

怎么样变换?

转换不会影响内容大小。他们不应该触发通知。

动画怎么样?

影响内容大小的动画应该会触发通知。

如果工作成本很高,开发人员可能会希望在动画期间跳过工作。

调整大小和可视性

当元素不可见时,内容大小变为0。这将生成一个调整大小的通知。开发人员将能够使用ResizeObserver观察可见性。

本文参考:

ResizeObserver: It’s Like document.onresize for Elements ----- https://developers.google.com/web/updates/2016/10/resizeobserver

WICG/ResizeObserver ----- https://github.com/WICG/ResizeObserver/blob/master/explainer.md

转载于:https://www.cnblogs.com/CrossGod/p/ResizeObserver.html

ResizeObserver - 元素resize监听API相关推荐

  1. [react] 组件卸载前,加在DOM元素的监听事件和定时器要不要手动清除?为什么?

    [react] 组件卸载前,加在DOM元素的监听事件和定时器要不要手动清除?为什么? 定时器要在 componentWillUnmount 手动清除,直接绑定在JSX里的事件监听器不用,使用ref绑定 ...

  2. waypoint+animate元素滚动监听触发插件实现页面动画效果

    最近在做一个官网类型滚动加载动画,使用到waypoint监听事件插件和animate动画样式,两者结合完美实现向下滚动加载动画,但是没有做向上滚动撤消动画,留待以后有空研究 首先来介绍下jquery. ...

  3. 原生js未来元素事件监听的写法

    绑定事件的另一种方法是用 addEventListener() 或 attachEvent() 来绑定事件监听函数. addEventListener()函数语法: elementObject.add ...

  4. js原生给生成的html添加点击事件,原生js为动态元素添加监听事件

    //已存在div //创建标签 function createpage(){ var span=document.createElement('span') span.innerHTML=" ...

  5. jquery控制只监听数字_JQuery通过一个开关来控制某个元素的监听

    控制其它元素的事件,或者执行其它JS代码,都是写在do other something的后面啊,下面是一个简单的例子 test .hideText{display:none;} 你好 $(docume ...

  6. Vue + Element UI——监听DOM元素高度和宽度解决方案整理(八种方法)

    问题描述 监听DOM元素大小的变化,在前端开发中,算是一个比较常见的需求,比如我们要制作可伸缩的图表的时候,可能需要根据DOM大小的变化,进行动态的更新图表. 解决方案 方法一: 监听window变化 ...

  7. Vue——全局element-resize-detector监听DOM元素

    解决方案 第一步:通过npm install element-resize-detector获取elementResizeDetectorMaker npm install element-resiz ...

  8. JavaScript 技术篇-通过代码获取dom元素绑定的监听事件,chrome浏览器查看js元素绑定的监听事件

    > var a = document.querySelector("#su"); < undefined > getEventListeners(a); < ...

  9. 【冷知识】获取网页所有的监听事件类型、方法。请认准getEventListeners

    获取事件列表 getEventListeners(window)//获取window绑定的所有监听事件列表//----------------------------------------getEv ...

最新文章

  1. java 捕获数据包,缓存从pcap捕获的数据包
  2. elasticJob分片跑批
  3. 18 个 Java8 日期处理的实践,太有用了!
  4. java 乐观锁 实例_JAVA乐观锁实现-CAS(示例代码)
  5. html5/css3响应式页面开发总结
  6. hadoop join之semi join
  7. uni app 录音结束监听_全新重构,uni-app实现微信端性能翻倍
  8. LintCode 28. 搜索二维矩阵
  9. HoloLens 2开发:使用Gaze开发,视线小球不停向眼端移动
  10. 挑战程序设计竞赛 练习日记
  11. 图像处理的alpha通道(RGBA图像)
  12. android极光推送tag,Android极光推送设置别名和标签
  13. 【Unity】Jay 开发日志(三)——道具效果的实现(上)
  14. Android新闻公告切换效果(上下滚动左右滚动)
  15. 万物互联时代到来,锐捷发布场景化无线零漫游方案
  16. error C2679: binary ‘<<‘ : no operator defined which takes a right-hand operand of type ‘class s
  17. 万维网服务器如何发送文档,服务器配置和管理教学讲义(39页)-原创力文档
  18. html实现爱情浪漫表白甜蜜时刻(附源码)
  19. 2022秋招蚂蚁金服面试
  20. 不依赖任何库打造属于自己的可视化数据地图

热门文章

  1. vertrigoserv mysql 密码_VertrigoServ
  2. Java基础:正则表达式
  3. Springboot工程下使用mybatis反向工程
  4. 调整表格的行高_Word表格无法调整行高?尽然是这个原因,90%的人都可能遇到...
  5. 计算同比 环比_PowerBI学习教程(三)时间累积同比环比计算
  6. 计算机windows8黑屏怎么办,老司机为你解说win8系统电脑黑屏开不了机的处理办法...
  7. php7与php5的区别,PHP7和PHP5区别
  8. Python基础之循环语句
  9. qtextedit改变单个字的颜色_发协广告~迷你字
  10. .NET Core2.1下采用EFCore比较原生IOC、AspectCore、AutoFac之间的性能