As title, how can I get the all DOM tree including generated by javascript.
For example:
<html>
...
<script type='text/javascript'>
function add_new_element(){
var dv, newP;
newP = document.createElement("p");
newP.id = 'new';
dv = document.getElementById('ex');
dv.appendChild(newP);
}
</script>
<body onload="add_new_element()">
<div id="ex"></div>
</body>
</html>
And I want get all DOM including the 'p' that is generated by js.
I used phantomjs to execute js and then get DOM, but failed.
Somebody have good ideas?
Thanks.
You have access to the newly created p object in your code. The variable newP has saved it. If you manipulate that variable the dom changes will be reflected in the dom automatically. Let me know if you still face issues accessing it.
Note: Since you have declared the newP variable as a var type it will remain private to that function ** add_new_element**. If you want it to be global variable (IMHO that is what you should be doing) so that you can have access to it all the time you should just declare it as newP.
var dv;
//remove the var type declaration
newP = document.createElement("p");
newP.id = 'new';
Related
EDIT: This question is not a duplicate, I am aware that at this point foo has not been inserted into the DOM. My question is whether or not is is possible to access the elements declared in the string assigned to foo without inserting it into the document object.
In the following code, we declare an HTML element as a JavaScript variable.
<script>
var foo = "<td id = 'bar'>";
</script>
Now, after the <script> tag but before the </script> tag, how do I access the value of id in the table cell?
Eg. calling console.log(foo.id) obviously prints undefined.
how could I call the console.log() function (or any other function to access the value of id) to give us the correct value, "bar"?
Im using <td> as an example but I assume this applies to any html tag declared with JS.
In your case you'd get what's between the first and second ', which coincidentally happens to be the id by doing:
foo.split("'")[1] // -> bar
However that is not too useful or reusable. You could push an element to memory and set the innerHTML of that node to your string, however the string in your example is not valid HTML, so it would not work.
var temp = document.createElement('html')
temp.innerHTML = str
temp.getElementsByTagName('td')[0].id // -> bar
Can't imagine your use case though, so maybe none are perfect.
(Feel free to reword the title; I find this hard to put into words.)
I've created a JavaScript "class" (for lack of a better word; I know JS isn't class-based) that represents a textarea and a div.
Every time the textarea's value is changed, I want the div's content to update accordingly, so I thought to assign an onkeyup event handler to the textarea — however, that turned out to be more problematic than I thought.
Here's the relevant part of my HTML:
<div id="container"></div>
<script src="MyTextarea.js"></script>
<script>
var ta = new MyTextarea('container');
</script>
And here's the JS I've written so far:
function MyTextarea(id) {
this.textarea = document.createElement('textarea');
this.box = document.createElement('div');
var container = document.getElementById(id);
container.appendChild(this.textarea);
container.appendChild(this.box);
this.textarea.onkeyup = this._synchronize;
}
MyTextarea.prototype._synchronize = function () {
this.box.innerHTML = this.textarea.value;
};
Instead of working, this insists on throwing a "this.textarea" is undefined" error. It turns out that — much to my surprise — in the _synchronize function, this doesn't refer to the MyTextarea object, but instead to the textarea element itself. I'm puzzled as to why that would be.
What am I doing wring and/or not getting here? Is it because I'm doing this within a "class"? How can I achieve this instead?
You are losing context when you assign event handler as direct function reference. So in other words, instead of MyTextarea instance object this points to HTMLTextAreaElement object.
There are multiple solutions, for example you can bind context explicitly:
this.textarea.onkeyup = this._synchronize.bind(this);
Or you could do it old-school way:
var self = this;
this.textarea.onkeyup = function() {
self._synchronize();
};
I keep learning very simple things about functions, returns, id and everything, so I ran into another problem that looks simple, but I cannot understand why it happens. Check this code:
function test() {
var text = document.createTextNode("Hello");
text.id = "t";
}
var whatIjustwrote = window.document.getElementById("t");
alert(whatIjustwrote);
Does the getElementById has restrictions to look only for global items? What would be the way to make that alert output the text node inside the function?
Thank you for any comment. The last few days asking things here I have been learning quite a lot!
JSFiddle
Firstly, getElementById will only return an element, and you're creating a text node.
Secondly, it will only return an element that has been added to the DOM. The node you create doesn't get added to the DOM, so it wouldn't be found even if it could be.
Finally, you don't actually call the test function, so the text node isn't even created in memory.
Here's an updated fiddle that demonstrates getElementById actually working:
function test() {
var text = document.createElement("span"); //Create an element
text.innerHTML = "Hello";
text.id = "t";
document.body.appendChild(text); //Add it to the DOM
}
test(); //Invoke the function (so the element actually gets created)
var yourElement = document.getElementById("t"); //Get reference to element
getElementById does only search for element nodes. You did create a text node, which has neither attributes nor an id - you just added a custom property to the JS object. Also, you did not append your node to the document, so it couldn't have been found in the DOM tree.
You might want to read an introduction to the DOM (at MDN), the introduction at quirksmode.org or even the W3 standard itself (especially the introduction section)
function test() {
var elem = document.createElement("span"); // Create an element
var text = document.createTextNode("Hello"); // Create a textnode
elem.appendChild(text); // add text to the element
elem.id = "t"; // assign id to the element
document.body.appendChild(elem); // Add it to the DOM
}
test();
var yourElement = document.getElementById("t"); // Get the element from the DOM
alert(yourElement.textContent); // alerts "Hello"
// you also could have alerted yourElement.firstChild.data - the content of the
// textnode, but only if you had known that yourelement really has a firstchild
(Demo at jsfiddle.net)
A couple of points that come to mind..
1) You cant give a textNode an id attribute (you're actually giving it a new member variable named id)
2) To find an element it must exist in the document's DOM
Do this instead:
var mSpan = document.createElement('span');
mSpan.id = 't';
mSpan.appendChild( document.createTextNode('Hello') );
document.body.appendChild(mSpan);
var whatIjustwrote = window.document.getElementById("t");
alert(whatIjustwrote.innerText);
Does the getElementById has restrictions to look only for global
items?
The answer is no. First you have to define global items anyways. Anything that is attached to the DOM is in fact global, and in terms of global javascript objects there is only one, window, in the case of a browser. You are creating a function but you're never executing it.
In addition the text node cannot actually have an id or any other attribute. You need an element for this, so even if you execute the function you would still get null. Also creating a node does not attach is to the DOM, so you won't be able to access it even if this isn't a text node.
I have updated your fiddle.
I have created an object at runtime by using innerHTML tag, now I want to access this element by using getElementById, when I accessed the element its return NULL value. Kindly suggest me any direction so that I can acheive this,
Here is the following code hint which I am using
In HTML
<div id="web">
<object id="test"></object>
</div>
In JS
document.getElementById("web").innerHTML="<object id='test2'></object>";
.
.
var obj = document.getElementById("test2");
Here obj return null value.
Did you assign an id to the freshly created element? Did you insert the element into the document tree (using appendChild or insertBefore)? As long as the element is not inserted into the DOM, you can't retrieve it using document.getElementById.
Example of element creation:
var myDiv = document.createElement('div');
myDiv.id = 'myDiv';
document.body.appendChild(myDiv);
document.getElementById('myDiv').innerHTML = 'this should have worked...';
[edit] Given the later supplied code, a third question emerges: is your script located at the bottom of your html page (right before the closing </body> tag)? If it's in the header of the document, your scripting may be running before the document tree is completely rendered. If your script has to be in the header of the document, you could use a load handler to run it after rendering of the document:
window.onload = function(){
document.getElementById("web").innerHTML='<object id="test2"></object>';
// [...]
var obj = document.getElementById('test2');
};
To add an element using JavaScript, you need to do 2 things.
Create the element
var element = document.createElement(tagName);
Add it to the dom
document.body.insertBefore(selector, element);
or
document.getElementByID(selector).appendChild(element);
More info here: MDN
If a DOM node is dynamically created, then there's no need EVER to find it again with document.getElementById().
By creating the node in the right way, you can keep a reference to it as a javascript variable, which can be used anywhere within scope.
For example:
window.onload = function(){
var myDiv = document.createElement('div');
document.body.appendChild(myDiv);
//and now a function that's called in response to some future event
function whatever(){
...
myDiv.style.color = 'red';
...
}
};
Note: The inner function (called at some point(s) future) has access to the myDiv variable because the outer function forms a "closure", within which variables are kept alive and accessible, even though the outer function has completed and returned.
As far as I know document.getElementById('myId') will only look for HTML elements that are already in the document. Let's say I've created a new element via JS, but that I haven't appended it yet to the document body, is there's a way I can access this element by its id like I would normally do with getElementById?
var newElement = document.createElement('div');
newElement.id = 'myId';
// Without doing: document.body.appendChild(newElement);
var elmt = document.getElementById('myId'); // won't work
Is there a workaround for that?
(I must tell that I don't want to store any reference to this particular element, that's why I need to access it via its Id)
Thank you!
If it isn't part of the document, then you can't grab it using document.getElementById. getElementById does a DOM lookup, so the element must be in the tree to be found. If you create a floating DOM element, it merely exists in memory, and isn't accessible from the DOM. It has to be added to the DOM to be visible.
If you need to reference the element later, simply pass the reference to another function--all objects in JavaScript are passed by reference, so working on that floating DOM element from within another function modifies the original, not a copy.
For anyone stumbling upon this issue in or after 2019, here is an updated answer.
The accepted answer from Andrew Noyes is correct in that document.getElementById won't work unless the element exists in the document and the above code already contains a reference to the desired element anyway.
However, if you can't otherwise retrieve a direct reference to your desired element, consider using selectors. Selectors allow you to retrieve nodes that aren't necessarily in the DOM by using their relationship to other nodes, for example:
var child = document.createElement("div");
child.id = "my_id";
var parent = document.createElement("div");
parent.appendChild(child);
var child2 = parent.querySelector("#my_id");
getElementById is a method on the document object. It's not going to return anything not in the document.
On not storing a reference, huh? If you could magically pull it out of the air by id, then the air would be a reference to it.
If you've created it, just pass the object to other functions and access it directly?
function createDiv()
{
var newElement = document.createElement('div');
doWorkWithDiv(newElement);
}
function doWorkWithDiv(element)
{
element.className = 'newElementCSS';
element.innerHTML = 'Text inside newElement';
addToDoc(element);
}
function addToDoc(element)
{
document.body.appendChild(element);
}