Can I reuse a variable that has been used for creating a DOM element?
I have an example:
var pauseButtonElement = document.createElement("input");
pauseButtonElement.setAttribute("type", "button");
pauseButtonElement.setAttribute("value", "Pausar autoactualitzaciĆ³");
pauseButtonElement.setAttribute("onclick", "pauseGraphicAU();");
document.getElementById("graphicButtons").appendChild(pauseButtonElement);
var maxYValueElement = document.createElement("input");
maxYValueElement.setAttribute("type", "number");
maxYValueElement.setAttribute("required", "");
document.getElementById("graphicButtons").appendChild(maxYValueElement);
Can I use a unique variable to create this elements? Or I have to create a variable for each element? I answer it because I don't know if it's a good practice use a unique variable or many in this case.
You can reuse the same variable. That's perfectly fine and generally preferred if you are only going to need the DOM reference for a defined period of time. In many cases, it is preferred to reuse the variable because it allows the JavaScript runtime to release its object reference, allowing memory to be freed up.
The only issue is that you will have lost that DOM reference and so if you want to interact with that element again, you'll have to re-scan the DOM for it.
In the end, it really comes down to the scope you are declaring the variable in and how persistent you want the reference to be.
Related
I am kinda newbie and I really want to understand why the variables we create don't just get the values inside the DOM element, but becomes the DOM element?
Here is some basic code;
var elementValues = document.getElementById("p1");
elementValues.style.color = "red";
// I don't understand why we don't need this step in order to manipulate the DOM.
// document.getElementById.getElementById("p1") = elementValues;
Aren't we basically saying to copy the values from DOM element with an id of p1 and paste them into elementValues?
But why the color of DOM element changes when I change the color of elementValues? From what I understand it acts like a pointer.
In Javascript, Object variables store a reference to the objects. Hence, document.getElementById returns a reference. So when you modify the values of elementsValues, your are editing the referenced object.
Have a look on Working with Objects - Comparing Object. You could read the whole page also to have an overview.
Yes, it is like a pointer.
By using var elementValues = document.getElementById("p1"); you are assigning a reference to the DOM element to the variable. Nothing about the element gets saved to the variable, but "where to find it".
I am having to store a large array of JavaScriptobjects, these objects need to contain a message, and a way of selecting an associated HTML element.
Currently, I've been using the the following code to add to this array:
if (field[0].id != ""){
this.selectorString = "#" + field[0].id;
}
else if (field.attr("name") != ""){
this.selectorString = "[name='" + field.attr("name") + "']";
}
I didn't want to store the entire field, as I wasn't confident on JavaScripts/JQuery memory management or how it worked. Selection strings seemed the safer option, as opposed to a large array of fields. I could then just use the stored string to perform a JQuery selection statement and manipulate the field.
The Big Question
If I store the fields, will this take up a large amount of memory, or is it purely reference to an object that is already stored somewhere in the big black hole of JavaScript of which I know little?
Is there an alternative that anyone can think of that would enable me to achieve what I'm going for. The 'fields' can be divs/spans/input fields/anything, that might not necessarily have an ID/Name - which will cause problems if I'm not storing the field.
Many thanks.
If I store the fields, will this take up a large amount of memory, or is it purely reference to an object that is already stored somewhere in the big black hole of JavaScript of which I know little?
Just a reference (the "big black hole" is called the "DOM" or "DOM tree" or sometimes "page"). But note that if you remove the element you're referring to from the DOM at some point, but still have a reference to it from a JavaScript variable, the element is kept in memory (just not in the DOM tree) until/unless you assign a new value to that variable or that variable goes out of scope.
Concrete example: Say we have this on our page:
<div id="foo">....</div>
And we have this code:
var f = $("#foo");
Now we have a jQuery object wrapped around a reference to that element. It's not a copy of the element, just a reference to it.
Now suppose we did this:
f.remove();
That div is no longer in the DOM (on the page), but it still exists because we still have a reference to it from the f variable (indirectly; f refers to a jQuery object which, in turn, refers to the element). But if that variable goes out of scope, or we assign some other value to it (for instance, f = null;), then the element is not referenced from anywhere and can be reclaimed.
If you're not removing elements from the DOM (directly, or indirectly by replacing the contents of an an ancestor of theirs), then very little memory is used to simply refer to the existing element.
I have wriiten
document.createElement("p");
document.createElement("p")
How does Javascript intepreter knows do distinct between those two?
Id ? ( what is the Js property )? maybe something else ?
In this particular case:
document.createElement("p");
document.createElement("p")
the JavaScript runtime doesn't worry about the elements at all, because you didn't save the values returned. They're thrown away.
If you had written,
var p1 = document.createElementById('p');
var p2 = document.createElementById('p');
well then you've got two separate variables, and so you're keeping track of the difference.
It's important to be aware that the JavaScript interpreter itself doesn't really care too much about your DOM nodes. That's not really it's business. If you call methods and create objects, it's your problem to keep track of them.
Let's pick another real-life example: How does a human distinguish one orange from another one, in a basket? I look inside the basket, and notice that there're multiple orange-coloured, ball-shaped items
The JavaScript interpreter internally keeps track of the created objects. When an object isn't referred by anything (variables), the built-in Garbage Collector destroys the object.
It doesn't. createElement returns the object reference but if you don't assign it to anything or directly use it, it's lost.
var firstp = document.createElement("p");
var secondp = document.createElement("p");
Then you can assign an id or whatnot:
firstp.id = "first";
Keep in mind though, that this is not in the DOM yet. You have to insert it somewhere before it can be seen by the user/found with getElementById.
For that you can do something like this:
document.body.appendChild(firstp);
It doesn't. When you call document.createElement(), you create an element and it's inserted into the DOM. JavaScript can then grab certain p elements by ID, for example, or grab other p (and other) elements with getElementsByClassName().
If you'd assigned the returned values to variables, you'd be able to keep track of which one was which by referencing different variables. This is you distinguishing between them, not JavaScript, though.
You can refer to them by their index in the array of elemnts:
document.getElementsByTagName('p')[0]
You can assign id to them
document.getElementsByTagName('div')[0].id = 'first'
document.getElementsByTagName('div')[1].id = 'second'
And refer to them by id
document.getElementById('first')
It is up to you how you do it really...
HI Guys, I have a question,
Im trying fo find the most efficient way in terms of performance to store and access an element in the javascript protoype library.
lets say I dynamically create a parent with an child element in a test class
testclass = Class.create({
newParent: null, //I will create a global reference to the parent element
method1: function(){
this.newParent = new Element('div',{'id':'newParent'});
var elm = new Element('div',
{
'id': 'elm1',
'identifier': 'elm1identifier'
}
);
newParent.insert(elm);
},
method2: function(){
??????????
}
})
In method 2, I want to be able to access the element elm1.
I have been thinking, and here are my different solution.
I can access the element using the utility method provided by prototype $()
method2: function(){
$('elm1');
}
I can make a global reference to the element.
elm1: null,
....
method2: function(){
this.elm1
}
3.I can pass the element in the method as a parameter but this option will not always be available
I create a unique identifier as an attribute and use the protoype .down function
this.newParent.down('[identifier=elm1identifier]');
So ofcourse i use a combination of these, but im curious, at out of all the methods, which is the most efficient in terms of performance.
I heard that the $() utility method searches the whole dom? Is this a significant difference? What if you have alot of elements.
Storing references to elements may also cause memory problems especially if you have a lot of javascript in a big web site.
using a unique and custom identifier is also nice, but you also add new attributes which might have an effect on the dom itself. But this advantage is that you specifiy where you want to search using the element.down() method in prototype.
Thanks for the help guys.
If you are creating an object that is supposed to represent a DOM element, it seems sensible to give it a property that references the element, say "element". Then in method1:
this.element = elm;
I think at this stage, micro-optimising for performance is pointless since the biggest improvement in performance would be to not use Prototype.js.
The $() method is firstly an alias for document.getElementById (which is blazingly fast in browsers and always has been) and secondly adds convenience methods to the element returned. If the browser doesn't implement a prototype based inheritance scheme, Prototpye.js adds about 50 methods directly to the element as properties, which is a pretty expensive operation.
I doubt that storing references to elements will cause significant memory issues unless you are storing tens of thousands and not using them (they are just references after all).
using a unique and custom identifier
is also nice, but you also add new
attributes which might have an effect
on the dom itself
Do not add custom attributes or properties to DOM elements. Prototype.js version 2.0 is going away from this model (at last), just don't do it. If you have an object that represents (or "wraps") an element, add the property to that.
In Actionscript I can do
var thing:MovieClip = new MovieClip ();
thing.somevar = 1;
and the thing object would have a variable called somevar.
Can I do the same in Javascript if I created an element using createElement?
Yes, you'd be creating a custom/unsupported attribute for the HTML element that you can read back. Most people will say that it's not good practice but it does work on all browsers*.
Be careful though to avoid circular references. IE cannot free the memory used by objects with circular references if one of the object is an HTML element. This will result in memory leak on IE. Though other browsers can handle it well enough.
* At least all browsers I've ever tried.
Do you mean this?
var a = document.createElement("input");
alert(a.localName); // gets "input"