說是冷門,無非於咱們而言,在實際項目中登場的機會少,或許有些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
複製代碼
若是你有更好的點子,或者沒有找到你想要的工具函數,歡迎留言
文中如有不許確或錯誤的地方,歡迎指出
往期文章 :