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
Related
Html ids are kind of the antithesis of good web application development. When you use reusable components, having IDs anywhere immediately either makes your component non-reusable, or forces you to manage a unique set of ids, which is bad for code maintenance and can easily introduce errors.
Aria-owns seems to require the use of ids. I would have assumed there would be a way to specify an a11y relationship in javascript with bare dom node references, but I can't seem to find anything like that.
Is there any way of avoiding ids if you want to use accessibility features like aria-owns?
Shadow DOM is a good way to include web components while avoiding id attributes overlapping.
The DOM shadow boundary would prevent any problem while still enabling screenreaders to parse the accessibility tree
No. HTML attributes can't use JS references.
IDs are the standard means to identify an element.
Generate a unique ID for the elements you need to reference: You already have a DOM reference in your JS to set it on.
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 was curious to know how a browser exposes the elements within a Document Object model (DOM) to the Javascript developer. Does it create an element instance for each node in the DOM or does it expose a hierarchical tree structure that one must traverse to access flat elements ? If it provides a tree structure comprised of element instances why are the framework API's so divergent either exposing a procedural type of interface (e.g. jQuery/D3) or an object orientated one (e.g. Angular/React).
In Python, for instance, one may traverse the file system in two ways. Each are effectively equivalent but one is more procedural and the other is more object orientated.
Using the os module - One may navigate the file system hierarchy by stepping through the folders to get to the files. The file, once found, is represented by a string and manipulated accordingly by means of string operations.
Using the pathlib module - One navigates the file system hierarchy by calling a method on some root folder object. The file once found is itself an object and manipulated by calling various methods upon it. Underneath it's still manipulating a string but it's encapsulated away from the user.
Python 3.4/5 onward started allowing both methods to work interchangeably. That is one may generate a file object from a procedurally traversed tree or procedurally traverse a tree from some root object.
jQuery and D3 appear to work more like the os module traversing a tree structure and Angular/React work more like pathlib manipulating element instances. If the browser provided a hierarchy to work with then D3/jQuery would map directly to it while Angular/React must necessarily create element instances. If the browser provides element instances then D3/jQuery are flattening these elements into a tree structure that it navigates while Angular/React would map directly to these instances.
I suspect the real scenario is that the browser exposes a tree of elements and that jQuery/D3 choose to traverse it as a tree while Angular/React choose to work with the elements and ignore/hide the structure.
In a worse case scenario the browser might retain it's own elements exposing only a tree structure from which Angular/React then create their own element instances and vice versa for jQuery/D3 which flatten these instances into a tree.
Could one classify the Javascript frameworks like vue/ember/backbone as working predominantly like jQuery/D3 upon a tree or like Angular/React upon elements ?
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://...')
Is it a bad practice to have backbone views which do not depend on any kind of templating system?
Of course, this does not mean that any kind of DOM code will be generated by hand, using hardcoded strings within the views. No no no. I can of course cache the basic layout for each view in DOM elements, set to display:none. However, I want to reduce any kind of value setting within the templates themselves. I'd rather do that using jquery, or any other kind of DOM modifier form within the view itself. This way I save myself the constant discrepancies and the countless hours of efforts that I've exposed my apps and myself to, using Mustache, Handelbars, the Underscore templating system, etc. Having all the view logic in one place makes everything much cleaner, at least in my view. It gives a lot of benefits, such as proper partial rendering, value binding, etc, that I'd need tons of days to spend on if I wanted to implement them with mustache or something.
The only problem that I see might occur is whether the constant checks that I'd do with jQuery will be performing fast enough, but I guess that it shouldn't be such a problem at the end.
What do you think? Good? Bad? Practical?
IMHO not using a template engine is not, per-se, a bad design decision.
Template engines are meant to produce cleaner and more maintainable code, if you think not using them produces cleaner and more maintainable code them you can run without them.
I my opinion is better to use template engines but this is just a matter of taste. I also combine the templates with manual DOM modifications through this.$el.find(".my-element").html( "new value" ); for partial updates.
Templates are good. They save you a lot of time coding and allow you to loop over elements and create multiple elements with very little code.
That said if the render is called too much or you destroy and recreate DOM elements/templates, it costs a lot in performance.
I have a PerfView for backbone that can display 1,000,000 models in a scrollview at 120FPS in chrome. The trick is I only render the template once with all the possible nodes I need then change the content in the DOM when the model changes. Also using an object pool for the DOM elements will let you reuse them. Check out the modelMap property on line 237 (https://github.com/puppybits/BackboneJS-PerfView/blob/master/index.html) on how to semi-automate updating an element so you don't overuse a template.