说是冷门,无非于咱们而言,在实际项目中登场的机会少,或许有些api压根没据说过,本篇介绍几个 api 算是冷门中的那几烁极光,在咱们穷尽一切办法时,它或许带来那丝曙光。html
Element.classList 是一个只读属性,返回一个元素的类属性的实时 DOMTokenList 集合。 相比将 element.className 做为以空格分隔的字符串来使用,classList 是一种更方便的访问元素的类列表的方法。经常使用相关的api以下:前端
在 Element.classList
没用出现以前,咱们可能这样操做DOMnode
/* 添加 class 类 方法*/
function add(element, className) {
if(!new RegExp("(^|\\s)" + className + "(\\s|$)").test(element.className)) element.className += ' ' + className;
}
/* 移出 class 类 方法*/
function remove(element, className) {
element.className = element.className.replace(new RegExp("(^|\\s)" + className + "(?=(\\s|$))", "g"), '');
}
/* 切换 class 类 方法*/
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;
}
}
/* 判断是否包含某个 class 类 方法*/
function contain(element, className) {
return element.className.indexOf(className)>-1
}
/* 用一个新类替换已有类*/
function replace(element, oldClassName,newClassName) {
element.className = element.className.replace(oldClassName,newClassName)
}
复制代码
Element.classList
出现后,咱们这样操做DOMapi
element.classList.add( className )
复制代码
element.classList.remove( className )
复制代码
element.classList.toggle( className )
复制代码
element.classList.contain( className )
复制代码
element.classList.replace( oldClass, newClass )
复制代码
//html <button class="a b c"> 按钮 </button>
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
复制代码
Element.getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置安全
返回值是一个 DOMRect 对象,这个对象是由该元素的 getClientRects() 方法返回的一组矩形的集合,就是该元素的 CSS 边框大小。返回的结果是包含完整元素的最小矩形,而且拥有left, top, right, bottom, x, y, width, 和 height这几个以像素为单位的只读属性用于描述整个边框。除了width 和 height 之外的属性是相对于视图窗口的左上角来计算的。空边框盒(译者注:没有内容的边框)会被忽略。若是全部的元素边框都是空边框,那么这个矩形给该元素返回的 width、height 值为 0,left、top 值为第一个 CSS 盒子(按内容顺序)的 top-left 值。app
当计算边界矩形时,会考虑视口区域(或其余可滚动元素)内的滚动操做,也就是说,当滚动位置发生了改变,top和left属性值就会随之当即发生变化(所以,它们的值是相对于视口的,而不是绝对的)。若是你须要得到相对于整个网页左上角定位的属性值,那么只要给top、left属性值加上当前的滚动位置(经过 window.scrollX 和 window.scrollY),这样就能够获取与当前的滚动位置无关的值 。源自 Element.getBoundingClientRect - MDN函数
咱们能够获取这些数据进行咱们的逻辑工具
function getBoundingClientRect (element) {
let rect = element.getBoundingClientRect();
return {
left: rect.left,//元素左边到视窗左边的距离
top: rect.top,//元素上边到视窗上边的距离
right: rect.right,//元素右边到视窗左边的距离
bottom: rect.bottom,//元素下边到视窗上边的距离
width: rect.width,//是元素自身的宽
height: rect.height//是元素自身的高
}
}
复制代码
insertAdjacentHTML() 方法将指定的文本解析为 Element 元素,并将结果节点插入到DOM树中的指定位置。它不会从新解析它正在使用的元素,所以它不会破坏元素内的现有元素。这避免了额外的序列化步骤,使其比直接使用innerHTML操做更快。post
语法: element.insertAdjacentHTML(position, text)性能
一个 DOMString,表示插入内容相对于元素的位置,而且必须是如下字符串之一:
beforebegin
:元素自身的前面。afterbegin
:插入元素内部的第一个子节点以前。beforeend
:插入元素内部的最后一个子节点以后。afterend
:元素自身的后面。是要被解析为HTML或XML元素,并插入到DOM树中的
DOMString
。
位置名称的可视化
<!-- beforebegin -->
<p>
<!-- afterbegin -->
foo
<!-- beforeend -->
</p>
<!-- afterend -->
复制代码
注意: beforebegin和afterend位置,仅在节点在树中且节点具备一个parent元素时工做。
有时候,咱们想要在页面的一个DOM元素里直接插入DOM字符串,想要jQuery的append的功能,可以往DOM里面注入DOM字符串
document.createElement实现
// html <ul id="ul"></div>
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)
}
复制代码
从中能够看出,频繁操做DOM,对页面性能极不友好
element.insertAdjacentHTML实现
// html <ul id="ul"></div>
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)
复制代码
只操做了一次DOM
安全问题
使用 insertAdjacentHTML 插入用户输入的HTML内容的时候,须要转义以后才能使用。
若是只是为了插入文本内容(而不是HTML节点),不建议使用这个方法,建议使用node.textContent 或者 node.insertAdjacentText()。由于这样不须要通过HTML解释器的转换,性能会好一点。
CustomEvent 事件是由程序建立的,能够有任意自定义功能的事件。
CustomEvent是一个构造函数, 能够建立一个自定义事件,能够用 window.dispatchEvent
去主动触发这个自定义事件
使用示例:
实现localStorage 监听
//监听自定义事件 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)
//监听自定义事件 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)
//监听自定义事件 removeItemEvent
localStorage.removeItem = (Orgin=>{
return function(key){
let removeItemEvent = new CustomEvent('removeItemEvent',{detail:{removeKey:key}})
window.dispatchEvent(removeItemEvent)
Orgin.call(this,key)
}
})(localStorage.removeItem)
复制代码
以上示例,咱们对localStorage的
setItem
、getItem
、removeItem
在不影响自己的功能前提下进行了重写,让咱们有了对这localStorage的这三个操做进行了监听的功能。
监听
//localStorage.setItem监听
window.addEventListener('setItemEvent',function(e){
console.log(e.detail)
})
//localStorage.getItem监听
window.addEventListener('getItemEvent',function(e){
console.log(e.detail)
})
//localStorage.removeItem监听
window.addEventListener('removeItemEvent',function(e){
console.log(e.detail)
})
复制代码
该示例在混合app开发中有实际应用,原生安卓或原生IOS 与 咱们的JS交互,有很大的帮助
ParentNode.append 方法在 ParentNode的最后一个子节点以后插入一组 Node 对象或 DOMString 对象。 被插入的 DOMString 对象等价为 Text 节点。
与 Node.appendChild() 的差别:
若是想要 DOM 插入 DOMString
,能够选用 element.insertAdjacentHTML(position, DOMString)
,若是想要便可以插入NODE节点也能够插入字符串,能够选用 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>
复制代码
建立一个新的空白的文档片断( DocumentFragment)。
语法:let fragment = document.createDocumentFragment()
描述: fragment 是一个指向空DocumentFragment对象的引用。
DocumentFragments 是DOM节点。它们不是主DOM树的一部分。一般的用例是建立文档片断,将元素附加到文档片断,而后将文档片断附加到DOM树。在DOM树中,文档片断被其全部的子元素所代替。
由于文档片断存在于内存中,并不在DOM树中,因此将子元素插入到文档片断时不会引发页面回流(对元素位置和几何上的计算)。所以,使用文档片断一般会带来更好的性能。
示例:
HTML
<ul id="ul"></ul>
复制代码
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);
复制代码
结果:
Firefox
Chrome
Opera
Safari
Internet Explorer
复制代码
若是你有更好的点子,或者没有找到你想要的工具函数,欢迎留言
文中如有不许确或错误的地方,欢迎指出
往期文章 :