I'm trying to get:
我想要:
document.createElement('div') //=> true
{tagName: 'foobar something'} //=> false
In my own scripts, I used to just use this since I never needed tagName
as a property:
在我自己的脚本中,我以前只使用这个,因为我从来没有需要tagName作为属性:
if (!object.tagName) throw ...;
So for the second object, I came up with the following as a quick solution -- which mostly works. ;)
因此,对于第二个对象,我提出了以下的快速解决方案——大多数情况下是可行的。,)
The problem is, it depends on browsers enforcing read-only properties, which not all do.
问题是,它依赖于浏览器强制执行只读属性,而不是全部。
function isDOM(obj) {
var tag = obj.tagName;
try {
obj.tagName = ''; // Read-only for DOM, should throw exception
obj.tagName = tag; // Restore for normal objects
return false;
} catch (e) {
return true;
}
}
Is there a good substitute?
有很好的替代品吗?
31 个解决方案
#1
222
This might be of interest:
这可能是有趣的:
function isElement(obj) {
try {
//Using W3 DOM2 (works for FF, Opera and Chrome)
return obj instanceof HTMLElement;
}
catch(e){
//Browsers not supporting W3 DOM2 don't have HTMLElement and
//an exception is thrown and we end up here. Testing some
//properties that all elements have (works on IE7)
return (typeof obj==="object") &&
(obj.nodeType===1) && (typeof obj.style === "object") &&
(typeof obj.ownerDocument ==="object");
}
}
It's part of the DOM, Level2.
它是DOM的一部分,第二级。
Update 2: This is how I implemented it in my own library: (the previous code didn't work in Chrome, because Node and HTMLElement are functions instead of the expected object. This code is tested in FF3, IE7, Chrome 1 and Opera 9).
更新2:这是我在自己的库中实现它的方法:(之前的代码在Chrome中不起作用,因为Node和HTMLElement是函数而不是预期的对象。此代码在FF3、IE7、chrome1和Opera 9中进行测试。
//Returns true if it is a DOM node
function isNode(o){
return (
typeof Node === "object" ? o instanceof Node :
o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName==="string"
);
}
//Returns true if it is a DOM element
function isElement(o){
return (
typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2
o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName==="string"
);
}
#2
15
The following IE7 compatible, super-simple code works perfectly.
下面的IE7兼容,超级简单的代码完美的工作。
The accepted answer does not detect all types of HTML elements. For example, SVG elements are not supported. In contrast, this answer works for HTML well as SVG.
被接受的答案没有检测到所有类型的HTML元素。例如,不支持SVG元素。相比之下,这个答案对HTML和SVG都有效。
See it in action here: https://jsfiddle.net/eLuhbu6r/
请参见这里的操作:https://jsfiddle.net/eLuhbu6r/。
function isElement(element) {
return element instanceof Element;
}
#3
11
All solutions above and below (my solution including) suffer from possibility of being incorrect, especially on IE — it is quite possible to (re)define some objects/methods/properties to mimic a DOM node rendering the test invalid.
上面和下面的所有解决方案(包括我的解决方案)都有可能出现错误,特别是在IE上,很有可能定义一些对象/方法/属性来模拟DOM节点,使测试无效。
So usually I use the duck-typing-style testing: I test specifically for things I use. For example, if I want to clone a node I test it like this:
因此,我通常使用鸭子类型的测试:我专门测试我使用的东西。例如,如果我想克隆一个节点,我就像这样测试它:
if(typeof node == "object" && "nodeType" in node &&
node.nodeType === 1 && node.cloneNode){
// most probably this is a DOM node, we can clone it safely
clonedNode = node.cloneNode(false);
}
Basically it is a little sanity check + the direct test for a method (or a property) I am planning to use.
基本上,它是一个小的完整性检查+对一个方法(或一个属性)的直接测试,我打算使用它。
Incidentally the test above is a good test for DOM nodes on all browsers. But if you want to be on the safe side always check the presence of methods and properties and verify their types.
顺便提一下,上面的测试对于所有浏览器上的DOM节点都是一个很好的测试。但是,如果你想要安全起见,总是检查方法和属性的存在,并验证它们的类型。
EDIT: IE uses ActiveX objects to represent nodes, so their properties do not behave as true JavaScript object, for example:
EDIT: IE使用ActiveX对象来表示节点,因此它们的属性不能作为真正的JavaScript对象,例如:
console.log(typeof node.cloneNode); // object
console.log(node.cloneNode instanceof Function); // false
while it should return "function" and true
respectively. The only way to test methods is to see if the are defined.
而它应该分别返回“函数”和“真”。测试方法的唯一方法是查看是否定义了。
#4
6
You could try appending it to a real DOM node...
您可以尝试将其添加到一个真正的DOM节点…
function isDom(obj)
{
var elm = document.createElement('div');
try
{
elm.appendChild(obj);
}
catch (e)
{
return false;
}
return true;
}
#5
5
How about Lo-Dash's _.isElement
?
Lo-Dash _.isElement的怎么样?
$ npm install lodash.iselement
And in the code:
和代码:
var isElement = require("lodash.iselement");
isElement(document.body);
#6
5
This is from the lovely JavaScript library MooTools:
这是来自可爱的JavaScript库MooTools:
if (obj.nodeName){
switch (obj.nodeType){
case 1: return 'element';
case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
}
}
#7
4
The using the root detection found here, we can determine whether e.g. alert is a member of the object's root, which is then likely to be a window:
使用在这里找到的根检测,我们可以确定是否例如警告是对象根的成员,它很可能是一个窗口:
function isInAnyDOM(o) {
return (o !== null) && !!(o.ownerDocument && (o.ownerDocument.defaultView || o.ownerDocument.parentWindow).alert); // true|false
}
To determine whether the object is the current window is even simpler:
要确定对象是否为当前窗口,则更简单:
function isInCurrentDOM(o) {
return (o !== null) && !!o.ownerDocument && (window === (o.ownerDocument.defaultView || o.ownerDocument.parentWindow)); // true|false
}
This seems to be less expensive than the try/catch solution in the opening thread.
这似乎比打开线程中的try/catch解决方案要便宜。
Don P
没有P
#8
4
old thread, but here's an updated possibility for ie8 and ff3.5 users:
旧的线程,但是这是ie8和ff3.5用户更新的可能性:
function isHTMLElement(o) {
return (o.constructor.toString().search(/\object HTML.+Element/) > -1);
}
#9
3
var IsPlainObject = function ( obj ) { return obj instanceof Object && ! ( obj instanceof Function || obj.toString( ) !== '[object Object]' || obj.constructor.name !== 'Object' ); },
IsDOMObject = function ( obj ) { return obj instanceof EventTarget; },
IsDOMElement = function ( obj ) { return obj instanceof Node; },
IsListObject = function ( obj ) { return obj instanceof Array || obj instanceof NodeList; },
// In fact I am more likely t use these inline, but sometimes it is good to have these shortcuts for setup code
//事实上,我更可能不使用这些内联,但是有时候有这些设置代码的快捷方式很好。
#10
3
This could be helpful: isDOM
这可能很有用:isDOM。
//-----------------------------------
// Determines if the @obj parameter is a DOM element
function isDOM (obj) {
// DOM, Level2
if ("HTMLElement" in window) {
return (obj && obj instanceof HTMLElement);
}
// Older browsers
return !!(obj && typeof obj === "object" && obj.nodeType === 1 && obj.nodeName);
}
In the code above, we use the double negation operator to get the boolean value of the object passed as argument, this way we ensure that each expression evaluated in the conditional statement be boolean, taking advantage of the Short-Circuit Evaluation, thus the function returns true
or false
在上面的代码中,我们使用双重否定操作符来获取作为参数传递的对象的布尔值,这样我们可以确保在条件语句中计算的每个表达式都是布尔值,利用了短路评估的优点,从而使函数返回true或false。
#11
2
You can see if the object or node in question returns a string type.
您可以看到问题中的对象或节点是否返回一个字符串类型。
typeof (array).innerHTML === "string" => false
typeof (object).innerHTML === "string" => false
typeof (number).innerHTML === "string" => false
typeof (text).innerHTML === "string" => false
//any DOM element will test as true
typeof (HTML object).innerHTML === "string" => true
typeof (document.createElement('anything')).innerHTML === "string" => true
#12
2
For the ones using Angular:
对于使用角的人:
angular.isElement
https://docs.angularjs.org/api/ng/function/angular.isElement
https://docs.angularjs.org/api/ng/function/angular.isElement
#13
1
In Firefox, you can use the instanceof Node
. That Node
is defined in DOM1.
在Firefox中,可以使用instanceof节点。该节点在DOM1中定义。
But that is not that easy in IE.
但在IE中这并不容易。
- "instanceof ActiveXObject" only can tell that it is a native object.
- “instanceof ActiveXObject”只能说明它是一个本机对象。
- "typeof document.body.appendChild=='object'" tell that it may be DOM object, but also can be something else have same function.
- “typeof document.body。appendChild=='object'"说明它可能是DOM对象,但也可以是其他具有相同功能的东西。
You can only ensure it is DOM element by using DOM function and catch if any exception. However, it may have side effect (e.g. change object internal state/performance/memory leak)
您只能通过使用DOM函数确保它是DOM元素,并捕获任何异常。但是,它可能有副作用(例如,更改对象的内部状态/性能/内存泄漏)
#14
1
Perhaps this is an alternative? Tested in Opera 11, FireFox 6, Internet Explorer 8, Safari 5 and Google Chrome 16.
也许这是另一种选择?测试在Opera 11, FireFox 6, Internet Explorer 8, Safari 5和谷歌Chrome 16。
function isDOMNode(v) {
if ( v===null ) return false;
if ( typeof v!=='object' ) return false;
if ( !('nodeName' in v) ) return false;
var nn = v.nodeName;
try {
// DOM node property nodeName is readonly.
// Most browsers throws an error...
v.nodeName = 'is readonly?';
} catch (e) {
// ... indicating v is a DOM node ...
return true;
}
// ...but others silently ignore the attempt to set the nodeName.
if ( v.nodeName===nn ) return true;
// Property nodeName set (and reset) - v is not a DOM node.
v.nodeName = nn;
return false;
}
Function won't be fooled by e.g. this
函数不会被这样的函数所欺骗。
isDOMNode( {'nodeName':'fake'} ); // returns false
#15
1
This is what I figured out:
这就是我想出来的:
var isHTMLElement = (function () {
if ("HTMLElement" in window) {
// Voilà. Quick and easy. And reliable.
return function (el) {return el instanceof HTMLElement;};
} else if ((document.createElement("a")).constructor) {
// We can access an element's constructor. So, this is not IE7
var ElementConstructors = {}, nodeName;
return function (el) {
return el && typeof el.nodeName === "string" &&
(el instanceof ((nodeName = el.nodeName.toLowerCase()) in ElementConstructors
? ElementConstructors[nodeName]
: (ElementConstructors[nodeName] = (document.createElement(nodeName)).constructor)))
}
} else {
// Not that reliable, but we don't seem to have another choice. Probably IE7
return function (el) {
return typeof el === "object" && el.nodeType === 1 && typeof el.nodeName === "string";
}
}
})();
To improve performance I created a self-invoking function that tests the browser's capabilities only once and assigns the appropriate function accordingly.
为了提高性能,我创建了一个自调用函数,它只测试一次浏览器的功能,并相应地分配相应的功能。
The first test should work in most modern browsers and was already discussed here. It just tests if the element is an instance of HTMLElement
. Very straightforward.
第一个测试应该在大多数现代浏览器中工作,并且已经在这里讨论过了。它只是测试元素是否是HTMLElement的实例。非常简单。
The second one is the most interesting one. This is its core-functionality:
第二个是最有趣的一个。这是它的核心功能:
return el instanceof (document.createElement(el.nodeName)).constructor
It tests whether el is an instance of the construcor it pretends to be. To do that, we need access to an element's contructor. That's why we're testing this in the if-Statement. IE7 for example fails this, because (document.createElement("a")).constructor
is undefined
in IE7.
它测试el是否是构造函数的实例,或者它假装成。要做到这一点,我们需要访问一个元素的contructor。这就是我们在if-Statement中测试这个的原因。例如,IE7失败了,因为(document.createElement(“a”))。构造函数在IE7中没有定义。
The problem with this approach is that document.createElement
is really not the fastest function and could easily slow down your application if you're testing a lot of elements with it. To solve this, I decided to cache the constructors. The object ElementConstructors
has nodeNames as keys with its corresponding constructors as values. If a constructor is already cached, it uses it from the cache, otherwise it creates the Element, caches its constructor for future access and then tests against it.
这种方法的问题在于文档。createElement并不是最快的函数,如果你用它来测试很多元素,它可以很容易地降低应用程序的速度。为了解决这个问题,我决定缓存构造函数。对象元素构造函数以其对应的构造函数作为值作为键。如果构造函数已经被缓存,它将从缓存中使用它,否则它将创建元素,缓存它的构造函数以供将来访问,然后对其进行测试。
The third test is the unpleasant fallback. It tests whether el is an object
, has a nodeType
property set to 1
and a string as nodeName
. This is not very reliable of course, yet the vast majority of users shouldn't even fall back so far.
第三个考验是令人不快的退却。它测试el是否为对象,将nodeType属性设置为1,字符串为nodeName。当然,这并不是很可靠,但绝大多数用户甚至不应该退回到目前为止。
This is the most reliable approach I came up with while still keeping performance as high as possible.
这是我提出的最可靠的方法,同时仍然保持尽可能高的性能。
#16
#17
1
I think prototyping is not a very good solution but maybe this is the fastest one: Define this code block;
我认为原型设计不是一个很好的解决方案,但也许这是最快的方法:定义这个代码块;
Element.prototype.isDomElement = true;
HTMLElement.prototype.isDomElement = true;
than check your objects isDomElement property:
不要检查你的对象isDomElement属性:
if(a.isDomElement){}
I hope this helps.
我希望这可以帮助。
#18
1
differentiate a raw js object from a HTMLElement
将一个原始js对象与一个HTMLElement区分开来。
function isDOM (x){
return /HTML/.test( {}.toString.call(x) );
}
use:
使用:
isDOM( {a:1} ) // false
isDOM( document.body ) // true
// OR
/ /或
Object.defineProperty(Object.prototype, "is",
{
value: function (x) {
return {}.toString.call(this).indexOf(x) >= 0;
}
});
use:
使用:
o={}; o.is("HTML") // false o=document.body; o.is("HTML") // true
o = { };o.is(HTML)/ /假o = document.body;o.is(HTML)/ /真实的
#19
0
I think that what you have to do is make a thorough check of some properties that will always be in a dom element, but their combination won't most likely be in another object, like so:
我认为你需要做的是彻底检查一些属性,这些属性总是在dom元素中,但是它们的组合不太可能出现在另一个对象中,比如:
var isDom = function (inp) {
return inp && inp.tagName && inp.nodeName && inp.ownerDocument && inp.removeAttribute;
};
#20
0
here's a trick using jQuery
这里有一个使用jQuery的技巧。
var obj = {};
var element = document.getElementById('myId'); // or simply $("#myId")
$(obj).html() == undefined // true
$(element).html() == undefined // false
so putting it in a function:
所以把它放在一个函数中
function isElement(obj){
return (typeOf obj === 'object' && !($(obj).html() == undefined));
}
#21
0
Not to hammer on this or anything but for ES5-compliant browsers why not just:
不要在这个或其他任何东西上敲打,而是为了符合es5的浏览器,为什么不只是:
function isDOM(e) {
return (/HTML(?:.*)Element/).test(Object.prototype.toString.call(e).slice(8, -1));
}
Won't work on TextNodes and not sure about Shadow DOM or DocumentFragments etc. but will work on almost all HTML tag elements.
不能在textnode上工作,也不能确定阴影DOM或DocumentFragments等,但几乎可以处理所有HTML标记元素。
#22
0
This will work for almost any browser. (No distinction between elements and nodes here)
这几乎适用于任何浏览器。(这里的元素和节点没有区别)
function dom_element_check(element){
if (typeof element.nodeType !== 'undefined'){
return true;
}
return false;
}
#23
0
A absolute right method, check target is a real html element primary code:
一个绝对正确的方法,检查目标是一个真正的html元素的主代码:
(function (scope) {
if (!scope.window) {//May not run in window scope
return;
}
var HTMLElement = window.HTMLElement || window.Element|| function() {};
var tempDiv = document.createElement("div");
var isChildOf = function(target, parent) {
if (!target) {
return false;
}
if (parent == null) {
parent = document.body;
}
if (target === parent) {
return true;
}
var newParent = target.parentNode || target.parentElement;
if (!newParent) {
return false;
}
return isChildOf(newParent, parent);
}
/**
* The dom helper
*/
var Dom = {
/**
* Detect if target element is child element of parent
* @param {} target The target html node
* @param {} parent The the parent to check
* @returns {}
*/
IsChildOf: function (target, parent) {
return isChildOf(target, parent);
},
/**
* Detect target is html element
* @param {} target The target to check
* @returns {} True if target is html node
*/
IsHtmlElement: function (target) {
if (!X.Dom.IsHtmlNode(target)) {
return false;
}
return target.nodeType === 1;
},
/**
* Detect target is html node
* @param {} target The target to check
* @returns {} True if target is html node
*/
IsHtmlNode:function(target) {
if (target instanceof HTMLElement) {
return true;
}
if (target != null) {
if (isChildOf(target, document.documentElement)) {
return true;
}
try {
tempDiv.appendChild(target.cloneNode(false));
if (tempDiv.childNodes.length > 0) {
tempDiv.innerHTML = "";
return true;
}
} catch (e) {
}
}
return false;
}
};
X.Dom = Dom;
})(this);
#24
0
Each DOMElement.constructor returns function HTML...Element() or [Object HTML...Element] so...
每个DOMElement。构造函数返回函数HTML…元素()或[对象HTML…元素)所以…
function isDOM(getElem){
if(getElem===null||typeof getElem==="undefined") return false;
var c = getElem.constructor.toString();
var html = c.search("HTML")!==-1;
var element = c.search("Element")!==-1;
return html&&element;
}
#25
0
I have a special way to do this that has not yet been mentioned in the answers.
我有一种特殊的方法来做这个,在答案中还没有提到。
My solution is based on four tests. If the object passes all four, then it is an element:
我的解决方案是基于四个测试。如果物体经过所有四个,那么它就是一个元素:
-
The object is not null.
对象不为空。
-
The object has a method called "appendChild".
该对象有一个名为“appendChild”的方法。
-
The method "appendChild" was inherited from the Node class, and isn't just an imposter method (a user-created property with an identical name).
方法“appendChild”是从节点类继承而来的,它不只是一个imposter方法(一个用户创建的具有相同名称的属性)。
-
The object is of Node Type 1 (Element). Objects that inherit methods from the Node class are always Nodes, but not necessarily Elements.
对象是节点类型1(元素)。从节点类继承方法的对象总是节点,但不一定是元素。
Q: How do I check if a given property is inherited and isn't just an imposter?
问:我如何检查给定的属性是否继承,而不只是一个冒名顶替者?
A: A simple test to see if a method was truly inherited from Node is to first verify that the property has a type of "object" or "function". Next, convert the property to a string and check if the result contains the text "[Native Code]". If the result looks something like this:
A:一个简单的测试,看看一个方法是否真正从节点继承,首先要验证该属性是否具有“对象”或“函数”的类型。接下来,将属性转换为字符串,并检查结果是否包含文本“[本机代码]”。如果结果是这样的:
function appendChild(){
[Native Code]
}
Then the method has been inherited from the Node object. See https://davidwalsh.name/detect-native-function
然后该方法从节点对象继承。参见https://davidwalsh.name/detect-native-function
And finally, bringing all the tests together, the solution is:
最后,把所有的测试结合起来,解决方案是:
function ObjectIsElement(obj) {
var IsElem = true;
if (obj == null) {
IsElem = false;
} else if (typeof(obj.appendChild) != "object" && typeof(obj.appendChild) != "function") {
//IE8 and below returns "object" when getting the type of a function, IE9+ returns "function"
IsElem = false;
} else if ((obj.appendChild + '').replace(/[\r\n\t\b\f\v\xC2\xA0\x00-\x1F\x7F-\x9F ]/ig, '').search(/\{\[NativeCode]}$/i) == -1) {
IsElem = false;
} else if (obj.nodeType != 1) {
IsElem = false;
}
return IsElem;
}
#26
0
No need for hacks, you can just ask if an element is an instance of the Element:
不需要黑客,您可以询问元素是否为元素的实例:
const isElement = element => {
element instanceof Element;
};
#27
0
(element instanceof $ && element.get(0) instanceof Element) || element instanceof Element
This will check for even if it is a jQuery or JavaScript DOM element
这将检查是否为jQuery或JavaScript DOM元素。
#28
0
I suggest a simple way to testing if a variable is an DOM element
我建议用一种简单的方法来测试变量是否是DOM元素。
function isDomEntity(entity) {
if( typeof entity === 'object' && entity.nodeType != undefined){
return true;
}
else{
return false;
}
}
#29
-1
var isElement = function(e){
try{
// if e is an element attached to the DOM, we trace its lineage and use native functions to confirm its pedigree
var a = [e], t, s, l = 0, h = document.getElementsByTagName('HEAD')[0], ht = document.getElementsByTagName('HTML')[0];
while(l!=document.body&&l!=h&&l.parentNode) l = a[a.push(l.parentNode)-1];
t = a[a.length-1];
s = document.createElement('SCRIPT'); // safe to place anywhere and it won't show up
while(a.length>1){ // assume the top node is an element for now...
var p = a.pop(),n = a[a.length-1];
p.insertBefore(s,n);
}
if(s.parentNode)s.parentNode.removeChild(s);
if(t!=document.body&&t!=h&&t!=ht)
// the top node is not attached to the document, so we don't have to worry about it resetting any dynamic media
// test the top node
document.createElement('DIV').appendChild(t).parentNode.removeChild(t);
return e;
}
catch(e){}
return null;
}
I tested this on Firefox, Safari, Chrome, Opera and IE9. I couldn't find a way to hack it.
In theory, it tests every ancestor of the proposed element, as well as the element itself, by inserting a script tag before it.
If its first ancestor traces back to a known element, such as <html>
, <head>
or <body>
, and it hasn't thrown an error along the way, we have an element.
If the first ancestor is not attached to the document, we create an element and attempt to place the proposed element inside of it, (and then remove it from the new element).
So it either traces back to a known element, successfully attaches to a known element or fails.
It returns the element or null if it is not an element.
我在Firefox、Safari、Chrome、Opera和IE9上做了测试。我找不到办法破解它。理论上,它通过在前面插入一个脚本标记来测试所提议元素的每个祖先,以及元素本身。如果它的第一个祖先可以追溯到一个已知的元素,比如, 或,并且它在这个过程中没有抛出一个错误,我们有一个元素。如果第一个祖先没有附加到文档,我们创建一个元素并尝试将所提议的元素放入其中,(然后从新元素中删除它)。因此,它可以追溯到已知元素,成功地连接到已知元素或失败。如果元素不是元素,它将返回元素或null。
#30
-1
The easiest and cross-browser way to detect if an element is part of HTML DOM is as below:
如果一个元素是HTML DOM的一部分,最简单、最跨浏览器的方法是:
function inHTMLDom(myelement){
if(myelement.ownerDocument.documentElement.tagName.toLowerCase()=="html"){
return true;
}else{
return false;
}
}
inHTMLDom(<your element>); // <your element>:element you are interested in checking.
tested in IE6,IE7,IE8,IE9,IE10,FF,Chrome,Safari,Opera.
测试在IE6,IE7,IE8,IE9,IE10浏览器,火狐,Chrome,Safari、Opera。
#1
222
This might be of interest:
这可能是有趣的:
function isElement(obj) {
try {
//Using W3 DOM2 (works for FF, Opera and Chrome)
return obj instanceof HTMLElement;
}
catch(e){
//Browsers not supporting W3 DOM2 don't have HTMLElement and
//an exception is thrown and we end up here. Testing some
//properties that all elements have (works on IE7)
return (typeof obj==="object") &&
(obj.nodeType===1) && (typeof obj.style === "object") &&
(typeof obj.ownerDocument ==="object");
}
}
It's part of the DOM, Level2.
它是DOM的一部分,第二级。
Update 2: This is how I implemented it in my own library: (the previous code didn't work in Chrome, because Node and HTMLElement are functions instead of the expected object. This code is tested in FF3, IE7, Chrome 1 and Opera 9).
更新2:这是我在自己的库中实现它的方法:(之前的代码在Chrome中不起作用,因为Node和HTMLElement是函数而不是预期的对象。此代码在FF3、IE7、chrome1和Opera 9中进行测试。
//Returns true if it is a DOM node
function isNode(o){
return (
typeof Node === "object" ? o instanceof Node :
o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName==="string"
);
}
//Returns true if it is a DOM element
function isElement(o){
return (
typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2
o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName==="string"
);
}
#2
15
The following IE7 compatible, super-simple code works perfectly.
下面的IE7兼容,超级简单的代码完美的工作。
The accepted answer does not detect all types of HTML elements. For example, SVG elements are not supported. In contrast, this answer works for HTML well as SVG.
被接受的答案没有检测到所有类型的HTML元素。例如,不支持SVG元素。相比之下,这个答案对HTML和SVG都有效。
See it in action here: https://jsfiddle.net/eLuhbu6r/
请参见这里的操作:https://jsfiddle.net/eLuhbu6r/。
function isElement(element) {
return element instanceof Element;
}
#3
11
All solutions above and below (my solution including) suffer from possibility of being incorrect, especially on IE — it is quite possible to (re)define some objects/methods/properties to mimic a DOM node rendering the test invalid.
上面和下面的所有解决方案(包括我的解决方案)都有可能出现错误,特别是在IE上,很有可能定义一些对象/方法/属性来模拟DOM节点,使测试无效。
So usually I use the duck-typing-style testing: I test specifically for things I use. For example, if I want to clone a node I test it like this:
因此,我通常使用鸭子类型的测试:我专门测试我使用的东西。例如,如果我想克隆一个节点,我就像这样测试它:
if(typeof node == "object" && "nodeType" in node &&
node.nodeType === 1 && node.cloneNode){
// most probably this is a DOM node, we can clone it safely
clonedNode = node.cloneNode(false);
}
Basically it is a little sanity check + the direct test for a method (or a property) I am planning to use.
基本上,它是一个小的完整性检查+对一个方法(或一个属性)的直接测试,我打算使用它。
Incidentally the test above is a good test for DOM nodes on all browsers. But if you want to be on the safe side always check the presence of methods and properties and verify their types.
顺便提一下,上面的测试对于所有浏览器上的DOM节点都是一个很好的测试。但是,如果你想要安全起见,总是检查方法和属性的存在,并验证它们的类型。
EDIT: IE uses ActiveX objects to represent nodes, so their properties do not behave as true JavaScript object, for example:
EDIT: IE使用ActiveX对象来表示节点,因此它们的属性不能作为真正的JavaScript对象,例如:
console.log(typeof node.cloneNode); // object
console.log(node.cloneNode instanceof Function); // false
while it should return "function" and true
respectively. The only way to test methods is to see if the are defined.
而它应该分别返回“函数”和“真”。测试方法的唯一方法是查看是否定义了。
#4
6
You could try appending it to a real DOM node...
您可以尝试将其添加到一个真正的DOM节点…
function isDom(obj)
{
var elm = document.createElement('div');
try
{
elm.appendChild(obj);
}
catch (e)
{
return false;
}
return true;
}
#5
5
How about Lo-Dash's _.isElement
?
Lo-Dash _.isElement的怎么样?
$ npm install lodash.iselement
And in the code:
和代码:
var isElement = require("lodash.iselement");
isElement(document.body);
#6
5
This is from the lovely JavaScript library MooTools:
这是来自可爱的JavaScript库MooTools:
if (obj.nodeName){
switch (obj.nodeType){
case 1: return 'element';
case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
}
}
#7
4
The using the root detection found here, we can determine whether e.g. alert is a member of the object's root, which is then likely to be a window:
使用在这里找到的根检测,我们可以确定是否例如警告是对象根的成员,它很可能是一个窗口:
function isInAnyDOM(o) {
return (o !== null) && !!(o.ownerDocument && (o.ownerDocument.defaultView || o.ownerDocument.parentWindow).alert); // true|false
}
To determine whether the object is the current window is even simpler:
要确定对象是否为当前窗口,则更简单:
function isInCurrentDOM(o) {
return (o !== null) && !!o.ownerDocument && (window === (o.ownerDocument.defaultView || o.ownerDocument.parentWindow)); // true|false
}
This seems to be less expensive than the try/catch solution in the opening thread.
这似乎比打开线程中的try/catch解决方案要便宜。
Don P
没有P
#8
4
old thread, but here's an updated possibility for ie8 and ff3.5 users:
旧的线程,但是这是ie8和ff3.5用户更新的可能性:
function isHTMLElement(o) {
return (o.constructor.toString().search(/\object HTML.+Element/) > -1);
}
#9
3
var IsPlainObject = function ( obj ) { return obj instanceof Object && ! ( obj instanceof Function || obj.toString( ) !== '[object Object]' || obj.constructor.name !== 'Object' ); },
IsDOMObject = function ( obj ) { return obj instanceof EventTarget; },
IsDOMElement = function ( obj ) { return obj instanceof Node; },
IsListObject = function ( obj ) { return obj instanceof Array || obj instanceof NodeList; },
// In fact I am more likely t use these inline, but sometimes it is good to have these shortcuts for setup code
//事实上,我更可能不使用这些内联,但是有时候有这些设置代码的快捷方式很好。
#10
3
This could be helpful: isDOM
这可能很有用:isDOM。
//-----------------------------------
// Determines if the @obj parameter is a DOM element
function isDOM (obj) {
// DOM, Level2
if ("HTMLElement" in window) {
return (obj && obj instanceof HTMLElement);
}
// Older browsers
return !!(obj && typeof obj === "object" && obj.nodeType === 1 && obj.nodeName);
}
In the code above, we use the double negation operator to get the boolean value of the object passed as argument, this way we ensure that each expression evaluated in the conditional statement be boolean, taking advantage of the Short-Circuit Evaluation, thus the function returns true
or false
在上面的代码中,我们使用双重否定操作符来获取作为参数传递的对象的布尔值,这样我们可以确保在条件语句中计算的每个表达式都是布尔值,利用了短路评估的优点,从而使函数返回true或false。
#11
2
You can see if the object or node in question returns a string type.
您可以看到问题中的对象或节点是否返回一个字符串类型。
typeof (array).innerHTML === "string" => false
typeof (object).innerHTML === "string" => false
typeof (number).innerHTML === "string" => false
typeof (text).innerHTML === "string" => false
//any DOM element will test as true
typeof (HTML object).innerHTML === "string" => true
typeof (document.createElement('anything')).innerHTML === "string" => true
#12
2
For the ones using Angular:
对于使用角的人:
angular.isElement
https://docs.angularjs.org/api/ng/function/angular.isElement
https://docs.angularjs.org/api/ng/function/angular.isElement
#13
1
In Firefox, you can use the instanceof Node
. That Node
is defined in DOM1.
在Firefox中,可以使用instanceof节点。该节点在DOM1中定义。
But that is not that easy in IE.
但在IE中这并不容易。
- "instanceof ActiveXObject" only can tell that it is a native object.
- “instanceof ActiveXObject”只能说明它是一个本机对象。
- "typeof document.body.appendChild=='object'" tell that it may be DOM object, but also can be something else have same function.
- “typeof document.body。appendChild=='object'"说明它可能是DOM对象,但也可以是其他具有相同功能的东西。
You can only ensure it is DOM element by using DOM function and catch if any exception. However, it may have side effect (e.g. change object internal state/performance/memory leak)
您只能通过使用DOM函数确保它是DOM元素,并捕获任何异常。但是,它可能有副作用(例如,更改对象的内部状态/性能/内存泄漏)
#14
1
Perhaps this is an alternative? Tested in Opera 11, FireFox 6, Internet Explorer 8, Safari 5 and Google Chrome 16.
也许这是另一种选择?测试在Opera 11, FireFox 6, Internet Explorer 8, Safari 5和谷歌Chrome 16。
function isDOMNode(v) {
if ( v===null ) return false;
if ( typeof v!=='object' ) return false;
if ( !('nodeName' in v) ) return false;
var nn = v.nodeName;
try {
// DOM node property nodeName is readonly.
// Most browsers throws an error...
v.nodeName = 'is readonly?';
} catch (e) {
// ... indicating v is a DOM node ...
return true;
}
// ...but others silently ignore the attempt to set the nodeName.
if ( v.nodeName===nn ) return true;
// Property nodeName set (and reset) - v is not a DOM node.
v.nodeName = nn;
return false;
}
Function won't be fooled by e.g. this
函数不会被这样的函数所欺骗。
isDOMNode( {'nodeName':'fake'} ); // returns false
#15
1
This is what I figured out:
这就是我想出来的:
var isHTMLElement = (function () {
if ("HTMLElement" in window) {
// Voilà. Quick and easy. And reliable.
return function (el) {return el instanceof HTMLElement;};
} else if ((document.createElement("a")).constructor) {
// We can access an element's constructor. So, this is not IE7
var ElementConstructors = {}, nodeName;
return function (el) {
return el && typeof el.nodeName === "string" &&
(el instanceof ((nodeName = el.nodeName.toLowerCase()) in ElementConstructors
? ElementConstructors[nodeName]
: (ElementConstructors[nodeName] = (document.createElement(nodeName)).constructor)))
}
} else {
// Not that reliable, but we don't seem to have another choice. Probably IE7
return function (el) {
return typeof el === "object" && el.nodeType === 1 && typeof el.nodeName === "string";
}
}
})();
To improve performance I created a self-invoking function that tests the browser's capabilities only once and assigns the appropriate function accordingly.
为了提高性能,我创建了一个自调用函数,它只测试一次浏览器的功能,并相应地分配相应的功能。
The first test should work in most modern browsers and was already discussed here. It just tests if the element is an instance of HTMLElement
. Very straightforward.
第一个测试应该在大多数现代浏览器中工作,并且已经在这里讨论过了。它只是测试元素是否是HTMLElement的实例。非常简单。
The second one is the most interesting one. This is its core-functionality:
第二个是最有趣的一个。这是它的核心功能:
return el instanceof (document.createElement(el.nodeName)).constructor
It tests whether el is an instance of the construcor it pretends to be. To do that, we need access to an element's contructor. That's why we're testing this in the if-Statement. IE7 for example fails this, because (document.createElement("a")).constructor
is undefined
in IE7.
它测试el是否是构造函数的实例,或者它假装成。要做到这一点,我们需要访问一个元素的contructor。这就是我们在if-Statement中测试这个的原因。例如,IE7失败了,因为(document.createElement(“a”))。构造函数在IE7中没有定义。
The problem with this approach is that document.createElement
is really not the fastest function and could easily slow down your application if you're testing a lot of elements with it. To solve this, I decided to cache the constructors. The object ElementConstructors
has nodeNames as keys with its corresponding constructors as values. If a constructor is already cached, it uses it from the cache, otherwise it creates the Element, caches its constructor for future access and then tests against it.
这种方法的问题在于文档。createElement并不是最快的函数,如果你用它来测试很多元素,它可以很容易地降低应用程序的速度。为了解决这个问题,我决定缓存构造函数。对象元素构造函数以其对应的构造函数作为值作为键。如果构造函数已经被缓存,它将从缓存中使用它,否则它将创建元素,缓存它的构造函数以供将来访问,然后对其进行测试。
The third test is the unpleasant fallback. It tests whether el is an object
, has a nodeType
property set to 1
and a string as nodeName
. This is not very reliable of course, yet the vast majority of users shouldn't even fall back so far.
第三个考验是令人不快的退却。它测试el是否为对象,将nodeType属性设置为1,字符串为nodeName。当然,这并不是很可靠,但绝大多数用户甚至不应该退回到目前为止。
This is the most reliable approach I came up with while still keeping performance as high as possible.
这是我提出的最可靠的方法,同时仍然保持尽可能高的性能。
#16
1
Test if obj
inherits from Node.
测试obj是否从节点继承。
if (obj instanceof Node){
// obj is a DOM Object
}
Node is a basic Interface from which HTMLElement and Text inherit.
Node是HTMLElement和Text继承的基本接口。
#17
1
I think prototyping is not a very good solution but maybe this is the fastest one: Define this code block;
我认为原型设计不是一个很好的解决方案,但也许这是最快的方法:定义这个代码块;
Element.prototype.isDomElement = true;
HTMLElement.prototype.isDomElement = true;
than check your objects isDomElement property:
不要检查你的对象isDomElement属性:
if(a.isDomElement){}
I hope this helps.
我希望这可以帮助。
#18
1
differentiate a raw js object from a HTMLElement
将一个原始js对象与一个HTMLElement区分开来。
function isDOM (x){
return /HTML/.test( {}.toString.call(x) );
}
use:
使用:
isDOM( {a:1} ) // false
isDOM( document.body ) // true
// OR
/ /或
Object.defineProperty(Object.prototype, "is",
{
value: function (x) {
return {}.toString.call(this).indexOf(x) >= 0;
}
});
use:
使用:
o={}; o.is("HTML") // false o=document.body; o.is("HTML") // true
o = { };o.is(HTML)/ /假o = document.body;o.is(HTML)/ /真实的
#19
0
I think that what you have to do is make a thorough check of some properties that will always be in a dom element, but their combination won't most likely be in another object, like so:
我认为你需要做的是彻底检查一些属性,这些属性总是在dom元素中,但是它们的组合不太可能出现在另一个对象中,比如:
var isDom = function (inp) {
return inp && inp.tagName && inp.nodeName && inp.ownerDocument && inp.removeAttribute;
};
#20
0
here's a trick using jQuery
这里有一个使用jQuery的技巧。
var obj = {};
var element = document.getElementById('myId'); // or simply $("#myId")
$(obj).html() == undefined // true
$(element).html() == undefined // false
so putting it in a function:
所以把它放在一个函数中
function isElement(obj){
return (typeOf obj === 'object' && !($(obj).html() == undefined));
}
#21
0
Not to hammer on this or anything but for ES5-compliant browsers why not just:
不要在这个或其他任何东西上敲打,而是为了符合es5的浏览器,为什么不只是:
function isDOM(e) {
return (/HTML(?:.*)Element/).test(Object.prototype.toString.call(e).slice(8, -1));
}
Won't work on TextNodes and not sure about Shadow DOM or DocumentFragments etc. but will work on almost all HTML tag elements.
不能在textnode上工作,也不能确定阴影DOM或DocumentFragments等,但几乎可以处理所有HTML标记元素。
#22
0
This will work for almost any browser. (No distinction between elements and nodes here)
这几乎适用于任何浏览器。(这里的元素和节点没有区别)
function dom_element_check(element){
if (typeof element.nodeType !== 'undefined'){
return true;
}
return false;
}
#23
0
A absolute right method, check target is a real html element primary code:
一个绝对正确的方法,检查目标是一个真正的html元素的主代码:
(function (scope) {
if (!scope.window) {//May not run in window scope
return;
}
var HTMLElement = window.HTMLElement || window.Element|| function() {};
var tempDiv = document.createElement("div");
var isChildOf = function(target, parent) {
if (!target) {
return false;
}
if (parent == null) {
parent = document.body;
}
if (target === parent) {
return true;
}
var newParent = target.parentNode || target.parentElement;
if (!newParent) {
return false;
}
return isChildOf(newParent, parent);
}
/**
* The dom helper
*/
var Dom = {
/**
* Detect if target element is child element of parent
* @param {} target The target html node
* @param {} parent The the parent to check
* @returns {}
*/
IsChildOf: function (target, parent) {
return isChildOf(target, parent);
},
/**
* Detect target is html element
* @param {} target The target to check
* @returns {} True if target is html node
*/
IsHtmlElement: function (target) {
if (!X.Dom.IsHtmlNode(target)) {
return false;
}
return target.nodeType === 1;
},
/**
* Detect target is html node
* @param {} target The target to check
* @returns {} True if target is html node
*/
IsHtmlNode:function(target) {
if (target instanceof HTMLElement) {
return true;
}
if (target != null) {
if (isChildOf(target, document.documentElement)) {
return true;
}
try {
tempDiv.appendChild(target.cloneNode(false));
if (tempDiv.childNodes.length > 0) {
tempDiv.innerHTML = "";
return true;
}
} catch (e) {
}
}
return false;
}
};
X.Dom = Dom;
})(this);
#24
0
Each DOMElement.constructor returns function HTML...Element() or [Object HTML...Element] so...
每个DOMElement。构造函数返回函数HTML…元素()或[对象HTML…元素)所以…
function isDOM(getElem){
if(getElem===null||typeof getElem==="undefined") return false;
var c = getElem.constructor.toString();
var html = c.search("HTML")!==-1;
var element = c.search("Element")!==-1;
return html&&element;
}
#25
0
I have a special way to do this that has not yet been mentioned in the answers.
我有一种特殊的方法来做这个,在答案中还没有提到。
My solution is based on four tests. If the object passes all four, then it is an element:
我的解决方案是基于四个测试。如果物体经过所有四个,那么它就是一个元素:
-
The object is not null.
对象不为空。
-
The object has a method called "appendChild".
该对象有一个名为“appendChild”的方法。
-
The method "appendChild" was inherited from the Node class, and isn't just an imposter method (a user-created property with an identical name).
方法“appendChild”是从节点类继承而来的,它不只是一个imposter方法(一个用户创建的具有相同名称的属性)。
-
The object is of Node Type 1 (Element). Objects that inherit methods from the Node class are always Nodes, but not necessarily Elements.
对象是节点类型1(元素)。从节点类继承方法的对象总是节点,但不一定是元素。
Q: How do I check if a given property is inherited and isn't just an imposter?
问:我如何检查给定的属性是否继承,而不只是一个冒名顶替者?
A: A simple test to see if a method was truly inherited from Node is to first verify that the property has a type of "object" or "function". Next, convert the property to a string and check if the result contains the text "[Native Code]". If the result looks something like this:
A:一个简单的测试,看看一个方法是否真正从节点继承,首先要验证该属性是否具有“对象”或“函数”的类型。接下来,将属性转换为字符串,并检查结果是否包含文本“[本机代码]”。如果结果是这样的:
function appendChild(){
[Native Code]
}
Then the method has been inherited from the Node object. See https://davidwalsh.name/detect-native-function
然后该方法从节点对象继承。参见https://davidwalsh.name/detect-native-function
And finally, bringing all the tests together, the solution is:
最后,把所有的测试结合起来,解决方案是:
function ObjectIsElement(obj) {
var IsElem = true;
if (obj == null) {
IsElem = false;
} else if (typeof(obj.appendChild) != "object" && typeof(obj.appendChild) != "function") {
//IE8 and below returns "object" when getting the type of a function, IE9+ returns "function"
IsElem = false;
} else if ((obj.appendChild + '').replace(/[\r\n\t\b\f\v\xC2\xA0\x00-\x1F\x7F-\x9F ]/ig, '').search(/\{\[NativeCode]}$/i) == -1) {
IsElem = false;
} else if (obj.nodeType != 1) {
IsElem = false;
}
return IsElem;
}
#26
0
No need for hacks, you can just ask if an element is an instance of the Element:
不需要黑客,您可以询问元素是否为元素的实例:
const isElement = element => {
element instanceof Element;
};
#27
0
(element instanceof $ && element.get(0) instanceof Element) || element instanceof Element
This will check for even if it is a jQuery or JavaScript DOM element
这将检查是否为jQuery或JavaScript DOM元素。
#28
0
I suggest a simple way to testing if a variable is an DOM element
我建议用一种简单的方法来测试变量是否是DOM元素。
function isDomEntity(entity) {
if( typeof entity === 'object' && entity.nodeType != undefined){
return true;
}
else{
return false;
}
}
#29
-1
var isElement = function(e){
try{
// if e is an element attached to the DOM, we trace its lineage and use native functions to confirm its pedigree
var a = [e], t, s, l = 0, h = document.getElementsByTagName('HEAD')[0], ht = document.getElementsByTagName('HTML')[0];
while(l!=document.body&&l!=h&&l.parentNode) l = a[a.push(l.parentNode)-1];
t = a[a.length-1];
s = document.createElement('SCRIPT'); // safe to place anywhere and it won't show up
while(a.length>1){ // assume the top node is an element for now...
var p = a.pop(),n = a[a.length-1];
p.insertBefore(s,n);
}
if(s.parentNode)s.parentNode.removeChild(s);
if(t!=document.body&&t!=h&&t!=ht)
// the top node is not attached to the document, so we don't have to worry about it resetting any dynamic media
// test the top node
document.createElement('DIV').appendChild(t).parentNode.removeChild(t);
return e;
}
catch(e){}
return null;
}
I tested this on Firefox, Safari, Chrome, Opera and IE9. I couldn't find a way to hack it.
In theory, it tests every ancestor of the proposed element, as well as the element itself, by inserting a script tag before it.
If its first ancestor traces back to a known element, such as <html>
, <head>
or <body>
, and it hasn't thrown an error along the way, we have an element.
If the first ancestor is not attached to the document, we create an element and attempt to place the proposed element inside of it, (and then remove it from the new element).
So it either traces back to a known element, successfully attaches to a known element or fails.
It returns the element or null if it is not an element.
我在Firefox、Safari、Chrome、Opera和IE9上做了测试。我找不到办法破解它。理论上,它通过在前面插入一个脚本标记来测试所提议元素的每个祖先,以及元素本身。如果它的第一个祖先可以追溯到一个已知的元素,比如, 或,并且它在这个过程中没有抛出一个错误,我们有一个元素。如果第一个祖先没有附加到文档,我们创建一个元素并尝试将所提议的元素放入其中,(然后从新元素中删除它)。因此,它可以追溯到已知元素,成功地连接到已知元素或失败。如果元素不是元素,它将返回元素或null。
#30
-1
The easiest and cross-browser way to detect if an element is part of HTML DOM is as below:
如果一个元素是HTML DOM的一部分,最简单、最跨浏览器的方法是:
function inHTMLDom(myelement){
if(myelement.ownerDocument.documentElement.tagName.toLowerCase()=="html"){
return true;
}else{
return false;
}
}
inHTMLDom(<your element>); // <your element>:element you are interested in checking.
tested in IE6,IE7,IE8,IE9,IE10,FF,Chrome,Safari,Opera.
测试在IE6,IE7,IE8,IE9,IE10浏览器,火狐,Chrome,Safari、Opera。