How to detect an jquery element is in DOM? - javascript

I have a jquery element. and I remove it from DOM by using remove(), but jQuery still keep a reference of it.
and later I still can use it and insert it into DOM.
How to detect that this "var p" is in DOM or off DOM ?
var p=$('p');
p.remove();
console.log(p);
p.insertAfter($('body'));
I think p.parent() is more easy way to go. if it in DOM it will get another DOM node

use javascript length to check if dom element exists or not
if($("p").length>0)
{
// p exists
}

var p=$('p');
p.remove();
So when you did p.remove(), it is removed from the dom but it still exists in memory as a stand alone dom node object with all its contents intact.
You can perform any operation as in normal dom element like append anywhere, change contents or change attributes.
The only difference is that it is not part of the document unless you append it in the html.
jQuery has contains method to check if the element is part of the document
jQuery.contains(document, $foo[0]));
p.parent() in case of removed p will return a 0 length jquery object because p is independent node and has no parent.

Related

puzzled about document.documentElement

I got puzzled about it .
1 Is document equal to document.documentElement? I think they are both root node.
2 Why I can use document.documentElement.getElementsByTagName() but I can not use
document.documentElement.getElementById()?
There is a difference between the document object and the document element.
When an HTML document is loaded into a web browser, it becomes a document object.
The document object is the root node of the HTML document and the common ancestor of all other nodes, such as element nodes (including the document element), text nodes and attribute nodes.
One of the differences is that an element has getElementsByTagName() but not getElementById(), which is part of the document itself.
To successfully use an element to get another one based on ID, you need to go through its document:
var elem2 = elem1.ownerDocument.getElementById(whatever)

How does this jquery code work?

(Sorry for the bad title, I can't think of a better one)
I recently learned that you can do something like this in jquery:
$("<div><span>content</span></div>").css("color", "red").appendTo("body");
My question is about the following:
$("<div><span>content</span></div>")
How does jquery turn this from a string into dom elements, and how could you do the same thing in vanilla js (no jquery)?
I have attempted to look through the jquery source code, but I don't really understand it.
Any explanation is greatly appreciated!
the equivalent in pure javascript would be
var newDiv = document.createElement("DIV");
newDiv.style.color = "red";
var newSpan = document.createElement("SPAN");
newSpan.innerHTML = "content";
newDiv.appendChild(newSpan);
document.body.appendChild(newDiv);
jquery shortcuts this by defining functions that are chainable meaning the next function uses the previous functions return value as its input so in your example it is adding the css to your html code and then adding all of that code to the body
jQuery is creating a new instance of a jQuery object that contains a reference to the DOM elements created by parsing <div><span>content</span></div>.
One really useful thing jQuery does is that every invocation of jQuery or any of its API methods returns either the newly created jQuery instance or the current jQuery instance. The benefit of this is that you can chain your calls to transform a set of DOM elements.
In this case, $(...) returns a jQuery instance containing the DOM elements you want to operate on. Next, you chained css() which adds style properties to that element. Finally, you chain appendTo() which adds that to a target DOM element. In this case, that target is the <body> element.
Here's how this process would look (roughly) in JavaScript:
First, we need to create the DOM elements we wish to insert.
var node = document.createElement("div");
node.innerHTML = "<div><span>content</span></div>";
var myElement = node.children[0];
Then we'll set the style properties.
myElement.style.color = "red";
Finally, lets append it to an existing element.
document.body.appendChild(myElement);
The creation of the DOM elements from a string happens through the magic of the innerHTML property. When the JavaScript parser encounters a string being set to an elements innerHTML, it will parse that string into DOM elements and insert those elements as children.
Therefore, what jQuery is doing under the hood is creating a dummy element, setting the string you provided as a value on the dummy elements innerHTML property. This causes the DOM elements to be created and inserted as the dummy elements children. Lastly, it retrieves the reference to the children element (the elements you want).
This line creates an jQuery wrapped object from an html string, essentially creating a div with a span inside it whose text is the word content:
$("<div><span>content</span></div>")
This applies a CSS property to the created element telling it to display the text in red:
.css("color", "red")
This adds the created and styled element to the DOM at the end of the body tag:
.appendTo("body");

Can I keep a reference to a document fragment?

I'm playing around with a document fragment. I find it hard to understand how it behave when I append it to the DOM.
I create a doc fragment that I assign to a variable, when I insert some stuff into it, and append the doc fragment into a element. But if I clear the element my variable which should reference to the doc fragment contain an empty document fragment.
I trying to make a cache for a third party lib that creates document fragments. So I would like to get this working. Should I create a cloneNode before I append the fragment to the DOM, is that correct?
I have created a JS fiddle:
http://jsfiddle.net/4CTXG/1/
var test = document.createDocumentFragment();
//var test = document.createElement("div"); // This one work
$(test).append($("<div>").html('Hello world!'));
$("#result").append(test);
setTimeout(function(){
$("#result").children().remove();
$("#result").append(test);
console.log('Now test should have been appended');
$(result).css({"background": "#FF0000"});
},5000)
When you append an Element (e.g. the <div>) into the DOM, the Element gets added as a child of its new parent. The div's children are not changed. When you remove the element from its parent, the Element is just detached from the DOM. It you still have a reference to the Element it will still contain its children, available to reattach later.
When you append an DocumentFragment into the DOM, the children of the DocumentFragment are removed from the DocumentFragment and moved to be children of its DOM element parent. The DocumentFragment is now empty.
So instead of appending the DocumentFragment, you should append a deep clone of the fragment.
See http://dom.spec.whatwg.org/#concept-node-insert for the gory details.
Javascript objects are copied by reference rather than value. So when you assign the fragment to a variable and then insert the fragment into the DOM, both the variable and the DOM are referencing the same object. Any change you make to one will also occur in the other.
If you really want the variable to reference an object that is distinct from the DOM, then cloning is the right approach.

What is the difference between appendChild, insertAdjacentHTML, and innerHTML

I want to know what the difference is between appendChild, insertAdjacentHTML, and innerHTML.
I think their functionality are similar but I want to understand clearly in term of usage and not the execution speed.
For example, I can use innerHTML to insert a new tag or text into another tag in HTML but it replaces the current content in that tag instead of appends.
If I would like to do it that way (not replace) I need to use insertAdjacentHTML and I can manage where I want to insert a new element (beforebegin, afterbegin, beforeend, afterend)
And the last if I want to create (not insertion in current tag) a new tag and insert it into HTML I need to use appendChild.
Am I understanding it correctly? Or are there any difference between those three?
element.innerHTML
From MDN:
innerHTML sets or gets the HTML syntax describing the element's descendants.
when writing to innerHTML, it will overwrite the content of the source element. That means the HTML has to be loaded and re-parsed. This is not very efficient especially when using inside loops.
node.appendChild
From MDN:
Adds a node to the end of the list of children of a specified parent node. If the node already exists it is removed from current parent node, then added to new parent node.
This method is supported by all browsers and is a much cleaner way of inserting nodes, text, data, etc. into the DOM.
element.insertAdjacentHTML
From MDN:
parses the specified text as HTML or XML and inserts the resulting nodes into the DOM tree at a specified position. [ ... ]
This method is also supported by all browsers.
....
The appendChild methods adds an element to the DOM.
The innerHTML property and insertAdjacentHTML method takes a string instead of an element, so they have to parse the string and create elements from it, before they can be put into the DOM.
The innerHTML property can be used both for getting and setting the HTML code for the content of an element.
#Guffa did explain the main difference ie innerHTML and insertAdjacentHTML need to parse the string before adding to DOM.
In addition see this jsPerf that will tell you that generally appendChild is faster for the job it provides.
One that I know innerHTML can grab 'inner html', appendChild and insertAdjacentHTML can't;
example:
<div id="example"><p>this is paragraph</p><div>
js:
var foo = document.getElementById('example').innerHTML;
end then now
foo = '<p>this is paragraph</p>';
DOCS:
appendChild
insertAdjacentHTML
innerHtml
innerHTML vs appendChild() performance
insertAdjacentHTML vs innerHTML vs appendChild performance
the main difference is location (positioning) :
(elVar mean element saved to variable)
** elVar.innerHTML: used to sets/get text and tags (like ) inside an element (if u use "=" it replace the content and "+=" will add to the end.
** divElvar.appendChild(imgElVar): to add pure element to the end of another element (or start with prepend) .
** insertedElVar.insertAdjacentElement(beforebegin,targetElvar): it insert element into spicific location before elVar (after it with "afterend").
-innerText: can replace/get/insertOnEnd text.but can read tags and text inside element with display:hidden , cant insert on start .
-innercontent : show all text inc hidden , cant read html tags and it put empty spaces instead of them , cant insert on start
-innerHTML: read all set all , cant insert on start
-prepend : insert text at start of elvar (but cant use to get/replace text or html)
prepend was needed for start, after it made its easy to make append , not for a need , its just bcz lol

How to insert a HTML fragment and hold a reference to the outer element?

I've always wondered how this jQuery feature works: $('<span>Hello world</span>')[0]
That is supposed to return a reference to the newly created span element. How can I achieve the same result using the native DOM methods? insertAdjacentHTML? innerHTML? documentFragment?
I need to insert a HTML fragment and hold a reference to the outer element without the need of using createElement/appendChild.
Thanks.
It's possible to create an element, set its innerHTML, and return the first child. The container element is never added to the DOM:
var el = document.createElement('div');
el.innerHTML = '<span>Hello world</span>';
console.log(el.firstChild);
If that's wrapped in a function, I believe the original container will be eligible for garbage collection as soon as the child is appended somewhere else.
jQuery seems to be doing something more sophisticated, checking if the string contains a single tag or not, and creating a fragment for more complicated strings. See the parseHTML method on jQuery's source code.

Categories