# 辨別頁面內有無指定元素
今天(週六)下午我在公司加班時不知道要幹什麼,就開啟公司的一個wordpress專案網站,想看下之前自己做的一個網頁是否有問題。
開啟網站首頁,我習慣性的開啟了chrome的除錯工具,然後滑鼠開始滾動頁面,然後問題就出來了:頁面無法向下滾動,除錯工具的console裡報了好多undefined的錯誤。
我馬上意識到是我寫的js程式碼錯誤的在首頁被執行導致的問題,我的程式碼大致是這樣:
```
if ($('#a')) {
// some code ...
$('#b').doSomething;
// some code ...
}
```
這段程式碼的想要做的就是,判斷下頁面是否有某個id標識的元素,如果有就做一些事情。網站首頁是應該沒有這個元素的,不應該執行這個程式碼。
好吧,如果你看到這裡,你肯定能猜到我不是做前端的。我期望它返回一個布林型別的false,但它實際上返回的是一個jQuery Object,
注意這裡獲得的不是dom element,如果想獲得真實的dom element,可以這麼寫$(‘#a’)[0]或者$(‘#a’).get(0)。
其實$(‘selector’)返回的永遠都是一個jQuery Object,不管它找沒找到元素。(關於這個返回值的問題請參考:What does jquery $ actually return? 和 How to get a DOM Element from a JQuery Selector)。
那麼我該如何判斷id=a的元素是否存在呢?其實可以這麼做,if ($(‘#a’).length),如果沒有#a則返回的object其實是個空物件,可以達到目的。
getElementById(‘a’)可以嗎,它返回的是Element object的一個參考(object型別)或者是null(document.getElementById()),可以用來判斷。
到此,我的問題就解決了,也就沒有這篇文章了。
但我閒著沒事又google了一把,然後我就在stackoverflow上發現了這個問答:How to check if element exists in the visible DOM? 問題是,如何檢查元素是否存在於可見(當前實時)的dom中。
這個問答裡提到了好多方法,除了上面兩個提到的方法,其他的比如getElementsByClassName、getElementsByName、querySelector等等,總之這些方法思路基本和上面的兩個是相同的,就是簡單的檢查元素是否存在。
對於題主的提問,有人提供了以下兩個比較有意思的方法,其中一個是:document.body.contains(element),這裡面用到了node.contains(othernode)方法,它可以判斷othernode是不是node的後代,並返回一個布林值。
具體用法可以這麼寫:
```
// 先獲取要判斷的元素節點
const aNode = document.getElementById('a');
// 然後判斷該元素節點是不是當前文件頁面body節點的後代
if (aNode.ownerDocument.body.contains(aNode)) {
// do something
}
其實,用這個方法可以寫一個通用的函式來判斷某個元素節點是否在某個頁面上,大家可以參考下Mozilla Developer Network官網javascript手冊上的程式碼:
function isInPage(node) {
return (node === document.body) ? false : document.body.contains(node);
}
上面程式碼中aNode.ownerDocument是個只讀屬性,它返回aNode所在頁面的頂級文件物件document。
另外有人還提到了這個方法:判斷元素節點的baseURI是否存在。
baseURI是個只讀屬性,node.baseURI返回node節點的絕對的基準url地址(我把它理解為頁面的絕對url地址),比如$(‘#a’)[0].baseURI,
我在chrome下試了下,#a元素存在的話就會返回一個url字串,不存在的話報undefined錯誤(#a不存在自然會報這個錯誤),感覺這個方法在實際應用中不太好操作,要丟擲和捕捉錯誤,感興趣的同學可以研究下。
How to check if element exists in the visible DOM?這個問答的發起者自己寫了個方法,我把程式碼貼到下面:
<!DOCTYPE html>
<html>
<head>
<script>
var getRandomID = function (size) {
var str = "",
i = 0,
chars = "0123456789abcdefghijklmnopqurstuvwxyzABCDEFGHIJKLMNOPQURSTUVWXYZ";
while (i < size) {
str = chars.substr(Math.floor(Math.random() * 62), 1);
i ;
}
return str;
},
isNull = function (element) {
var randomID = getRandomID(12),
savedID = (element.id)? element.id : null;
element.id = randomID;
var foundElm = document.getElementById(randomID);
element.removeAttribute('id');
if (savedID !== null) {
element.id = savedID;
}
return (foundElm) ? false : true;
};
window.onload = function () {
var image = document.getElementById("demo");
console.log('undefined', (typeof image === 'undefined') ? true : false); // false
console.log('null', (image === null) ? true : false); // false
console.log('find-by-id', isNull(image)); // false
image.parentNode.removeChild(image);
console.log('undefined', (typeof image === 'undefined') ? true : false); // false ~ should be true?
console.log('null', (image === null) ? true : false); // false ~ should be true?
console.log('find-by-id', isNull(image)); // true ~ correct but there must be a better way than this?
};
</script>
</head>
<body>
<div id="demo"></div>
</body>
</html>
```
注意程式碼中的isNull函式,它是用來判斷元素是否存在的,這個方法其實是依據元素的id是否為null來判斷,思路好像和用baseURI來判斷是相同的。我試了下,當元素存在時返回true,
但當元素不存在時,它會報undefined錯誤,感興趣的同學可以研究下。
總結:
其實判斷一個元素是否存在,用getElementById()(或其他選擇元素的方法)再配合是否為null來判斷,或用jQuery獲取物件並判斷其length,簡單又直接。
但如果想判斷一個元素是否在當前實時可見的dom中,那就用node.contains(othernode)方法。
參考:
1,How to check if element exists in the visible DOM?
2,What does jquery $ actually return?
2,Node.contains()
3,Node.ownerDocument
4,How to get a DOM Element from a JQuery Selector
5,https://api.jquery.com/get/
6,baseURI
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支援指令碼之