Próbuję uzyskać:
document.createElement('div') //=> true
{tagName: 'foobar something'} //=> false
W moich własnych skryptach po prostu używałem tego, ponieważ nigdy nie potrzebowałem tagName
jako właściwości:
if (!object.tagName) throw ...;
W przypadku drugiego obiektu opracowałem następujące rozwiązanie jako szybkie rozwiązanie - które w większości działa. ;)
Problem polega na tym, że zależy to od przeglądarki wymuszającej właściwości tylko do odczytu, co nie wszystkie.
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;
}
}
Czy istnieje dobry zamiennik?
javascript
dom
object
Jonathan Lonowski
źródło
źródło
Odpowiedzi:
Może to być interesujące:
Jest częścią DOM, Level2 .
Aktualizacja 2 : tak zaimplementowałem go we własnej bibliotece: (poprzedni kod nie działał w Chrome, ponieważ Node i HTMLElement są funkcjami zamiast oczekiwanego obiektu. Ten kod jest testowany w FF3, IE7, Chrome 1 i Opera 9).
źródło
function Fake() {}; Fake.prototype=document.createElement("div"); alert(new Fake() instanceof HTMLElement);
true
do[] instanceof HTMLElement
.HTMLElement
zawsze jestfunction
, więctypeof
zrzuci cię z toru i wykona drugą część instrukcji. Możesz spróbować, jeśli chceszinstanceof Object
, ponieważ funkcja będzie instancjąObject
lub po prostu jawnie sprawdzitypeof === "function"
,Node
czy iHTMLElement
oba są rodzimymi funkcjami obiektowymi.isElement(0)
, zwraca 0, a nie fałsz ... Dlaczego tak jest i jak mogę temu zapobiec?Poniższy super-prosty kod kompatybilny z IE8 działa idealnie.
Odpowiedź Zaakceptowany nie wykrywa wszystkie typy elementów HTML. Na przykład elementy SVG nie są obsługiwane. Natomiast ta odpowiedź działa dobrze w przypadku HTML i SVG.
Zobacz to w akcji tutaj: https://jsfiddle.net/eLuhbu6r/
źródło
document
elementu (we wszystkich przeglądarkach). jeśli jej potrzebujesz, powinieneś spróbować:x instanceof Element || x instanceof HTMLDocument
Wszystkie rozwiązania powyżej i poniżej (w tym moje rozwiązanie) mogą być niepoprawne, szczególnie w IE - całkiem możliwe jest (ponowne) zdefiniowanie niektórych obiektów / metod / właściwości w celu naśladowania węzła DOM powodującego niepoprawność testu.
Dlatego zwykle używam testów typu kaczego: testuję specjalnie pod kątem rzeczy, których używam. Na przykład, jeśli chcę sklonować węzeł, testuję go w następujący sposób:
Zasadniczo jest to mały test poczytalności + bezpośredni test metody (lub właściwości), której zamierzam użyć.
Nawiasem mówiąc, powyższy test jest dobrym testem dla węzłów DOM we wszystkich przeglądarkach. Ale jeśli chcesz być bezpieczny, zawsze sprawdzaj obecność metod i właściwości oraz weryfikuj ich typy.
EDYCJA: IE używa obiektów ActiveX do reprezentowania węzłów, więc ich właściwości nie zachowują się jak prawdziwy obiekt JavaScript, na przykład:
podczas gdy powinien zwracać odpowiednio „funkcję” i
true
. Jedynym sposobem na przetestowanie metod jest sprawdzenie, czy są one zdefiniowane.źródło
Możesz spróbować dołączyć go do prawdziwego węzła DOM ...
źródło
obj.cloneNode(false)
. I nie ma skutków ubocznych.Nie potrzebujesz hacków, możesz po prostu zapytać, czy element jest instancją elementu DOM :
źródło
Co powiesz na Lo-Dash
_.isElement
?I w kodzie:
źródło
To jest z uroczej biblioteki JavaScript MooTools :
źródło
Za pomocą wykrytego tutaj rootowania możemy ustalić, czy np. Alert jest elementem root obiektu, który może wtedy być oknem:
Ustalenie, czy obiekt jest bieżącym oknem, jest jeszcze prostsze:
To wydaje się być tańsze niż rozwiązanie try / catch w wątku otwierającym.
Don P.
źródło
document.createElement()
ale nie wstawionych również w DOM. Niesamowite (: Dziękujęstary wątek, ale oto zaktualizowana możliwość dla użytkowników ie8 i ff3.5 :
źródło
Sugeruję prosty sposób sprawdzenia, czy zmienna jest elementem DOM
lub zgodnie z sugestią HTMLGuy :
źródło
return typeof entity === 'object' && typeof entity.nodeType !== undefined;
object
i / lub właściwości, może to być bardzo przydatne! Tx, @Roman// W rzeczywistości bardziej prawdopodobne jest, że użyję tych wbudowanych, ale czasami dobrze jest mieć te skróty do kodu instalacyjnego
źródło
Może to być pomocne: isDOM
W powyższym kodzie używamy operatora podwójnej negacji , aby uzyskać wartość logiczną obiektu przekazaną jako argument, w ten sposób upewniamy się, że każde wyrażenie ocenione w instrukcji warunkowej ma wartość logiczną, korzystając z oceny zwarcia , a zatem funkcji zwraca
true
lubfalse
źródło
undefined && window.spam("should bork")
na przykład nigdy nie ocenia fałszywejspam
funkcji. Więc nie!!
potrzebuję, nie wierzę. Czy możesz podać [nieakademicki] przypadek, w którym jego zastosowanie ma znaczenie?!!
argumentu „nigdy nie jest potrzebny” ( a jeśli nie, to jestem ciekawy, dlaczego nie ), możesz edytować ten wierszreturn !!(obj && typeof obj === "object" && obj.nodeType === 1 && obj.nodeName);
i sprawić, by działał tak samo.Możesz sprawdzić, czy dany obiekt lub węzeł zwraca typ ciągu.
źródło
typeof ({innerHTML: ""}).innerHTML === "string"
notANode.innerHTML = "<b>Whoops</b>";
, a potem kazał temu kodowi przekazać swój zanieczyszczony obiekt do tego kodu. Kod defensywny === lepszy kod, wszystkie inne rzeczy są równe, a to ostatecznie nie jest defensywne.Dla tych, którzy używają Angulara:
https://docs.angularjs.org/api/ng/function/angular.isElement
źródło
function isElement(node) { return !!(node && (node.nodeName || (node.prop && node.attr && node.find))); }
Wygląda trochę jak @ finpingvin's . Zauważ, że określa ono „ czy odwołanie jest elementem DOM (lub opakowanym elementem jQuery) ” .Myślę, że prototypowanie nie jest zbyt dobrym rozwiązaniem, ale być może jest to najszybsze: Zdefiniuj ten blok kodu;
niż sprawdź, czy twoja właściwość isDomElement:
Mam nadzieję, że to pomoże.
źródło
Według MDN
Możemy wdrożyć
isElement
przez prototyp. Oto moja rada:źródło
Myślę, że musisz dokładnie sprawdzić niektóre właściwości, które zawsze będą w elemencie dom, ale ich kombinacja najprawdopodobniej nie będzie w innym obiekcie, na przykład:
źródło
W przeglądarce Firefox możesz użyć
instanceof Node
. ToNode
jest zdefiniowane w DOM1 .Ale to nie jest takie proste w IE.
Możesz tylko upewnić się, że jest to element DOM, używając funkcji DOM i wychwytywać ewentualny wyjątek. Może jednak mieć efekt uboczny (np. Zmienić stan wewnętrzny obiektu / wydajność / wyciek pamięci)
źródło
Być może jest to alternatywa? Testowane w Opera 11, FireFox 6, Internet Explorer 8, Safari 5 i Google Chrome 16.
Funkcja nie da się oszukać np. Przez to
źródło
Oto co wymyśliłem:
Aby poprawić wydajność, stworzyłem funkcję samo-wywołującą, która testuje możliwości przeglądarki tylko raz i odpowiednio przypisuje odpowiednią funkcję.
Pierwszy test powinien działać w większości nowoczesnych przeglądarek i został już tutaj omówiony. Po prostu sprawdza, czy element jest instancją
HTMLElement
. Bardzo proste.Drugi jest najciekawszy. Oto jego podstawowa funkcjonalność:
Sprawdza, czy el jest instancją konstruktora, którym udaje. Aby to zrobić, potrzebujemy dostępu do konstruktora elementu. Dlatego testujemy to w instrukcji if. Na przykład IE7 nie działa, ponieważ
(document.createElement("a")).constructor
jestundefined
w IE7.Problem z tym podejściem polega na tym, że
document.createElement
tak naprawdę nie jest to najszybsza funkcja i może łatwo spowolnić twoją aplikację, jeśli testujesz z nią wiele elementów. Aby rozwiązać ten problem, postanowiłem buforować konstruktory. ObiektElementConstructors
ma nodeNames jako klucze, a odpowiadające im konstruktory jako wartości. Jeśli konstruktor jest już buforowany, używa go z pamięci podręcznej, w przeciwnym razie tworzy element, buforuje swojego konstruktora do przyszłego dostępu, a następnie testuje na nim.Trzeci test to nieprzyjemna awaria. Sprawdza, czy el jest an
object
, manodeType
ustawioną właściwość na1
oraz string asnodeName
. Oczywiście nie jest to zbyt wiarygodne, ale zdecydowana większość użytkowników nie powinna nawet cofnąć się do tej pory.Jest to najbardziej niezawodne podejście, jakie wymyśliłem, przy jednoczesnym utrzymaniu jak najwyższej wydajności.
źródło
Sprawdź, czy
obj
dziedziczy po Węzle .Węzeł to podstawowy interfejs, z którego dziedziczą HTMLElement i tekst.
źródło
odróżnić surowy obiekt js od HTMLElement
posługiwać się:
// LUB
posługiwać się:
o={}; o.is("HTML") // false o=document.body; o.is("HTML") // true
źródło
oto sztuczka przy użyciu jQuery
więc umieszczenie go w funkcji:
źródło
elem.nodeType === 1
więc dlaczego nie zaoszczędzić na wywołaniu i zależności jQuery i czy funkcja isElement zrobi to sama?Nie wbijaj się w to ani nic innego, tylko w przeglądarki zgodne z ES5, dlaczego nie tylko:
Nie będzie działać na TextNodes i nie jestem pewien co do Shadow DOM lub DocumentFragments itp., Ale będzie działać na prawie wszystkich elementach tagów HTML.
źródło
Będzie to działać w prawie każdej przeglądarce. (Tutaj nie ma rozróżnienia między elementami i węzłami)
źródło
Absolutnie poprawna metoda, sprawdź cel to prawdziwy kod podstawowy elementu HTML:
źródło
Każdy DOMElement.constructor zwraca funkcję HTML ... Element () lub [Object HTML ... Element], więc ...
źródło
Mam specjalny sposób, aby to zrobić, o czym jeszcze nie wspomniano w odpowiedziach.
Moje rozwiązanie opiera się na czterech testach. Jeśli obiekt przechodzi wszystkie cztery, jest to element:
Obiekt nie ma wartości null.
Obiekt ma metodę o nazwie „appendChild”.
Metoda „appendChild” została odziedziczona z klasy Node i nie jest tylko metodą oszustwa (właściwość stworzona przez użytkownika o identycznej nazwie).
Obiekt jest typu węzła 1 (element). Obiekty dziedziczące metody z klasy Node są zawsze Węzłami, ale niekoniecznie elementami.
P: Jak sprawdzić, czy dana właściwość jest dziedziczona i nie jest tylko oszustem?
Odp .: Prostym testem sprawdzającym, czy metoda została naprawdę odziedziczona z Węzła, jest sprawdzenie, czy właściwość ma typ „obiekt” lub „funkcja”. Następnie przekonwertuj właściwość na ciąg znaków i sprawdź, czy wynik zawiera tekst „[Kod macierzysty]”. Jeśli wynik wygląda mniej więcej tak:
Następnie metoda została odziedziczona z obiektu Node. Zobacz https://davidwalsh.name/detect-native-function
I na koniec, łącząc wszystkie testy, rozwiązaniem jest:
źródło
Spowoduje to sprawdzenie, nawet jeśli jest to element DOM jQuery lub JavaScript
źródło
Jedynym sposobem na zagwarantowanie, że sprawdzasz rzeczywisty element HTMLEement, a nie tylko obiekt o takich samych właściwościach jak element HTML, jest ustalenie, czy dziedziczy on po węźle, ponieważ niemożliwe jest utworzenie nowego węzła () w JavaScript. (chyba że natywna funkcja Węzła jest nadpisana, ale nie masz szczęścia). Więc:
źródło