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...
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".
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.
Developers I know tend to call the same JQuery selectors over and over instead of storing the result in a variable. They are consistent with this approach.
For example, they do this:
var propName = $(this).attr('data-inv-name');
var propValue = $(this).attr('data-inv-value');
Instead of this:
var current = $(this);
var propName = current.attr('data-inv-name');
var propValue = current.attr('data-inv-value');
The latter approach feels correct to me but maybe I'm missing something. This is a simple example, but I've seen $(this) repeated dozens of times in the same function.
What is the best practice for development with JQuery? Call selectors repeatedly or store in a variable?
The shown analysis is a micro optimization. Using $(this) repeatedly versus storing $(this) in a variable and reusing it will not cause a significant hit to performance.
The times you really want to store the result is when there is an actual selector in there. The only hit you are taking by repeatedly calling $(this) is calling the jQuery constructor function which is very lightweight.
So in this instance go with what reads better. If there really is a dozen occurrences of $(this) in a row, then there should have either been some storing of the variable as indicated, or more likely there was an opportunity to take advantage of chaining which was missed.
If I'm going to use the same selector more than twice I always create a variable. The one change I would recommend is using $ before your variable name to signify that it is a jQuery object
var $current = $(this);
var propName = $current.attr('data-inv-name');
var propValue = $current.attr('data-inv-value');
In theory selecting the component many times demands more process then using one you already have...
If you don't have too many selectors in your page the diference will be almost null (I guess this is the more commom case)... Then you can think about what makes it more readable or easy to modify...
Sometimes you use the same element in a dozen of lines, in this case I prefer to assign this to a variable because when the element change I will need to change just one line (the line I assigned the variable)...
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.
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"