I am building a tree (for SOAP) using DOM. I would like read the following info at a certain node:
Is an XML namespace already "imported" into the document (with xmlns:blah="http://...) - knowing the http://... part.
What moniker (in the above example blah) used.
Is there any way other than the manual: to walk chain of ancestors and iterate on attribute nodes, find any starting with xmlns: checking the value and if match return the rest of the attribute name?
Aside the usual methods such as document.getElementsByTagName, DOM offers their namespaced versions: document.getElementsByTagNameNS
Such methods take the namespace URL as their first argument.
document.getElementsByTagNameNS('http://...', 'abc');
By the way, using the regular methods, the elements might be available as…
document.getElementsByTagName('xmlns\\:abc');
This works for me in case of a HTML DOM even without "importing" any namespace.
Update:
The method OP was looking for is document.lookupPrefix('http://...')
Related
JavaScript lets you add arbitrary properties and methods to any object, including DOM nodes. Assuming the property was well namespaced (something like _myLib_propertyName) so that it would be unlikely to create a conflict, are there any good reasons not to stash data in DOM nodes?
Are there any good use cases for doing so?
I imagine doing this frequently could contribute to a sloppy coding style or code that is confusing or counter-intuitive, but it seems like there would also be times when tucking "custom" properties into DOM nodes would be an effective and expedient technique.
No, it is usually a bad idea to store your own properties on DOM nodes.
DOM nodes are host objects and host objects can do what they like. Specifically, there is no requirement in the ECMAScript spec for host objects to allow this kind of extension, so browsers are not obliged to allow it. In particular, new browsers may choose not to, and existing code relying on it will break.
Not all host objects in existing browsers allow it. For example, text nodes and all ActiveX objects (such as XMLHttpRequest and XMLDOM objects, used for parsing XML) in IE do not, and failure behaviour varies from throwing errors to silent failure.
In IE, the ability to add properties can be switched off for a whole document, including all nodes within the document, with the line document.expando = false;. Thus if any of the code in your page includes this line, all code relying on adding properties to DOM nodes will fail.
I think more than anything, the best reason not to store data in the DOM is because the DOM is meant to represent content structure and styling for an HTML page. While you could surely add data to the nodes in a well-namespaced manner as to avoid conflicts, you're introducing data state into the visual representation.
I'm trying to find an example for or against storing data in the DOM, and scratching my head to find a convincing case. In the past, I've found that the separation of the data state from the visual state has saved headache during re-designs of sites I've worked on.
If you look at HTML 5 there is the data attribute for fields that will allow you to store information for the field.
Don't be surprised to run into trouble with IE 6 & 7. They are very inconsistent with setAttribute vs set as a property.
And if you're not careful you could set circular references and give yourself a memory leak.
http://www.ibm.com/developerworks/web/library/wa-memleak/
I always set node properties as a last resort, and when I do I'm extra careful with my code and test more heavily than usual.
For what it's worth, the D3.js library makes extensive use of custom properties on DOM nodes. In particular for the following packages that introduce interaction behaviors:
https://github.com/d3/d3-zoom - the __zoom property
https://github.com/d3/d3-brush - the __brush property
D3 also provides a mechanism for putting your own custom properties on DOM elements called d3.local. The point of that utility is to generate property names that are guaranteed not to conflict with the DOM API.
The primary risk I can see associated with custom properties on DOM nodes is accidentally picking a name that already has some meaning in the DOM API. If you use d3.local or maybe prefix everything with __, that should avoid conflicts.
I've been writing Javascript for years, but just now realized I don't entirely understand how these "HTML-y" methods actually interact with the DOM.
My assumption is that when HTML is interpreted into the DOM, the browser keeps references as to which HTML element became which DOM node.
So for .getElementById when you select an element, the browser returns the relevant node by reference. Why not just do .getNodeById then and be more correct?
My assumption is that .innerHTML is interpreted by the browser into the DOM at runtime. However, in older browsers like IE7, .innerHTML cannot be used to create table nodes. This suggests to me that it was originally intended just to modify the text properties of existing nodes, but then it seems strange that it exists at all, and we don't just use .innerText.
I guess I'm just confused by some Javascript history.
Well, the thing is, things like .innerHTML and .getElementById aren't really JavaScript objects at all. They're what the language specification calls "Host Objects" - it's a form of FFI. What happens when you call .getElementById in most browsers is that the string is marshalled from a JS string to a DOM string and then passed to C++ code.
In fact, they're allowed to have pretty much whatever semantics they please - the language makes no guarantees about how they act (this is also true for other DOM objects like timers and XHR).
well if you really want to know about the internals and want to digg into the deep rabbit hole of rendering engines i'd give you a start by pointing you to certain source files of chromium:
http://src.chromium.org/viewvc/blink/trunk/Source/core/dom/Element.cpp
you could find stuff like innerHTML and how it actually works in it. (around line 2425)
.getElementById() will just resolve to a document element that matches the specified id and will return a reference to it.
its some kind of identifier with prototyped methods, getters and setters to interact with that element. as soon as you interact with methods like innerHTML etc. you will simply tell the engine to execute that action on the element that is referenced inside the element reference.
just digg around inside the source code. you might get a good insight:
http://src.chromium.org/viewvc/blink/trunk/Source/core/dom/
I know a bit of Javascript and have recently started trying to tie it into HTML with the code academy course. in the following code:
function sayHello(name){
document.getElementById("result").innerHTML = 'Hello ' + name + '!';
}
The "document" in the above code is the DOM?
That would mean that getElements is a property (function) of document, and that innerHTML is a function of the getElements function.... right?
If I am seeing this correctly, how is it possible that DOM objects have javascript properties/functions?
Is document the DOM
Short answer
Yes, in the sense that it is the root of it.
Slightly longer answer
The Document Object Model (DOM) is what the browser exposes to the JavaScript runtime to allow JavaScript code to manipulate the page (its nodes and associated metadata). document is one part of the DOM.
How can the DOM have JavaScript properties
Short answer
They don't.
Slightly longer answer
The DOM is not actually managed in JavaScript (yet). It is typically managed by a separate engine altogether, written in a lower-level language like C++ or Rust (in the case of Mozilla's Servo project). The JavaScript runtime is also written in a lower-level language (again, C++ is most likely) and certain attributes of the DOM are exposed to the JavaScript runtime as if they were native JavaScript objects. The fact that they are not makes all kinds of interesting things possible ... and generally make it so that these DOM objects do not always behave as you would expect "real" JavaScript objects to behave (for example typeof querySelectorAll in IE 8 returns "object", not "function" as one would reasonably expect).
the Document Object Model is a model for interacting with HTML. They do not have "javascript properties" or "functions", javascript functions are executed on HTML elements which are found through the DOM.
getElementbyID
is a function in javascript, which retrieves a HTML element based on the DOM. Below is what the DOM looks like, and is how javascript will execute the aforementioned function.
http://www.w3schools.com/js/js_htmldom.asp
Close. document is the root element in the DOM, or Document Object Model. The DOM is the in-memory representation of the current document.
Calling document.getElementById() returns an HTML element, which has the property innerHTML. Writing to innerHTML tells the browser to render the string as that element's children.
DOM objects do not have javascript-dependent properties or attributes. Javascript is just one way of accessing DOM attributes.
DOM can be thought as an Interface (provide by layout engine like Gecko in Google Chrome and Firefox ) between the HTML and Any_Other_language
{like JavaScript} that want to use the html.
Say Tomorrow If a new language is born ( something similar to javaScript but a new language that has it's engine implemented in the browser like JavaScript has V8 engine in Google Chrome ) that want to play around with HTML, then just to access the HTML they don't have to write some hefty low level code( inside the engine for this language ) instead they can use DOM_Interface ( inside the browser ) to access and this makes it easy for them to concentrate on their logic.
DOM is Document Object Model ie your whole document is the hierarchy of objects with Window being the parent of all.
It provides a structured representation of the document (a tree) and it defines a way that the structure can be accessed from programs so that they can change the document structure, style and content.
We use dojo/parser on our application to parse html produced by our server side templating language using the dojo-data-type attribute.
One common thing we need to do is access a node that's part of the modules' domNode to do something with. We've come up with a unique id method for id'ing the nodes we want, but that leaves me uneasy for various reasons.
the _templated mixin allows you to define 'attach-points' in templates that get attached to the object instance. Does something like this exist for for the parser, so a node can be easily identified by the module code?
If not, what's the best way to parse the module's domNode to find these important child nodes, especially avoiding child nodes that belong to another (child) module's domNode?
No, attach-point is not supported in the parser. That is a Dijit template thing.
Using an ID will work, but that runs the risk of duplicate IDs and things will break. I'd suggest using classNames and finding your nodes with dojo.query.
If the attachable items are other Dijits, you can access them with widget.getChildren();
If you are not using all the features of dojo.parser (there a lot that I don't use) you could build your own. I built one, and it's shocking how tiny it is compared to Dojo's. Note that mine has just been created and has had very little testing, so this is just for reference. https://github.com/clubajax/dx-ui/blob/master/util/parser.js
Many of us non-jquery javaScript developers, have been using domElement.setAttribute, and its sister functions, to hack our way around countless dom elements, for all of internet eternity.
Be it, css, dom classNames, storing/retrieval of variable data, etc...
var b = document.getElementById("someDiv");
b.setAttribute("align", "center");
So what's the purpose / practical use of its domElement.setAttributeNS variant? This question is in regards to web browser display / uses. And not in the context of XML. In which setAttributeNS has lots of uses.
var d = document.getElementById("someDiv");
d.setAttributeNS("http://www.mozilla.org/ns/specialspace", "align", "center");
In HTML Documents (i.e. Document objects create by the text/html parser) there really aren't many uses for setAttributeNS.
But if look at what the HTML5 parser is required to do when parsing foreign content (i.e. SVG abd MathML) we find this table: adjust foreign attributes.
So it automatically moves and renames some attributes into the XLink, XML and XMLNS namespaces. When you are manipulating the DOM via functions like setAttribute and setAttributeNS, that automatic moving and renaming won't happen, so to get the attributes into their correct namespaces, you need to use setAttributeNS to create and modify them.
xlink:href is possibly the most common of these to be set via setAttributeNS()
That's domElement not htmlElement.
It is useful when you are working with a DOM constructed from XML that uses elements from multiple namespaces.
(And if you want to know why namespaces are useful, then see this question)