現在我正在使用isElementloadash來檢查一個元素是否可能是 DOM。我想擺脫這個庫,所以我正在尋找這個函式的純 JS 實作。
我正在使用它,但我不知道它是否是正確的實作以及我是否忽略了任何邊緣情況:
const isDOMElement = el => el instanceof HTMLElement
uj5u.com熱心網友回復:
從庫源代碼看實作:
https://github.com/lodash/lodash/blob/master/isElement.js
uj5u.com熱心網友回復:
這是lodash實用程式:
function isElement(value) {
return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value)
}
基本上,isObjectLike它檢查傳遞的值是一個非null物件(因為 null 是 js 中的一個物件)并且!isPlainObject它不是一個普通物件(因為它可能是一個攜帶“nodeType”的物件:1條目并且因為一個 HTMLElement 實體有嵌套的原型。
實用程式是這樣的isPlainObject:
function isPlainObject(value) {
if (!isObjectLike(value) || getTag(value) != '[object Object]') {
return false
}
if (Object.getPrototypeOf(value) === null) {
return true
}
let proto = value
while (Object.getPrototypeOf(proto) !== null) {
proto = Object.getPrototypeOf(proto)
}
return Object.getPrototypeOf(value) === proto
}
正如您所看到的,第一次檢查是多余的,因為它isObjectLike再次檢查,但我認為主要的警告是它不包括其他物件的情況,因為例如“陣列”也是物件,因此它們通過了檢查:
const arr = [1, 2]; // array
arr.nodeType = 1; // add nodeType property to the array object
console.log(isElement(arr)); // true Lodash
自己試試。
我認為檢查物件是否具有nodeType繼承的屬性更安全:
const _isElement = (node) =>
typeof node === 'object' &&
node !== null &&
!node.hasOwnProperty('nodeType') &&
node.nodeType &&
node.nodeType === 1
const el = document.createElement('h1'); // node
const arr = [1, 2]; // array
arr.nodeType = 1; // add nodeType property to the array object
console.log(isElement(arr)); // true Lodash
console.log(isElement(el)); // true Lodash
console.log(_isElement(arr)) // false
console.log(_isElement(el)) // true
無論如何,我更喜歡使用您的檢查,它已經涵蓋了大多數檢查,因為任何原始非物件都不是 HTMLElement 的實體,null 不是 HTMLElement 的實體,并且 HTMLElement 實體具有“nodeType”屬性,但它是從 proto 和不是自己的財產,:
const isDOMElement = el => el instanceof HTMLElement
//or
const isDOMElement = el => el instanceof Node
uj5u.com熱心網友回復:
可以試一試...
function exposeImplementation(value) {
return Object
.prototype
.toString
.call(value);
}
function getInternalClassName(value) {
return (/^\[object\s (?<className>[^\]] )\]$/)
.exec(
exposeImplementation(value)
)
?.groups
?.className;
}
function isHTMLElement(value) {
return !!value && (/^HTML(?:[A-Z][A-Za-z] )?Element$/)
.test(
getInternalClassName(value)
);
}
console.log(
getInternalClassName(document.createElement('h1')),
isHTMLElement(document.createElement('h1'))
);
console.log(
getInternalClassName(document.body),
isHTMLElement(document.body)
);
console.log(
getInternalClassName(document),
isHTMLElement(document)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/463508.html
標籤:javascript
上一篇:復選框狀態未在現場更新
