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>
function drawEllipse(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

ResizeObserver - 元素resize监听API ResizeObserver的更多相关文章

  1. ResizeObserver - 元素resize监听API

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

  2. resize监听div的size变化

    具体实现分两类, ie9-10 默认支持div的resize事件,可以直接通过div.attachEvent('onresize', handler);的方式实现 其它浏览器 通过在div中添加一个内 ...

  3. Fullscreen API与DOM监听API

    前言 以下几个API,在web开发中可以简化我们一部分交互操作. Fullscreen API 有时候我们想要全屏预览的效果,比如类似于图片预览.幻灯片播放等.全屏API是一个很好的选择. 基本用法 ...

  4. jquery对append进的元素的监听操作

    通常append是再页面加载完之后才加入进去的,此时使用click方法是没有效果的,应使用document.on来实现对元素的监听. 例: $(document).on("click&quo ...

  5. avalon子孙元素属性监听

    HTML正文: <body ms-controller="ex"> <div class="ms-hover" ms-click=" ...

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

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

  7. JQuery未来元素事件监听写法

    $(document).on('click','.div1',function(){ alert("abc"); }); 格式一致,第一个参数写事件,第二个参数给谁写事件(选择器) ...

  8. html 子元素和父元素都监听了 click 事件,点击子元素时为何先触发的是父元素的 click 事件?

    先上一段代码,点击子元素时先触发的是父元素的 click 事件 <html> <head> <script type="text/javascript" ...

  9. jquery resize监听dom

    添加如下代码即可(function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j=& ...

随机推荐

  1. 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_02-用户认证-认证服务查询数据库-需求分析&搭建环境

    1.2 认证服务查询数据库 1.2.1 需求分析 认证服务根据数据库中的用户信息去校验用户的身份,即校验账号和密码是否匹配. 认证服务不直接连接数据库,而是通过用户中心服务去查询用户中心数据库. 完整 ...

  2. 【418】C语言ADT实现Quack(stack+queue)

    quack.h #include <stdio.h> #include <stdlib.h> #include <assert.h> typedef struct ...

  3. 使用弹窗批量修改数据POPUP_GET_VALUES

    转自:https://blog.csdn.net/huanglin6/article/details/81231215 业务场景:在SAP内,有时候需要用户批量维护某些数据,这时候可以使用标准函数PO ...

  4. java8中计算两个日期时间LocalDateTime的时间差,格式化成xx年yy月zz日aa时bb分cc秒

    原则上应该适用Period来计算,因为他是专门为这种需求设计的.当时他只能计算到两个时间差的,年月日 传入参数Period.between(LocalDate,LocalDate) 这里是计算两个Lo ...

  5. springboot Thymeleaf中格式化jsr310新日期时间类(LocalDateTime,LocalDate)--thymeleaf格式化LocalDateTime,LocalDate等JDK8新时间类

    依赖maven包 <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>th ...

  6. 【c# 学习笔记】使用virtual和override关键字实现方法重写

    只有基类成员声明为virtual或abstract时,才能被派生类重写:而如果子类想改变虚方法的实现行为,则必须使用override关键字. public class Animal { private ...

  7. dropout含义与原理

    含义 在训练过程中,对神经网络单元按照一定比例暂时将其丢弃. 原理 由于网络参数过多,训练数据少,或者训练次数过多,会产生过拟合的现象.dropout产生的一个重大原因就是为了避免过拟合. 每一层的神 ...

  8. 【C/C++开发】ffplay中的FrameQueue的自我理解

    最近在研究ffplay,以下是本人今天在研究FrameQueue的时候整理的笔记,如有错误还请有心人指出来~ //这个队列是一个循环队列,windex是指其中的首元素,rindex是指其中的尾部元素. ...

  9. 【C/C++开发】运算符重载二

    C++中预定义的运算符的操作对象只能是基本数据类型.但实际上,对于许多用户自定义类型(例如类),也需要类似的运算操作.这时就必须在C++中重新定义这些运算符,赋予已有运算符新的功能,使它能够用于特定类 ...

  10. JPEG2000开发SDK及其特点

    JPEG2000开发SDK及其特点 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:JPEG2000被开发来取代JPEG,但因为大量核心算法被专利注册, ...