preface
We don’t have much of a chance to make an appearance in real projects, and some oF the apis we’ve never heard of. Here are some of the few that are out of the window.
Element.classList
Element.classList is a read-only property that returns a real-time DOMTokenList collection of an Element’s class attributes. ClassName is a more convenient way to access an element’s classList than using element.className as a whitespace delimited string. Common apis are as follows:
- Add: Adds the specified class value. If these classes already exist in an element’s attribute, they are ignored.
- Remove: deletes the specified class value.
- Toggle: to switch classes; That is, remove the class if it exists, or add it if it doesn’t.
- Contain: Checks whether the element’s class attribute contains the specified class value
- Replace: Replace an existing class with a new class.
We could manipulate the DOM like this before element. classList didn’t come up
/* Add the class method */
function add(element, className) {
if(!new RegExp("(^|\\s)" + className + "(\\s|$)").test(element.className)) element.className += ' ' + className;
}
/* Remove the class method */
function remove(element, className) {
element.className = element.className.replace(new RegExp("(^|\\s)" + className + "(? =(\\s|$))"."g"), ' ');
}
/* Toggle class methods */
function toggle(element, className) {
if(new RegExp("(^|\\s)" + className + "(\\s|$)").test(element.className)){
element.className = element.className.replace(className,' ')}else{
element.className = element.className.trim() + ' '+ className; }}/* Determine whether a class method */ is included
function contain(element, className) {
return element.className.indexOf(className)>- 1
}
/* Replace the existing class */ with a new class
function replace(element, oldClassName,newClassName) {
element.className = element.className.replace(oldClassName,newClassName)
}
Copy the code
After the appearance of element. classList, we manipulate the DOM like this
- Add a class class to the element
element.classList.add( className )
Copy the code
- Removes a class from the element
element.classList.remove( className )
Copy the code
- Toggles a class on the element
element.classList.toggle( className )
Copy the code
- Determines whether the element contains a class class
element.classList.contain( className )
Copy the code
- Replace an existing class with a new class
element.classList.replace( oldClass, newClass )
Copy the code
- Returns the class corresponding to the index
document.querySelector('.a').classList.item(0) // a
document.querySelector('.a').classList.item(1) // b
document.querySelector('.a').classList.item(2) // c
document.querySelector('.a').classList.item(3) // null
Copy the code
Element.getBoundingClientRect
Element. GetBoundingClientRect () method returns the Element size and its position relative to the viewport
The return value is a DOMRect object that is the set of rectangles returned by the element’s getClientRects() method, which is the CSS border size of the element. The result is the smallest rectangle that contains the entire element and has the left, top, right, bottom, x, y, width, and height read-only attributes in pixels that describe the entire border. Properties other than width and height are evaluated relative to the top left corner of the view window. Empty border boxes are ignored. If all element borders are empty, the rectangle returns 0 width, 0 height, and the values left and top are the top-left values of the first CSS box (in content order).
When the bounding rectangle is evaluated, scroll operations within the viewport region (or other scrollable elements) are taken into account, that is, when the scroll position changes, the values of the top and left attributes change immediately (thus, their values are relative to the viewport, not absolute). If you need to get a value relative to the top left corner of the entire page, just add the current scroll position to the top and left attributes (via window.scrollx and window.scrolly). This will get a value independent of the current scroll position. From Element. GetBoundingClientRect – MDN
We can get these data for our logic
function getBoundingClientRect (element) {
let rect = element.getBoundingClientRect();
return {
left: rect.left,// The distance from the left side of the element to the left side of the window
top: rect.top,// Distance from the top of the element to the top of the window
right: rect.right,// The distance from the right side of the element to the left side of the window
bottom: rect.bottom,// The distance from below the element to the top of the window
width: rect.width,// Is the width of the element itself
height: rect.height// Is the height of the element itself}}Copy the code
Element.insertAdjacentHTML
The insertAdjacentHTML() method parses the specified text into an Element and inserts the resulting node into the specified location in the DOM tree. It does not reparse the element it is using, so it does not destroy existing elements within the element. This avoids the extra serialization step and makes it faster than using innerHTML directly.
Grammar: element. InsertAdjacentHTML (position, text)
- position
A DOMString representing the position of the inserted content relative to the element and must be one of the following strings:
beforebegin
: precedes the element itself.afterbegin
: before inserting the first child node inside the element.beforeend
: After the last child node is inserted inside the element.afterend
: comes after the element itself.
- text
Is a DOMString to be parsed as AN HTML or XML element and inserted into the DOM tree.
Visualization of location names
<! -- beforebegin -->
<p>
<! -- afterbegin -->
foo
<! -- beforeend -->
</p>
<! -- afterend -->
Copy the code
Note: beforebegin and Afterend positions work only if the node is in the tree and the node has a parent element.
Sometimes we want to insert a DOM string directly into a DOM element on a page. We want jQuery’s append function to inject DOM strings into the DOM
Document. The createElement method implementation
// html
let ul = document.getElementById('ul');
for(let i=0; i<5; i++){let li = document.createElement('li')
li.className = "item"
li.innerHTML = `<p>${item}</p>`
ul.appendChild(li)
}
Copy the code
As you can see, frequent DOM manipulation is extremely performance unfriendly
Element. InsertAdjacentHTML implementation
// html
let ul = document.getElementById('ul');
let html = ' '
for(let i=0; i<5; i++){ html +=`<li class="item"><p>${item}</p></li>`
}
ul.insertAdjacentHTML('beforeend',html)
Copy the code
You only manipulate the DOM once
Security issues
When you use insertAdjacentHTML to insert user-entered HTML content, you need to escape it before you can use it.
Use node.textcontent or node.insertadjacenttext () instead of this method if you want to just insert textContent (not HTML nodes). Because this does not require HTML interpreter conversion, performance is better.
CustomEvent
CustomEvent events are created by the program and can have any custom function events.
CustomEvent is a constructor that creates a CustomEvent that can be actively triggered with window.dispatchevent
Example:
Implement localStorage listening
- Localstorage. setItem Listens for: custom event setItemEvent
- Localstorage. getItem Listens to: custom event getItemEvent
- Localstorage. removeItem Listens for: custom event removeItemEvent
// Listen for custom event setItemEvent
localStorage.setItem = (Orgin= >{
return function(key,value){
let setItemEvent = new CustomEvent('setItemEvent', {detail: {setKey:key,value}})
window.dispatchEvent(setItemEvent)
Orgin.call(this,key,typeof value == 'string'? value : JSON.stringify(value))
}
})(localStorage.setItem)
// Listen for the custom getItemEvent
localStorage.getItem = (Orgin= >{
return function(key){
let result = JSON.parse(Orgin.call(this,key))
let getItemEvent = new CustomEvent('getItemEvent', {detail: {getKey:key,value:result}})
window.dispatchEvent(getItemEvent)
return result
}
})(localStorage.getItem)
// Listen for the custom event removeItemEvent
localStorage.removeItem = (Orgin= >{
return function(key){
let removeItemEvent = new CustomEvent('removeItemEvent', {detail: {removeKey:key}})
window.dispatchEvent(removeItemEvent)
Orgin.call(this,key)
}
})(localStorage.removeItem)
Copy the code
SetItem, getItem and removeItem of localStorage are rewritten without affecting their own functions, allowing us to listen to the three operations of localStorage.
Listening to the
/ / localStorage. SetItem listening in
window.addEventListener('setItemEvent'.function(e){
console.log(e.detail)
})
/ / localStorage. The getItem to monitor
window.addEventListener('getItemEvent'.function(e){
console.log(e.detail)
})
/ / localStorage. RemoveItem listening in
window.addEventListener('removeItemEvent'.function(e){
console.log(e.detail)
})
Copy the code
This example has practical application in hybrid app development, native Android or native IOS interacting with our JS, which is very helpful
ParentNode.append
The parentNode. append method inserts a set of Node objects or DOMString objects after the last child of ParentNode. The inserted DOMString object is equivalent to a Text node.
Differences with Node.appendChild() :
- Parentnode.append () allows DOMString objects to be appended, while Node.appendChild() only accepts Node objects.
- Parentnode.append () returns no value, while Node.appendChild() returns the appended Node object.
- Parentnode.append () can append multiple nodes and strings, whereas Node.appendChild() can append only one Node.
If you want to insert DOMString DOM, you can choose element. InsertAdjacentHTML (position, DOMString), if you want to which can be inserted into the NODE NODE can also be inserted into the string, Parentnode.append ()
var parent = document.createElement("div");
var p = document.createElement("p");
parent.append("Some text", p);
console.log(parent);
// <div>"Some text"<p></p></div>
Copy the code
Document.createDocumentFragment
Create a new blank DocumentFragment.
Grammar: let fragments = document. CreateDocumentFragment ()
Description: Fragment is a reference to an empty DocumentFragment object.
DocumentFragments are DOM nodes. They are not part of the main DOM tree. The usual use case is to create a document fragment, attach elements to the document fragment, and then attach the document fragment to the DOM tree. In the DOM tree, the document fragment is replaced by all of its child elements.
Because the document fragment exists in memory, not in the DOM tree, inserting child elements into the document fragment does not cause page backflow (calculations of element position and geometry). Therefore, using document fragments generally results in better performance.
Example:
HTML
<ul id="ul"></ul>
Copy the code
JavaScript
var element = document.getElementById('ul'); // assuming ul exists
var fragment = document.createDocumentFragment();
var browsers = ['Firefox'.'Chrome'.'Opera'.'Safari'.'Internet Explorer'];
browsers.forEach(function(browser) {
var li = document.createElement('li');
li.textContent = browser;
fragment.appendChild(li);
});
element.appendChild(fragment);
Copy the code
Results:
Firefox
Chrome
Opera
Safari
Internet Explorer
Copy the code
reference
Chinese Web API reference | MDN interface
conclusion
If you have a better idea, or don’t find the tool function you want, feel free to leave a comment
Please point out any inaccuracies or errors in the article
Previous articles:
Front-end code optimization utility
Practical tools and methods in front-end development
Common application scenarios for front-end promises