Ako zistiť či je objekt html element pomocou javascriptu

Jedna z vlastností, ktorá sa mi páči na javascripte je Weak Typing. Nie že by som to pokladal za nejakú super výhodu. Na otázku, či je lepší pogramovací jazyk podporujúci Strong Typing alebo Weak Typing, by som si za víťaza zvolil určite toho skôr menovaného.

Na druhej strane to, že v javascripte sa môže dátový typ premennej meniť počas behu programu umožňuje písať kód tak, ako by sme ho napríklad v C# nikdy nenapísali.

var x;

1;
console.info(x);
console.log(typeof(x));

"some string";
console.info(x);
console.log(typeof(x));

{};
console.info(x);
console.log(typeof(x));
Príklad zmeny dátového typu premennej

Častým takýmto prípadom využitia je metóda, ktorá na základe dátového typu vstupného parametra vykoná rôzne operácie. Ja som si takúto metódu vyrobil. Moja metóda mala jeden vstupný parameter. Ak tento bol typu string, tak to znamenalo, že parameter reprezentuje id html elementu, ale ak bol typu object, tak to bol priamo html element. A konečne sa dostávam k jadru problému. Zistiť, či je premenná typu string je jednoduché použitím operátora typeof (viď. Príklad zmeny dátového typu premennej). Ak je však premenná handle na html element, operátor typeof zahlási že je to object. No dobre, ale objekt môže byť aj niečo iné ako len html element. Po relatívne krátkej dobe, som našiel spôsob, ako overiť či premená predstavuje handle na html element. Výsledok mojej snahy je možné vidieť na nasledovnej úkážke:

var isHtmlNode = function (o) {
    
if (typeof (Node) === "object") {
        
return o instanceof Node;
    
}
    
else {
        
return (typeof (o) === "object") && (typeof (o.nodeType) === "number"
        && (
typeof (o.nodeName) === "string");
    
}
}
;

var 
isHtmlElement = function (o) {
    
if (typeof (HTMLElement) === "object") {
        
return o instanceof HTMLElement;
    
}
    
else {
        
return (typeof (o) === "object") && (o.nodeType === 1
        && (
typeof (o.nodeName) === "string");
    
}
}
Metódy overujúce, či je premenná html element

Prvá metóda overí, či je vstupný objekt inštanciou triedy Node a druhá či je vstupný objekt inštanciou triedy HTMLElement. Ich použitie môže vyzerať aj takto:

var setContent = function (o) {
    
if (isHtmlElement(content) || isHtmlNode(content)) {
        
// o is an html element
    
}
    
else if (typeof(o) === "string") {
        
// o is id of an html element
    
}
    
else {
          
// throw an error
    
}
}
;
Príklad použitia metód pre detekciu objektu typu HTMLElement

Takto si môžeme vyrobiť aj oveľa presnejšie metódy pre detekciu konkrétnych elementov, či už to podľa atribútu tagName alebo detekciou na konkrétne triedy, ktoré dedia z triedy HTMLElement (HTMLAnchorElement, HTMLAppletElement, HTMLAreaElement, HTMLBaseElement, HTMLBaseFontElement, HTMLBlockquoteElement, HTMLBodyElement, HTMLBRElement, HTMLButtonElement, HTMLDirectoryElement, HTMLDivElement, HTMLDListElement, HTMLFieldSetElement, HTMLFontElement, HTMLFormElement, HTMLFrameElement, HTMLFrameSetElement, HTMLHeadElement, HTMLHeadingElement, HTMLHRElement, HTMLHtmlElement, HTMLIFrameElement, HTMLImageElement, HTMLInputElement, HTMLIsIndexElement, HTMLLabelElement, HTMLLayerElement, HTMLLegendElement, HTMLLIElement, HTMLLinkElement, HTMLMapElement, HTMLMenuElement, HTMLMetaElement, HTMLModElement, HTMLObjectElement, HTMLOListElement, HTMLOptGroupElement, HTMLOptionElement, HTMLParagraphElement, HTMLParamElement, HTMLPreElement, HTMLQuoteElement, HTMLScriptElement, HTMLSelectElement, HTMLStyleElement, HTMLTableCaptionElement, HTMLTableCellElement, HTMLTableColElement, HTMLTableElement, HTMLTableRowElement, HTMLTableSectionElement, HTMLTextAreaElement, HTMLTitleElement, HTMLUListElement).

Publikované Friday, February 03, 2012 10:05 AM xxxmatko
Zaradené do: ,

Komentáre

# re: Ako zistiť či je objekt html element pomocou javascriptu

Friday, February 03, 2012 11:02 AM vlko

Zaujimalo ma ako to robi jQuery, nejak takto (upravovane)

// Handle $(""), $(null), or $(undefined)

if ( !selector ) {

return false;

}

// Handle $(DOMElement)

if ( selector.nodeType ) {

return true;

}

return false;

# re: Ako zistiť či je objekt html element pomocou javascriptu

Friday, February 03, 2012 11:12 AM xxxmatko

Po pravde, neskúmal som ako by to šlo s jQuery, primárne používam dojo, kde existujú metódy na detekciu pre string, function, object, array, ..., ale takáto možnosť chýba preto som hladal spolahlivý spôsob ako to spraviť bez použitia nejakého js frameworku. Určite toto nie je jediný spôsob ako sa to dá spraviť.

# re: Ako zistiť či je objekt html element pomocou javascriptu

Friday, February 03, 2012 11:26 AM T

Vdaka za post, budem ale trosku zly

.net dilema - objektove progamovanie a boxing(spokojne object x= "" alebo object x= 1)

a za hentaky kod v js by Ta asi nikto nepochvalil. Tiez za metodu, ktora robi rozne magicky na zaklade toho, aky typ posles dnu (samozrejme existuju pripady, kde je to ako tak obhajitelne)..zvysok fajn.

# re: Ako zistiť či je objekt html element pomocou javascriptu

Friday, February 03, 2012 12:03 PM xxxmatko

Ok, súhlasím že kód object x = "" alebo object x = 1 bude fungovať, ale keby niekto v C# písal metódy a používal len premenné typu object, tak toho by potom asi určite nepochválil.

Nesúhlasím ale s druhou časťou, pretože takéto metódy sú v js úplne normálne a bežné, a funguje takto x metód v rôznych js frameworkoch. (napr: dojo.connect, a taktiež už len samotná init funkcia z jQuery)

# re: Ako zistiť či je objekt html element pomocou javascriptu

Friday, February 03, 2012 1:23 PM T

Samozrejme zbytocny boxing je zlou praktikou, ale specialne napr. Console.WriteLine("Boxed value: {0}", p1); bude boxovat a je to v poriadku, aj ked existuju specialne typove overloady.

OK upresnim radsej, co mam presne na mysli...

Kedze v js nema overloading, tak sa to riesi naozaj tak(to je jeden z dovodov, kedy do akceptujem ako argument, ale aj tu treba vytycit urcite mantinely)

V js fmwk sa pristupuje na rozne neciste design praktiky jednak preto, ze to koduju "rozni" ludia s roznymi navykmi(pre ilustraciu sa staci mrknut z nadhladu na php) a jednak koly "setreniu". Cize toto nie je bohuzial argument :-)

Na Tvojom poslednom pripade vidiet ten zbytocny magic IMHO(kedy si to implementoval objektovo, tak by to bolo jasne breaknutie SRP). Majme jednu metodu, ktora setuje content, ako argument berie DOMElement a jednu metodu, ktora na zaklade id vyhlada element. Nemajme jednu metodu, ktora ma obe zodpovednosti a pripadne zbytocne zavislosti(na pripadnej externej metode, ktora bude robit search elementu). Dava to takto zmysel?