技术控

    今日:30| 主题:49448
收藏本版 (1)
最新软件应用技术尽在掌握

[其他] ResizeObserver – It’s like document.onresize for elements

[复制链接]
wqr2rwer 发表于 2016-10-12 17:05:25
217 4

立即注册CoLaBug.com会员,免费获得投稿人的专业资料,享用更多功能,玩转个人品牌!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
AfterMutationObserver,PerformanceObserver andIntersectionObserver, we have another observer for your collection! ResizeObserver allows you to be notified when an element’s content rectangle has changed its size, and react accordingly. The spec is currently being iterated on in the WICG and your feedback is very much welcome.
  Motivation

   previously, you had to attach a listener to the document’s resize event to get notified of any change of the viewport’s dimensions. In the event handler, you would then have to figure out which elements have been affected by that change and call a specific routine to react appropriately. If you need the new dimensions of an element after a resize, you need to call getBoundingClientRect or getComputerStyle , which can cause layout thrashing if you don’t take care of batching all your reads and all your writes.
   And then you realize that this doesn’t even cover the cases where elements change their size without the main window having been resized. For example, appending new children, setting an element’s display style to none , or similar actions can change the size of an element, its siblings or ancestors.
   This is why ResizeObserver is a useful primitive. It reacts to changes in size of any of the observed elements , independent of what caused the change. It provides you access to the new size of the observed elements, too. Let’s get straight into it.
  API

   All the APIs with the “observer” suffix I mentioned above share a simple API design. ResizeObserver is no exception. You create a ResizeObserver object and pass a callback to the constructor. The callback will be given an array of ResizeOberverEntries – one entry per observed element – which contain the new dimensions for the element.
  [code]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);[/code]  Some details

  What is being reported?

   Generally, ResizeObserver reports the content rectangle of an element. The content rectangle is the box in which content can be placed. It is the border box minus the padding.
   
ResizeObserver – It’s like document.onresize for elements-1 (collection,previously,currently,listener,elements)

   It's important to note that while ResizeObserver reports both the dimensions of the contentRect and the padding, it only watches the contentRect . Don't confuse contentRect with the bounding box of the element. The bounding box, as reported by getBoundingClientRect , is the box that contains the entire element and its decendants. SVGs are an exception to the rule, where ResizeObserver will report the dimensions of the bounding box.
  When is it being reported?

   The spec prescribes that ResizeObserver should process all resize events before paint and after layout. This makes the callback of an ResizeObserver the ideal place to make changes to your page’s layout. Because ResizeObserver processing happens between layout and paint, doing so will only invalidate layout, not paint.
  Gotcha

   You might be asking yourself: What happens if I change the size of an observed element inside the ResizeObserver ’s callback? The answer is: You will trigger another call to the callback right away. However, ResizeObserver has a mechanism to avoid infinite callback loops and cyclic dependencies. Changes will only be processed in the same frame if the resized element is deeper in the DOM tree than the shallowest element processed in the previous callback. Otherwise, they’ll get deferred to the next frame.
  Application

   One thing that ResizeObserver allows you to do is to implement per-element media queries. By observing elements, you can imperatively define your design breakpoints and change the element’s styles. In the following example , the second box will change its border radius according to its width.
            [code]const ro = new ResizeObserver(entries => {
  for (let entry of entries) {
    entry.target.style.borderRadius = Math.max(0, 250 - entry.contentRect.width) + 'px';
  }
});
// Only observe the second box
ro.observe(document.querySelector('.box:nth-child(2)'));[/code]  Another interesting example to look at is a chat window. The problem that arises in a typical top-to-bottom conversation layout is scroll positioning. To avoid confusing the user, it is helpful if the window sticks to the bottom of the conversation, where the newest messages will appear. Additionally, any kind of layout change (think of a phone going from landscape to portrait or vice versa) should strive to achieve the same.
   ResizeObserver allows you to write a single piece of code that takes care of both scenarios. Resizing the window is an event that ResizeObservers can capture by very definition, but calling appendChild() will also resize that element (except if overflow: hidden is set), because it needs to make space for the new elements. With this in mind, you can get away with a couple of lines to achieve the desired effect:
            [code]const ro = new ResizeObserver(entries => {
  document.scrollingElement.scrollTop =
    document.scrollingElement.scrollHeight;
});

// Observe the scrollingElement for when the window gets resized
ro.observe(document.scrollingElement);
// Observe the timeline to process new messages
ro.observe(timeline);[/code]  Pretty neat, huh?
   From here, we could add more code to handle the case where the user has scrolled up manually and we want to the scrolling to stick to that message when a new message comes in.
   Another use case is for any kind of custom element that is doing its own layout. Until ResizeObserver , there was no reliable way to get notified when your own dimensions change so you ca re-layout your own children.
  Out now!

   As with a lot of the observer APIs, ResizeObserver is not 100% polyfillable, which is why native implementations are needed. Current polyfill implementations either rely on polling or on adding sentinel elements to the DOM. The former will drain your battery on mobile by keeping the CPU busy while the latter modifies your DOM and might mess up styling and other DOM-reliant code.
   ResizeObserver is in Chrome 55 Canary, behind the Experimental Web Platform flag. It is a small primitive that allows you to write certain effects in a much more efficient way. Try them out and let us know what you think or if you have questions.
友荐云推荐




上一篇:Pure versus impure functions
下一篇:The Long View: Macintosh Common Lisp
酷辣虫提示酷辣虫禁止发表任何与中华人民共和国法律有抵触的内容!所有内容由用户发布,并不代表酷辣虫的观点,酷辣虫无法对用户发布内容真实性提供任何的保证,请自行验证并承担风险与后果。如您有版权、违规等问题,请通过"联系我们"或"违规举报"告知我们处理。

947068972 发表于 2016-10-12 22:09:14
生命中的第一个沙发,激动嘞!
回复 支持 反对

使用道具 举报

vkvln 发表于 2016-10-14 00:36:26
我死了,但是在烈火中我又站起来了,你猜是涅磐,还是尸变?
回复 支持 反对

使用道具 举报

静枫 发表于 2016-10-21 06:29:52
没人回帖。。。我来个吧
回复 支持 反对

使用道具 举报

听枫 发表于 2016-10-24 20:49:24
这次必须是沙发!
回复 支持 反对

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

我要投稿

推荐阅读

扫码访问 @iTTTTT瑞翔 的微博
回页顶回复上一篇下一篇回列表手机版
手机版/CoLaBug.com ( 粤ICP备05003221号 | 文网文[2010]257号 )|网站地图 酷辣虫

© 2001-2016 Comsenz Inc. Design: Dean. DiscuzFans.

返回顶部 返回列表