Dynamic DOM elements not accessible? - javascript

I can see a DOM element with an ID of Foo by using the debug inspector.
This DOM element is inserted dynamically by a script that I do not have access to.
Because of this you can not see it when you do View->Source.
When I try to access the element using
document.getElementById('Foo'), it returns a null b.c. it can not find it.
Verified this in the debug console as well.
Is it possible to get elements that are inserted dynamically?
I ask b.c. I would like to remove the node.

Yes, you can:
function addElement() {
var foo = document.createElement('p');
foo.id = "bar";
document.body.appendChild(foo);
}
function getElement() {
alert(document.getElementById('bar'));
}
addElement();
getElement();
See also a live demo of this.
Why your example doesn't work is hard to say as you haven't provided any details.
At a guess, the element you are seeing is in a different document, embedded in an iframe, in which case you would have to access the document in the iframe before calling getElementById on it. This is, of course, subject to the same origin policy.
​

Related

Why I can not access an Element (which has been created by JS) using document.body.myElement?

let myElement = document.createElement("div")
I can access the element by:
myElement.anyMethod
But I can not access by:
document.body.myElement.anyMethod
So why can we access body by:
document.body.anyMethod
But we can not access the element by:
document.body.myElement.anyMethod
CreateElement
Let's make this simple. In DOM all the elements are treated as objects.
The document is also an object with attributes like body and methods like clear, location, and so on. So when you are creating an element with
let x=document.createElement('div')
console.log(typeof(x))
//returns object
The CreateElement returns an object and it does not create an attribute or anything for it. So the element is not connected to the document object.
Methods
x.click()
X is an object of HTMLElement and has methods like click and attributes like id and so on. But when you are doing like this
document.body.x.click()
The document has an attribute named body but the body object has no attributes like x
document.body.x //returns undefined
So finally the createElement method returns an object but it doesn't add the element as its attribute so when you are calling like this you get an undefined error.
You're missing a step in your code if you're expecting to reference it from the DOM (via document.body... or document.getElement...). You need to append the element to a particular place where you want it. This reference page shows a simple example, but I'll share an example related to your code here:
let myElement = document.createElement("div");
myElement.innerHTML = "It works!";
// you can replace the following with `document.body.append(myElement)`
document.getElementById("body").append(myElement);
<div id="body"></div>

How to clear all that's written on an HTML document?

How do I clear off all that was written in a document? Is there a DOM JavaScript API that will erase all that's in the document object's buffer; an equivalent of the server-side Response.Clear()?
I am just practicing JavaScript.
You can remove the root (html) element using:
document.querySelector('html').remove();
or the jQuery equivalent if you have a very old browser:
$('html').remove();
here's an alternative that doesn't require querying:
document.documentElement.remove();
What do you mean by “document object's buffer”? The actual visible content is usually contained in the body, so you can empty it:
document.body.innerHTML = null;
There is no buffer like in server-side preprocessor languages, because the DOM document is entirely client-side rendered.
You can even wipe all the document's descendants, clearing the <html> element:
document.getElementsByTagName('html').item(0).innerHTML = null;
Also, if you don't like innerHTML, you can also use textContent:
document.head.textContent = null;
This is because, quoting MDN:
Setting this property on a node removes all of its children and replaces them with a single text node with the given value.

Invoke javascript class function in firefox addon

I needed xpaths generated by Firepath (Firebug extension), to be passed to my native JavaScript class object present in DOM. So, I am modifying Firepath extension itself, now to pass the generated xpath to my JavaScript class function present in DOM, I can't figure out a way. I tried many solutions like inside the extension function, the following example works:
window.alert("hello");
But the following doesn't:
var pObj = new window.wrappedJSObject.PClass();
alert(pObj);
pObj.CalledFromAddOn();
Any help will be highly appreciated.
After doing some hard work I finally got it working, the document and window objects in Firefox extension refer to different document and window objects and not the DOM (should be obvious), so we need to find the current window to execute the function or class function, whatever. So, here is the code snippet, which you can use in your extension to invoke DOM javascript:
var doc = Application.activeWindow.activeTab.document;
var win = doc.defaultView; // will give you the DOM window object atleast on firefox and chrome
// Now call your functions or create objects
win.wrappedJSObject.hello();
var pToolObj = new win.wrappedJSObject.PTool();
alert(pToolObj.currTaskNo);

How a variable binds its value to the DOM?

This might be crazy but it intriguing me for quite some time :)
I would like to know how a javascript variable can bind itself do the DOM after it is appended to the body, for example?
var p = document.createElement('p');
p.innerHTML = 'Hello World';
document.body.appendChild(p);
So now I have this p variable which contains an exact reference of that specific paragraph no matter where it is located inside the body.
p.innerHTML = 'new content';
will easily find the paragraph and change its value
So my question is...how this binding is made?
what If I want to re-create that after the variable is gone?
is there any way to attach that again without having to run through the DOM and find it?
I was thinking if somehow each node inside the DOM have its specific identifier that is not the id attribute but some kind of UUID that can be referred later on?
like:
console.log(p.localName); //aoi12e2kj2322444r4t
p = null;
so I can still recover that paragraph node thought this uuid?
In this environment I wouldn't have access to any external node attribute, such name, id, data, etc..
So I am quite curious to know how this binding is created between variable and DOM node?
I believe that it changes depending on the browser your using. There's no standard way to do so. Currently you either use the id or iterate over the dom until you reach the element you want.
The binding is created on the first line, where you assign the result of document.createElement to p. This is no different from any other time you assign something to a variable, which always binds the variable name to the value. As far as the script is concerned, there is no other binding occurring. The p is an HTMLElement, and that's all of the element that's exposed.
Note that for p.innerHTML = 'new content';, the element doesn't have to be found because p already refers to the element. That's what the DOM does: it exposes documents and document elements.
If you later want another reference to the same element, you'll have to use DOM methods (such as getElementById) to find it. That's what they're there for.
As for how the DOM exposes elements, that's implemented internally and varies from browser to browser or library to library (since the DOM isn't used just in browsers).

How to find with javascript if element exists in DOM or it's virtual (has been just created by createElement)

I'm looking for a way to find if element referenced in javascript has been inserted in the document.
Lets illustrate a case with following code:
var elem = document.createElement('div');
// Element has not been inserted in the document, i.e. not present
document.getElementByTagName('body')[0].appendChild(elem);
// Element can now be found in the DOM tree
Jquery has :visible selector, but it won't give accurate result when I need to find that invisible element has been placed somewhere in the document.
Here's an easier method that uses the standard Node.contains DOM API to check in an element is currently in the DOM:
document.body.contains(MY_ElEMENT);
CROSS-BROWSER NOTE: the document object in IE does not have a contains() method - to ensure cross-browser compatibility, use document.body.contains() instead. (or document.head.contains if you're checking for elements like link, script, etc)
Notes on using a specific document reference vs Node-level ownerDocument:
Someone raised the idea of using MY_ELEMENT.ownerDocument.contains(MY_ELEMENT) to check for a node's presence in the document. While this can produce the intended result (albeit, with more verbosity than necessary in 99% of cases), it can also lead to unexpected results, depending on use-case. Let's talk about why:
If you are dealing with a node that currently resides in an separate document, like one generated with document.implementation.createHTMLDocument(), an <iframe> document, or an HTML Import document, and use the node's ownerDocument property to check for presence in what you think will be your main, visually rendered document, you will be in a world of hurt.
The node property ownerDocument is simply a pointer to whatever current document the node resides in. Almost every use-case of contains involves checking a specific document for a node's presence. You have 0 guarantee that ownerDocument is the same document you want to check - only you know that. The danger of ownerDocument is that someone may introduce any number of ways to reference, import, or generate nodes that reside in other documents. If they do so, and you have written your code to rely on ownerDocument's relative inference, your code may break. To ensure your code always produces expected results, you should only compare against the specifically referenced document you intend to check, not trust relative inferences like ownerDocument.
Do this:
var elem = document.createElement('div');
elem.setAttribute('id', 'my_new_div');
if (document.getElementById('my_new_div')) { } //element exists in the document.
The safest way is to test directly whether the element is contained in the document:
function isInDocument(el) {
var html = document.body.parentNode;
while (el) {
if (el === html) {
return true;
}
el = el.parentNode;
}
return false;
}
var elem = document.createElement('div');
alert(isInDocument(elem));
document.body.appendChild(elem);
alert(isInDocument(elem));
You can also use jQuery.contains:
jQuery.contains( document, YOUR_ELEMENT)
Use compareDocumentPosition to see if the element is contained inside document. PPK has browser compatibility details and John Resig has a version for IE.
function isInDocument(query){
return document.querySelectorAll(query).length != 0;
}
// isInDocument("#elemid")

Categories

Resources