MutationObserverMutationObserver is an interface that can monitor changes in DOM structure. MutationObserver will be notified when any changes occur in the DOM object tree. APIMutationObserver is a constructor that accepts a callback parameter, which is used to handle the callback function of node changes and returns two parameters: The MutationObserver object has three methods, as follows: //Select a node to be observed var targetNode = document.getElementById('root') // Set observer configuration options var config = { attributes: true, childList: true, subtree: true } // Function to be executed when a node changes var callback = function (mutationsList, observer) { for (var mutation of mutationsList) { if (mutation.type == 'childList') { console.log('A child node has been added or removed.') } else if (mutation.type == 'attributes') { console.log('The ' + mutation.attributeName + ' attribute was modified.') } } } // Create an observer instance and associate it with the callback function var observer = new MutationObserver(callback) //Use the configuration file to observe the target node observer.observe(targetNode, config) // Stop observing observer.disconnect() The options parameter in the observe method has the following options: FeaturesMutationObserver has the following features:
When the DOM changes, the MutationObserver event is triggered. However, it is essentially different from events: events are triggered synchronously, that is, DOM changes will immediately trigger the corresponding events; MutationObserver is triggered asynchronously, and it will not be triggered immediately after the DOM changes, but will be triggered after all current DOM operations are completed. For example, if you insert 1000 paragraphs (p elements) into a document continuously, 1000 insertion events will be triggered continuously, and the callback function of each event will be executed, which is likely to cause browser lag. MutationObserver is completely different. It will only be triggered after all 1000 paragraphs have been inserted, and it will only be triggered once. This reduces frequent changes to the DOM and greatly benefits performance. IntersectionObserverWhen developing web pages, you often need to know whether an element has entered the "viewport", that is, whether the user can see it. The traditional implementation method is to listen to the scroll event, call the getBoundingClientRect() method of the target element, obtain its coordinates corresponding to the upper left corner of the viewport, and then determine whether it is within the viewport. The disadvantage of this method is that due to the intensive occurrence of scroll events, the amount of calculation is large, which can easily cause performance problems. There is a new IntersectionObserver API that can automatically "observe" whether an element is visible, which is supported by Chrome 51+. Since the essence of visible is that the target element and the viewport produce an intersection area, this API is called "intersection observer". APIIntersectionObserver is a constructor provided by the browser natively. It accepts two parameters: callback is the callback function when visibility changes, and option is a configuration object (this parameter is optional). var io = new IntersectionObserver(callback, option) // Start observing io.observe(document.getElementById('example')) // Stop observing io.unobserve(element) // Close the observer io.disconnect() If you want to observe multiple nodes, you need to call this method multiple times. io.observe(elementA) io.observe(elementB) When the visibility of the target element changes, the observer's callback function is called. The callback is usually triggered twice. Once when the target element just enters the viewport (begins to be visible), and once when it completely leaves the viewport (begins to be invisible). var io = new IntersectionObserver((entries) => { console.log(entries) }) The callback function's parameter (entries) is an array, each member of which is an IntersectionObserverEntry object. For example, if the visibility of two observed objects changes at the same time, the entries array will have two members. For example<html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> <style> #div1 { position: sticky; top: 0; height: 50px; line-height: 50px; text-align: center; background: black; color: #ffffff; font-size: 18px; } </style> </head> <body> <div id="div1">Home</div> <div style="height: 1000px;"></div> <div id="div2" style="height: 100px; background: red;"></div> <script> var div2 = document.getElementById('div2') let observer = new IntersectionObserver( function (entries) { entries.forEach(function (element, index) { console.log(element) if (element.isIntersecting) { div1.innerText = 'I'm out' } else { div1.innerText = 'Homepage' } }) }, { root: null, threshold: [0, 1] } ) observer.observe(div2) </script> </body> </html> Compared with getBoundingClientRect, its advantage is that it will not cause redrawing and reflow. Lazy loading of imagesThe principle of lazy loading of images is mainly realized by the core logic of judging whether the current image has reached the visible area. This saves bandwidth and improves web page performance. Traditional breakthrough lazy loading is achieved by listening to scroll events, but scroll events will be triggered many times in a short period of time, seriously affecting page performance. To improve page performance, we can use IntersectionObserver to implement lazy loading of images. const imgs = document.querySelectorAll('img[data-src]') const config = { rootMargin: '0px', threshold: 0 } let observer = new IntersectionObserver((entries, self) => { entries.forEach((entry) => { if (entry.isIntersecting) { let img = entry.target let src = img.dataset.src if (src) { img.src = src img.removeAttribute('data-src') } // Unobserve self.unobserve(entry.target) } }) }, config) imgs.forEach((image) => { observer.observe(image) }) Infinite ScrollThe implementation of infinite scroll is also simple. var intersectionObserver = new IntersectionObserver(function (entries) { // If it is not visible, return if (entries[0].intersectionRatio <= 0) return loadItems(10) console.log('Loaded new items') }) // Start observing intersectionObserver.observe(document.querySelector('.scrollerFooter')) getComputedStyle() DOM2 Style adds a getComputedStyle() method to APIdocument.defaultView.getComputedStyle(element[,pseudo-element]) // or window.getComputedStyle(element[,pseudo-element]) This method accepts two parameters: the element to get the computed style of and the pseudo-element string (such as ":after"). If no pseudo-element is needed, the second parameter can be null. <!DOCTYPE html> <html> <head> <style type="text/css"> #myDiv { background-color: blue; width: 100px; height: 200px; } </style> </head> <body> <div id="myDiv" style="background-color: red; border: 1px solid black"></div> </body> <script> function getStyleByAttr(obj, name) { return window.getComputedStyle ? window.getComputedStyle(obj, null)[name] : obj.currentStyle[name] } let node = document.getElementById('myDiv') console.log(getStyleByAttr(node, 'backgroundColor')) console.log(getStyleByAttr(node, 'width')) console.log(getStyleByAttr(node, 'height')) console.log(getStyleByAttr(node, 'border')) </script> </html> Similarities and differences with styleThe similarity between getComputedStyle and element.style is that both return CSSStyleDeclaration objects. The difference is: element.style only reads the inline style of the element, that is, the style written in the style attribute of the element; while the style read by getComputedStyle is the final style, including inline style, embedded style and external style. element.style supports both reading and writing. We can rewrite the style of an element through element.style. However, getComputedStyle only supports reading and not writing. We can read the style using getComputedStyle and modify the style using element.style getBoundingClientRectThe getBoundingClientRect() method returns the size of an element and its position relative to the viewport. APIlet DOMRect = object.getBoundingClientRect() Its return value is a DOMRect object, which is a set of rectangles returned by the getClientRects() method of the element, that is, the CSS border size of the element. The result returned is the smallest rectangle that contains the entire element, and has read-only properties of left, top, right, bottom, x, y, width, and height that describe the entire bounding box in pixels. Properties other than width and height are calculated relative to the upper-left corner of the view window. Application Scenario1. Get the distance of the DOM element relative to the upper left corner of the web pageThe previous writing method is to find the element through offsetParent to locate the parent element until it recursively reaches the top-level element body or html. // Get the distance of the DOM element relative to the upper left corner of the web page function offset(el) { var top = 0 var left = 0 do { top += el.offsetTop left += el.offsetLeft } while ((el = el.offsetParent)) // There is a compatibility issue, need to be compatible return { top: top, left: left } } var odiv = document.getElementsByClassName('markdown-body') offset(a[0]) // {top: 271, left: 136} Now according to the getBoundingClientRect API, it can be written like this: var positionX = this.getBoundingClientRect().left + document.documentElement.scrollLeft var positionY = this.getBoundingClientRect().top + document.documentElement.scrollTop 2. Determine whether the element is in the visible areafunction isElView(el) { var top = el.getBoundingClientRect().top // The distance from the top of the element to the top of the visible areavar bottom = el.getBoundingClientRect().bottom // The distance from the bottom of the element to the top of the visible areavar se = document.documentElement.clientHeight // The height of the visible area of the browser. if (top < se && bottom > 0) { return true } else if (top >= se || bottom <= 0) { // Invisible} return false } The above is the detailed content of several API examples commonly used in advanced front-end development of javascript. For more information about advanced front-end API examples, please pay attention to other related articles on 123WORDPRESS.COM! You may also be interested in:
|
<<: Significantly optimize the size of PNG images with CSS mask (recommended)
>>: iFrame is a great way to use it as a popup layer to cover the background
This technique comes from this article - How to a...
I accidentally discovered a great artificial inte...
As an open source software, Apache is one of the ...
Table of contents 1. Connect to Tencent Cloud Ser...
This article uses an example to describe how MySQ...
Preface: The "Getting Started with MySQL&quo...
For example, to query yesterday's newly regis...
Table of contents 1. WordPress deployment 1. Prep...
Table of contents 1. this keyword 2. Custom attri...
Copy code The code is as follows: <html xmlns=...
MySQL is a very powerful relational database. How...
Table of contents Pull the rocketmq image Create ...
Before you begin Have a cloud server, mine is Ten...
Today, when I was installing CentOS6.2, I couldn&...
For those who don't know how to install the s...