Является ли объект 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 |
if(typeof element.nodeType === "undefined" || element.nodeType !== 1 || /^(HTML|HEAD|BODY)$/i.test(element.nodeName)){} Больше ниче в голову не приходит |
|
Цитата:
Функция принимает DOM элемент, по которому кликнул пользователь. Сразу же отменяет действие возвращая false. Проверяет на сервере авторизацию пользователя и если все нормально, то эмулирует отмененное действие. Но перед тем как начать работать, функция должна удостовериться, что ей передали действительно DOM элемент, к которому применим click или submit. Ну и html, head и body отбрасываются |
Цитата:
$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]"); }; |
Проверять через Object.prototype.toString в IE не вариант. Например, в 9-м выдаёт "[object Object]", ибо никаких HTMLElement или HTMLDivElement там нет.
|
Цитата:
Тем не менее, соглашусь, что это не очень надежная проверка :) Вероятно, можно проверить, например, так (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: А вообще, как ты гуглил? |
Цитата:
|
Может проверять есть ли у элемента родитель (parentElement, parentNode) и от этого стартовать. Это так мысли вслух :)
|
Цитата:
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 и др., чтобы сравнять результаты во всех браузерах |
Octane,
Чет я ниче не понял. А если так function isDomElement(el, type){ return typeof el.nodeType !== "undefined" && el.nodeType === type; } Ведь click() есть у каждого DOM элемента. Ну а у формы есть submit |
Или даже так
function isDomElement(el, type){ return typeof type === "number" ? el.nodeType === type : typeof el.nodeType === "number"; } |
Я про то, что ты не свою задачу решаешь, тебе нужен объект с событиями, а ты проверяешь тип, проверяй возможность использовать события
Для твоей задачи вообще достаточно function isEventTarget(obj) { return "addEventListener" in Object(obj); } |
Octane,
Нет мне не нужны события, мне нужно вот что: function(elem){ // проверяем, что elem - DOM элемент // ... что-то делаем // а теперь делаем elem.click(); // или elem.submit(); } То есть, вот например: Пользователь кликает по ссылке, но прежде чем он перейдет, нужно на лету проверить его авторизацию. Для этого функция отмеить его действие и после успешной проверки эмулирует это действие. Это может быть клик по ссылке, отправка формы и т.д... |
Цитата:
Мне же нужен DOM элемент, по которому можно кликнуть мышкой. Сюда же входят и формы |
Вот наглядный пример:
<a href="#" id="link">Link</a> <script> EventHandler.add(document.getElementById("link"), click, checkAction); function checkAction(){ // функция перехватывает действие пользователя // что-то делает... // может проверяет форму, если вместо <a> перехватила <form> // И теперь функция хочет проверить, не закончилась ли сессия пользователя // Она обращается к модулю из общей библиотеки // и передает ему элемент, с которого перехватила событие click или submit return issetSeance(this); } /******/ function issetSeance(elem){ // упрощенно: если у переданного элемента нет метода click или submit // просто вернуть true и не отменять действие пользователя if(!elem.click || !elem.submit){return true;} // если указанные методы присутствуют, то запустить модуль проверки авторизации checkLogin(elem); return false; } function checkLogin(elem){ // тут общаемся с сервером // в случае успеха делаем elem.click() // если не форма elem.submit() // если форма } </script> |
И вот в функции issetSeance() мне нужно проверить, что передан DOM элемент, у которого есть метод click() или submit(), и что этот элемент не HTML, не BODY и не HEAD
|
Цитата:
Ну и, click ко всему применим. |
Цитата:
Ну я же привел пример. Я не знаю, как еще подробнее... Функция, которая перехватывает действие пользователя должна вернуть true или false. Она вместо этого обращается к модулю проверки авторизации. И уже модуль должен вернуть true или false. Теперь: 1) модуль проверяет, что ему дали DOM объект и у этого объекта есть метод click() или submit(). Нахрена ему это - ниже 2) если модулю передали что-то не то, то он вернет true и просто не начнет работать. 3) если модулю передали DOM объект, у которого есть метод click() или submit(), то он возвращает false и начинает работать. 4) модуль делает запрос на сервер - авторизован ли пользователь 5) авторизован - имитируем действие пользователя, которое сами же и отменили. То есть кликаем программно по чем он там кликал |
Нахрена я отменяю действие пользователя, а потом имитирую его программно?
Потому как я не знаю как поставить скрипт на паузу, пока выполняется асинхронный запрос(ы) |
Цитата:
|
Почему бы просто не выполнять никаких действий, пока от сервера не придет ответ?)
Цитата:
|
Цитата:
http://learn.javascript.ru/ajax-xmlhttprequest#синхронный-вызов Но лучше так не делать. |
Цитата:
Цитата:
|
Цитата:
Цитата:
Цитата:
|
Hapson, а не пофиг ли, Dom-объект - не Dom? Тебе нужно вызвать метод, вот и проверяй его наличие:
if (isFunction(elem.click)) elem.click(); |
Цитата:
Цитата:
Если копнуть еще глубже, то ему не надо вызывать методы клик и сабмит у дум нод, т.к. это та же самая "ошибка в архитектуре" :) Цитата:
|
Если в гугле нет описания проблемы, возникшей в процессе решения стандартной задачи - скорее всего, решение неверное.
|
Цитата:
Пользователь пишет статью, в процессе его сеанс заканчивается и он становится неавторизованным юзером. Но он узнает об этом лишь когда его выкинет на страницу авторизации при попытке сохранить статью. Я написал на php функционал хранения данных, которые пользователь вводил, так что катастрофы не будет, если юзер там поэму настрочил - все восстановится. Но вот захотел я сделать так, чтобы авторизация проверялась перед отправкой формы и чтобы подтвердить авторизацию юзер мог тутже - без перебросов на другие страницы. Ну общие черты понятны думаю... едем дальше. У движка сайта есть общая javascript библиотека со всякими функциями и даже модулями. В свою очередь, у каждого модуля сайта (в данном случае у модуля управления статьями) тоже есть свой набор скриптов javascript. У модуля управления статьями есть скриптик, который перехватывает форму добавления статьи и поверхностно ее проверяет перед отправкой на сервер. И тут я решил, что хорошо бы было, если бы перед отправкой формы была бы еще и проверка авторизации. Я начал писать эту проверку в составе скрипта модуля статей. Но тут я подумал... а ведь потом я буду писать модуль управления комментариями, и там тоже не помешала бы фишка проверки авторизации перед отправкой комментария. Че делать? Потом писать аналогичную проверку в модуле комментариев? Нет наверно, нахрена одно и тоже переписывать. Поэтому я решил написать модуль проверки авторизации, который смогут использовать все - любой модуль сайта. Естественно этот модуль вошел в состав общей javascript библиотеки. У модуля есть два открытых метода isLogin() и isLogin.setup(). Один конфигурирует модуль, второй используется a функции перехвата действия пользователя. То есть скрипт перехватил форму, проверил ее и он делает return isLogin(); И все. Теперь модуль проверки авторизации решает, что вернуть - true или false. Так как модуль будет делать асинхронные ajax запросы, то он должен сразу что-то вернуть. В данном случае он отменяет действие пользователя и проверяет авторизацию. Не отменить я не могу, так как никто ждать не будет, пока вернется ответ сервера. Поэтому, в модуль авторизации передается объект, по которому кликнул пользователь. Если с объектом все ОК, то модуль просто возвращает false и начинает делать свою работу. nerv_ Что не так с архитектурой? Есть другие способы? Синхронные запросы не предлагать. |
Цитата:
Ну вот нет такого описания. А вся проблема сводится к другой проблеме: Как остановить скрипт на время выполнения ajax запроса. Ответа два: НИКАК или синхронный запрос. Ни то, ни другое не подходит. Но вот многие пишут, что при таком раскладе просто отменяют действие юзера, а потом если все ОК эмулируют его программно (click, submit). И это единственное подходящее решение. |
Цитата:
|
Цитата:
Но слишком обобщать - тоже не хорошо. При чрезмерном повышении уровня теряется гибкость. |
Цитата:
Вот функция которая перехватила форму function checkForm(){ // проверяет форму... // нет у нас никаких модулей проверки авторизации, тупо делаем все тут // нужно сделать ajax запрос... // запрос асинхронный - никто никого не ждет... // все нужно что-то вернуть - true или false... что вернуть!? // если вернуть true - форма уйдет и все проверки авторизации идет лесом // если false - то нужно потом при удачной проверке или удачном подтверждении (а это еще запросы) сделать submit этой чертовой формы } |
Смысл в том, что я перехватил клик юзера и нужно что-то решать. Но я не могу ничего решить пока не получу ответ сервера.
|
Ну так делай/не делай субмит программно по приходу ответа от сервера, когда уже будешь знать, авторизован ли пользователь.
|
<script> function send_data() { //Хорошей идеей было бы оповестить пользователя, что идет проверка авторизации. //Делаем запрос на сервер, вешаем колбек с соответствующими проверками - если пользователь авторизован, делаем document.getElementById("myform").submit(), не авторизован - выдаем ошибку, открываем окно авторизации. } </script> <form id="myform" action="data_reciever.php"> <textarea></textarea> <button onclick="send_data()">Отправить</button> </form> |
Цитата:
Но только товарищ nerv_ считает это корявой акхитектурой. Единственным условием для успешного запуска модуля проверки авторизации, является передача ему ссылки на объект, по которому кликнул юзер, будь то кнопка, ссылка, форма... неважно. Главное чтоб это был объект, у которого есть click() или submit(); Так сделано, потому что модуль как бы общий, и использовать его может любой модуль сайта. Ладно, проблема-то решена уже давно |
Erolast,
Да... если задержка более 500мс, то юзер увидит анимацию и оповещение, что скрипт чего-то там делает... надо обождать. Это тоже все уже есть |
Цитата:
И не надо никуда никаких элементов передавать. |
Цитата:
http://javascript.ru/forum/events/46...tml#post304218 Цитата:
Если ему передали DOM объект на котором произошел click, то он отменить действие и приступит к работе. В случае успешной проверки на сервере или при любых ошибках в работе, он программно совершит отмененное действие. Если юзер потерял авторизацию, то будет выведена форма авторизации. Если юзер верно введет все, то получить сообщение, типа все ОК пуляй форму. Если N-ное кол-во раз он неверно укажет логин/пароль, то скрипт отключится и перестанет перехватывать данные с формы авторизации. Ну и юзер уже физически отправится по action, указанный в форме авторизации, а там уже сервер ему что-то скажет |
Часовой пояс GMT +3, время: 06:18. |