Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Является ли объект DOM объектом (https://javascript.ru/forum/events/46005-yavlyaetsya-li-obekt-dom-obektom.html)

Hapson 24.03.2014 20:29

Является ли объект DOM объектом
 
Пишу я функцию.
Функция принимает в параметре DOM элемент.
В процессе работы функция может имитировать клик по переданному элементу.
function foo(elem){
    elem.click();
    // or
    elem.submit()
}

Это будет модуль ajax проверки авторизации перед действием, но суть не в этом.
Нужно в функции сразу проверить, является переданный параметр DOM элементом. Ну и в разумных пределах отфильтровать, так как head и body тоже имеют метод click.
var doc = document;
var head = document.head;
var body = document.body;
var div = document.getElementById("dv");

console.log("document");
console.log("nodeType: "+ doc.nodeType);
console.log("typeObject: "+ new Object().toString.call(doc));
console.log("click: "+ doc.click);
console.log("---");

console.log("head");
console.log("nodeType: "+ head.nodeType);
console.log("typeObject: "+ new Object().toString.call(head));
console.log("click: "+ head.click);
console.log("---");

console.log("body");
console.log("nodeType: "+ doc.nodeType);
console.log("typeObject: "+ new Object().toString.call(body));
console.log("click: "+ body.click);
console.log("---");

console.log("div");
console.log("nodeType: "+ doc.nodeType);
console.log("typeObject: "+ new Object().toString.call(div));
console.log("click: "+ div.click);

Код:

document
nodeType: 9
typeObject: [object HTMLDocument]
click: undefined
---
head
nodeType: 1
typeObject: [object HTMLHeadElement]
click: function click() {
    [native code]
}
---
body
nodeType: 9
typeObject: [object HTMLBodyElement]
click: function click() {
    [native code]
}
---
div
nodeType: 9
typeObject: [object HTMLDivElement]
click: function click() {
    [native code]
}


Hapson 24.03.2014 21:35

if(typeof element.nodeType === "undefined" || element.nodeType !== 1 || /^(HTML|HEAD|BODY)$/i.test(element.nodeName)){}

Больше ниче в голову не приходит

nerv_ 24.03.2014 23:02

Я делал так, но тесты оставляют желать лучшего.

Кроме того, если ты проверяешь на DOM элемент, вероятно, тебе следует пересмотреть функцию/архитектуру.

Hapson 24.03.2014 23:24

Цитата:

Сообщение от nerv_
Кроме того, если ты проверяешь на DOM элемент, вероятно, тебе следует пересмотреть функцию/архитектуру

Почему?
Функция принимает DOM элемент, по которому кликнул пользователь. Сразу же отменяет действие возвращая false. Проверяет на сервере авторизацию пользователя и если все нормально, то эмулирует отмененное действие. Но перед тем как начать работать, функция должна удостовериться, что ей передали действительно DOM элемент, к которому применим click или submit. Ну и html, head и body отбрасываются

Hapson 24.03.2014 23:40

Цитата:

Сообщение от nerv_
Я делал так

Я таким макаром написал isArray и isObject
$G.isObject = function(test){
	if(test === null || test === undefined){return false;}
	return ({}.toString.call(test) == "[object Object]");
};

$G.isArray = function(test){
	if(test === null || test === undefined){return false;}
	return ({}.toString.call(test) == "[object Array]");
};

Sweet 25.03.2014 00:22

Проверять через Object.prototype.toString в IE не вариант. Например, в 9-м выдаёт "[object Object]", ибо никаких HTMLElement или HTMLDivElement там нет.

nerv_ 25.03.2014 01:59

Цитата:

Сообщение от Sweet
Например, в 9-м выдаёт "[object Object]"

в восьмом. Только что проверил. В девятом норм, кроме document

Тем не менее, соглашусь, что это не очень надежная проверка :)

Вероятно, можно проверить, например, так (IE9+):
function isElement(v) {
    if (typeof v !== 'object') return false;
    if (v === null) return false;
    var c = window.HTMLDocument || window.Document;
    return v instanceof c || v instanceof window.HTMLElement;
}

alert(isElement(document));
alert(isElement(document.documentElement));
alert(isElement(document.head));
alert(isElement(document.body));
alert(isElement(null));
alert(isElement({}));


upd: А вообще, как ты гуглил?

Sweet 25.03.2014 02:24

Цитата:

Сообщение от nerv_
В девятом норм, кроме document

Действительно, норм. Я без DOCTYPE проверял, в режиме совместимости.

Vlasenko Fedor 25.03.2014 02:50

Может проверять есть ли у элемента родитель (parentElement, parentNode) и от этого стартовать. Это так мысли вслух :)

Octane 25.03.2014 06:23

Цитата:

Сообщение от Hapson
функция должна удостовериться, что ей передали действительно DOM элемент, к которому применим click или submit

проверяй инстанс EventTarget
function isEventTarget(obj) {
	return Object(obj) === obj && obj instanceof EventTarget;
}
на этом бы и остановились, если бы не IE, даже в 11 нет EventTarget, поэтому перечислим конструкторы объектов, имеющих события
//IE8+
function isEventTarget(obj) {
	return Object(obj) === obj && [
		obj instanceof (window.EventTarget || function () {}),
		obj instanceof (window.HTMLElement || window.Element),
		obj instanceof HTMLDocument,
		obj instanceof Window,
		obj instanceof XMLHttpRequest
	].indexOf(true) != -1;
}
ну и по желанию можно дописать всякие Comment, Text и др., чтобы сравнять результаты во всех браузерах


Часовой пояс GMT +3, время: 20:50.