I have a question about the following piece of Javascript code, it is very basic.
var elNote = document.getElementById('note');
elNote.TextContent = 'Hello';
I am new to Javascript and would like to know what is going on here. My book will most likely explain it later, but I would like to learn now.
It is my understanding that elNote gets assigned the html element named note.
My question is if html elements have built in properties, since we select the Property TextConent from the element note. It is also my understanding that elements such as note, are NODES. Does Javascript create and "inject" properties into elements so that they can be modified. I don't know, I'm really trying to think what is going on. thanks.
Yes you can use for example:
elNote.textContent = 'Hello world'; // For raw text content
elNote.innerHTML = '<h1>Hello</h1> world'; // For raw text content
elNote.value = 123; // Tipically for <input> and <button> tags value
Javascript is a loosely typed language, it assigns properties and related methods to the nodes when DOM is defined and its properties vary browser to browser and tier versions.
as far as TextContent is concerned it is described here
These properties are specific to the type of nodes like
document it self is also a node but it is a top level node and it does not contains properties like innerText etc.
For more deep understanding of Document Object Model please refer this wiki
Summing up:
The W3C DOM and WHATWG DOM standards form the basis of the DOM implemented in most modern browsers. Many browsers offer extensions beyond the standard, so care must be exercised when using them on the web where documents may be accessed by various browsers with different DOMs. Copied from this source It looks like DOM is defined by Browsers in the form of javascript readable / accessible objects and their properties vary browser to browser.
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.
Is it possible to augment a DOM element by adding a new property to it as augmenting a normal JavaScript object? For example, can we add a new property of a button or an input, say a value that indicates when was the last time user click on it?
Yes. You can sometimes find it described as bad form. The obvious drawback is that in later versions of Web standards, the DOM element may have new properties added to it which will clash with your custom property, so if you do use this technique, choose a name that is unlikely to clash, e.g. incorporate your company name into it.
Another potential problem is that DOM objects in some browsers are not properly garbage collected. Instead they are reference counted. This means that if you create a system of circular references through custom properties, you may cause a memory leak.
For example, this may cause a memory leak, because there is a circular reference between the DOM and javascript objects:
var myJsObj = {};
var myDomElt = document.getElementById('myId');
myJsObj.domElt = myDomElt;
myDomElt.jsObj = myJsObj;
It is, however, safe to add a property that just holds a primitive value:
myDomElt.fullTitle = "My DOM Element";
Although the warning that the DOM standard may change is still important; what if HTML7 defines a fullTitle property on DOM elements? Your site will have unpredictable behaviour.
An alternative is to use the $.data feature of jQuery:
$(myDomElt).data('fullTitle', 'My Dom Element');
var retrieved = $(myDomElt).data('fullTitle');
It's possible but is a really bad idea. Daniel Earwicker's answer mentions some reasons why it's a bad idea. I'd add these:
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 in older IE 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've been looking for a straight answer for this (I can think of lots of possiblities, but I'd like to know the true reason):
jQuery provides a .data() method for associating data with DOM Element objects. What makes this necessary? Is there a problem adding properties (or methods) directly to DOM Element Objects? What is it?
Is there a problem adding properties (or methods) directly to DOM Element Objects?
Potentially.
There is no web standard that says you can add arbitrary properties to DOM nodes. They are ‘host objects’ with browser-specific implementations, not ‘native JavaScript objects’ which according to ECMA-262 you can do what you like with. Other host objects will not allow you to add arbitrary properties.
In reality since the earliest browsers did allow you to do it, it's a de facto standard that you can anyway... unless you deliberately tell IE to disallow it by setting document.expando= false. You probably wouldn't do that yourself, but if you're writing a script to be deployed elsewhere it might concern you.
There is a practical problem with arbitrary-properties in that you don't really know that the arbitrary name you have chosen doesn't have an existing meaning in some browser you haven't tested yet, or in a future version of a browser or standard that doesn't exist yet. Add a property element.sausage= true, and you can't be sure that no browser anywhere in space and time will use that as a signal to engage the exciting DOM Sausage Make The Browser Crash feature. So if you do add an arbitrary property, make sure to give it an unlikely name, for example element._mylibraryname_sausage= true. This also helps prevent namespace conflicts with other script components that might add arbitrary properties.
There is a further problem in IE in that properties you add are incorrectly treated as attributes. If you serialise the element with innerHTML you'll get an unexpected attribute in the output, eg. <p _mylibraryname_sausage="true">. Should you then assign that HTML string to another element, you'll get a property in the new element, potentially confusing your script.
(Note this only happens for properties whose values are simple types; Objects, Arrays and Functions do not show up in serialised HTML. I wish jQuery knew about this, because the way it works around it to implement the data method is absolutely terrible, results in bugs, and slows down many simple DOM operations.)
I think you can add all the properties you want, as long as you only have to use them yourself and the property is not a method or some object containing methods. What's wrong with that is that methods can create memory leaks in browsers. Especially when you use closures in such methods, the browser may not be able to complete garbage cleaning which causing scattered peaces of memory to stay occupied.
This link explains it nicely.
here you'll find a description of several common memory leak patterns
It has to do with the fact that DOM in IE is not managed by JScript, which makes it completely different environment to access. This leads to the memory leaks http://www.crockford.com/javascript/memory/leak.html. Another reason is that, when people use innerHTML to copy nodes, all those added properties are not transfered.