DOM小測28期直播答疑文字版整理

1、題目與考察點

題目地址:github.com/zhangxinxu/…html

題目內容以下(點擊查看大圖):html5

DOM小測28期題目

本題主要考察如何判斷DOM節點文檔先後位置,父子關係等。我看了下最後的回答,近9成的回答使用了很是囉嗦的方法,比例之高,實在出乎意料。實際上,本題有很是簡單、寥寥數行就能實現的方法,只要你知道下面這兩個頗有用的DOM原生API,一個是contains()方法,判斷DOM元素或節點是否有包含關係;另一個是compareDocumentPosition()方法,更強悍的DOM或節點位置關係判斷,不管是先後、內外仍是跨文檔均可以。node

本次B站答疑直播在週六上午10:34分開始,持續約30分鐘,有錄播,能夠點擊這裏觀看,建議1.5倍速食用。git

2、DOM包含關係判斷contains()

contains()方法是一個很古老的API,用來判斷兩個DOM節點之間的包含關係,語法以下:github

node.contains(otherNode)複製代碼

返回布爾值,表示node是否包含otherNode,或者就是node自己。瀏覽器

例如:bash

document.documentElement.contains(document.body);    // 返回值是true
document.body.contains(document.body);               // 返回值是true
document.body.contains(document.documentElement);    // 返回值是false複製代碼

此API兼容性良好,IE5就開始支持了,使用很是方便,咱們無需專門遍歷祖先元素用判斷兩個節點之間的嵌套關係。app

其它

若是判斷的兩個節點元素是跨iframe文檔的,則會被認爲是false。例如咱們直接藉助Blob動態建立一個非外鏈iframe,代碼以下:ide

var htmlIframe = '<img id="img" src="https://.../mm.jpg" onclick="console.log(window.parent.document.body.contains(this))">';
var iframe = document.createElement('iframe');
var blob = new Blob([htmlIframe], { 'type': 'text/html'});
iframe.src = URL.createObjectURL(blob);
iframeBlob1.appendChild(iframe);複製代碼

點擊圖片,能夠看到控制檯輸出結果以下:wordpress

iframe內外節點包含關係

若是想要知道iframe內外的包含關係,則須要使用另外的API:compareDocumentPosition()

3、任意位置判斷compareDocumentPosition

本題中圖片DOM元素先後位置的比對徹底不須要寫循環進行遍歷,有現成的API能夠實現咱們想要的效果,那就是Node.compareDocumentPosition API。

此API很有深度,我專門寫了篇文章介紹這個API,可參見這裏:「深刻Node.compareDocumentPosition API」。

例如:

var compareValue = img.compareDocumentPosition(compareImg);
if (compareValue == 2) {
  // compareImg在前
} else if (compareValue == 4) {
  // compareImg在後
} else if (compareValue == 0) {
  // 就是compareImg元素自身
} else {
  // 其它位置關係
}複製代碼

若是compareValue2,則表示compareImgimg的前面;若是是4,則表示compareImgimg的後面。

由此咱們能夠輕鬆判斷點擊圖片和對比圖片之間的文檔位置關係,寥寥幾行代碼的事情。

不過須要注意的是,若是是判斷其餘非替換元素的位置關係,則不能使用數值比對,由於可能compareDocumentPosition()方法執行後的值是一個混合數值,例如:

// 返回值是 10,8 + 2
document.body.compareDocumentPosition(document.documentElement);
// 返回值是 20,16 + 4
document.documentElement.compareDocumentPosition(document.body)複製代碼

咱們須要使用單個&符合和對應目標值進行與位運算的結果來斷定,例如:

if (document.body.compareDocumentPosition(document.documentElement) & 2) {
   // document.documentElement在document.body前面
   // ...
}複製代碼

若是不是很理解,能夠訪問我剛寫的專門深刻介紹compareDocumentPosition的文章。

4、如何判斷click元素是圖片

例如:

container.onclick = function (event) {
  // event.target ...
}複製代碼

業界用的比較多的方法是使用tagName值進行判斷,以下:

event.target.tagName == 'IMG'  // truefalse複製代碼

全部瀏覽器都返回大寫標籤名,固然,若是你不放心(之後變了,或者遇到SB瀏覽器),能夠更嚴格比對下:

/^img$/i.test(event.target.tagName)    // truefalse複製代碼
event.target.tagName.toLowerCase() == 'img'    // truefalse複製代碼

咱們還能夠使用nodeName進行判斷,例如:

event.target.nodeName == 'IMG'    // truefalse複製代碼

最後,在介紹一種對象類型判斷方法,以下:

event.target instanceof Image    // truefalse複製代碼

也是能夠的。

5、答疑要點總結

  1. 包含關係推薦使用Node.contains()方法;
  2. 判斷當前元素是不是IMG,能夠 :
    event.target.tagName/nodeName == 'IMG'複製代碼
    /^img$/i.test(event.target.tagName)複製代碼
    event.target.tagName.toLowerCase() == 'img'複製代碼
    event.target instanceof Image複製代碼
  3. 先後節點關係判斷使用Node.compareDocumentPosition()

關於直播答疑

每週三會在這個項目issues中發佈小測題,依次CSS,JS和DOM,每週六上午10:00~11:00之間直播答疑。

有興趣參與的能夠多多關注下,免費的。

以上~

相關文章
相關標籤/搜索