This post was the most helpfull to understand createDocumentFragment() instead of createElement()
Should I use document.createDocumentFragment or document.createElement
I've understood that for performance reason using fragment will help on big dataset so i want to conver my function.
This is what i use right now and it works as desired => Get content from a php file with ajax and then append this content at the top of existing div#wrapperinside a new div.feedBox(r being the XMLHTTP /ACTIVE OBJECT)
r.onreadystatechange=function(){
if(r.readyState==4 && r.status==200){
//Want to convert this to createDocumentFrangment --START
var n = document.createElement("div");
n.className = "feedBox";
n.innerHTML = r.responseText;
document.getElementById("wrapper").insertBefore(n, document.getElementById("wrapper").firstChild);
//Want to convert this to createDocumentFrangment --END
}
}
This is what i tried, but what happens is the content is added but without the div.feedBox
var n = document.createElement("div");
n.className = "feedBox";
n.innerHTML = r.responseText;
var f = document.createDocumentFragment();
while (n.firstChild) { f.appendChild(n.firstChild); }
document.getElementById("wrapper").insertBefore(f, document.getElementById("wrapper").firstChild);
What did i miss? can you explain why and how to make it work?
Is this really a more efficient way of doing this?
PS: NO jquery please. I know it well and i use it widely on other project but i want this to be as small / lite / efficient as possible.
Shouldn't this line
while (n.firstChild) { f.appendChild(n.firstChild);
be
f.appendChild(n);
Also I see that you are not appending the div.feedBox to your DOM anywhere..
What happens if the while condition fails.. You are not appending anything to your DOM..
I am assuming this will work .. Not tested though
f.appendChild(n)
document.getElementById("wrapper").appendChild(f,
document.getElementById("wrapper").firstChild);
ALso better to use
.appendChild(f, instead of .insertBefore(f,
Check Fiddle
This is the full working function, any1 sould feel free to use it:
function ajax_fragment(php_file){
if (window.XMLHttpRequest){
r=new XMLHttpRequest();
} else{
r=new ActiveXObject("Microsoft.XMLHTTP");
}
r.onreadystatechange=function(){
if(r.readyState==4 && r.status==200){
var n = document.createElement("div"); //Create a div to hold the content
n.className = "feedBox"; //Give a class 'feddBox' to the div
n.innerHTML = r.responseText; //Put the response in the div
var f = document.createDocumentFragment(); //Create the fragment
f.appendChild(n); //Add the div to the fragment
//Append the fragment's content to the TOP of wrapper div.
document.getElementById("wrapper").insertBefore(f, document.getElementById("wrapper").firstChild);
}
}
r.open("GET",php_file,true);
r.send();
}
Related
I am making a plugin for form validation as practice, but for some reason after I create a h2 element and try to set it's attribute, it is not working. Here is the code
var testing = function(regex, value, error_msg, error_msg_field_id){
var pattern = new RegExp(regex);
if (!pattern.test(value)){
var ele = document.createElement("H2");
var node = document.createTextNode(error_msg);
ele.setAttribute('style', 'color:white');
alert("hi");
jQuery(error_msg_field_id).append(node);
}
}
the text appears with no problem, but it is not in white color. This make no sense at all to me
You are using setAttribute correctly, but you are setting the property on your h2-element, which is never actually inserted in your DOM.
You can change and simplify the relevant section of your code to:
var ele = document.createElement("H2");
ele.textContent = error_msg;
ele.setAttribute('style', 'color:white');
jQuery(error_msg_field_id).append(ele);
The usage of jQuery here is also not necessary. You can simply use
document.querySelector("#" + error_msg_field_id).appendChild(ele);
which is equally simple.
I am trying to remove scripts and their content from html body and this is what I have came up until now
just_text = just_text.replace(/<\s*script[^>]*>(<\s*\/script[^>]*>|$)/ig, '');
It does not work as want to, I still get the content.
Can you please help me?
Thank you
The answer to such questions is always the same: Don't use regular expressions. Instead, parse the HTML, modify the DOM and serialize it back to HTML if you need to.
Example:
var container = document.createElement('div');
container.innerHTML = just_text;
// find and remove `script` elements
var scripts = container.getElementsByTagName('script');
for (var i = scripts.length; i--; ) {
scripts[i].parentNode.removeChild(scripts[i]);
}
just_text = container.innerHTML;
If you want to remove the script tags from the page itself, it's basically the same:
var scripts = document.body.getElementsByTagName('script');
for (var i = scripts.length; i--; ) {
scripts[i].parentNode.removeChild(scripts[i]);
}
I have been strugling with this for a while and I am sure there is a simple answer to this. What happens is I remove a div called "payment" then dynamicaly create it again so I can add to it. That then gets repeated as the infomation that needs to be added to it changes.
I have mangaged to get this so far.
function clearPage()
{
var d = document.getElementById("contain");
var d_nested = document.getElementById("payment");
var deleteNode = d.removeChild(d_nested);
}
function createPayment()
{
payment = document.createElement("div");
payment.id = "mine";
document.getElementById("contain").appendChild(payment);
}
function printOnPage()
{
var x = names.length;
for( var i = 0 ; i < x ; i++ )
{
var para = document.createElement("p");
var paymentDiv = document.getElementById("payment");
paymentDiv.appendChild(para);
var txtName = document.createTextNode("Item: ");
para.appendChild(txtName);
var txtNameArray = document.createTextNode(names[i]);
para.appendChild(txtNameArray);
var txtQty = document.createTextNode(" Qty: ");
para.appendChild(txtQty);
var txtQtyArray = document.createTextNode(qty[i]);
para.appendChild(txtQtyArray);
var txtCost = document.createTextNode(" Cost: ");
para.appendChild(txtCost);
var txtCostArray = document.createTextNode(prices[i]);
para.appendChild(txtCostArray);
}
}
Related HTML
<div id="contain">
<p>Payment</p>
<div id="payment">
<br />
</div>
</div>
It needs the ID of payment for both my CSS rules and for my creating the text that goes in it.
This is the error I get in FireFox
Error: paymentDiv is null Source File:
http://itsuite.it.brighton.ac.uk/ks339/sem2/javascript/js.js Line: 76
Hope someone can provide some insight in to this and please tell me if I am completly off!
Thanks
Edit: Is it easior to clear the div rather than delete it, how would I go about doing such a thing?
In create_payment(), you set the ID to 'mine'. Shouldn't it be 'payment'?
I do not understand your requirements very well, but anyway you cannot create multiple items in the page using the same id attribute, if you want to duplicate an item and still have control over it, you should be using class instead.
Try switching your code into jquery it will be cleaner and easier to understand for you & me.
Your problem is the fact that in createPayment() you're setting the id to 'mine':
payment.id = "mine";
while later on in printOnPage() you're looking for the element using id 'payment':
var paymentDiv = document.getElementById("payment");
As you mention in your edit, it is far easier just to clear the div than to remove it, specially if you still need it later.
To clear a DIV-block just set it's content to empty:
document.getElementById('payment').innerHTML = "";
I hope you find a solution! Good luck!
Any ideas on how I would convert this jQuery to vanilla JS:
$('.section > h1').after('<p>This paragraph was inserted with jQuery</p>');
I am new to jQuery and even newer to vanilla JS.
This is as far as I got:
var newP = document.createElement('p');
var pTxt = document.createTextNode('This paragraph was inserted with JavaScript');
var header = document.getElementsByTagName('h1');
Not sure where to go from here?
jQuery does a lot for you behind the scenes. The equivalent plain DOM code might look something like this:
// Get all header elements
var header = document.getElementsByTagName('h1'),
parent,
newP,
text;
// Loop through the elements
for (var i=0, m = header.length; i < m; i++) {
parent = header[i].parentNode;
// Check for "section" in the parent's classname
if (/(?:^|\s)section(?:\s|$)/i.test(parent.className)) {
newP = document.createElement("p");
text = document.createTextNode('This paragraph was inserted with JavaScript');
newP.appendChild(text);
// Insert the new P element after the header element in its parent node
parent.insertBefore(newP, header[i].nextSibling);
}
}
See it in action
Note that you can also use textContent/innerText instead of creating the text node. It's good that you're trying to learn how to directly manipulate the DOM rather than just letting jQuery do all the work. It's nice to understand this stuff, just remember that jQuery and other frameworks are there to lighten these loads for you :)
You might find this function useful (I didn't test)
function insertAfter(node, referenceNode) {
referenceNode.parentNode.insertBefore(node, referenceNode.nextSibling);
}
Oh it's not so bad...
var h1s = document.getElementsByTagName('h1');
for (var i=0, l=h1s.length; i<l; i++) {
var h1 = h1s[i], parent = h1.parentNode;
if (parent.className.match(/\bsection\b/i)) {
var p = document.createElement('p');
p.innerHTML = 'This paragraph was inserted with JavaScript';
parent.insertBefore(p, h1.nextSibling);
}
}
Imagine I have the following HTML:
<div><span><b>This is in bold</b></span></div>
I want to get the HTML for the div, including the div itself. Element.innerHTML only returns:
<span>...</span>
Any ideas? Thanks
Use outerHTML:
var el = document.getElementById( 'foo' );
alert( el.outerHTML );
Expanding on jldupont's answer, you could create a wrapping element on the fly:
var target = document.getElementById('myElement');
var wrap = document.createElement('div');
wrap.appendChild(target.cloneNode(true));
alert(wrap.innerHTML);
I am cloning the element to avoid having to remove and reinsert the element in the actual document. This might be expensive if the element you wish to print has a very large tree below it, though.
First, put on element that wraps the div in question, put an id attribute on the element and then use getElementById on it: once you've got the lement, just do 'e.innerHTML` to retrieve the HTML.
<div><span><b>This is in bold</b></span></div>
=>
<div id="wrap"><div><span><b>This is in bold</b></span></div></div>
and then:
var e=document.getElementById("wrap");
var content=e.innerHTML;
Note that outerHTML is not cross-browser compatible.
old question but for newcomers that come around :
document.querySelector('div').outerHTML
You'll want something like this for it to be cross browser.
function OuterHTML(element) {
var container = document.createElement("div");
container.appendChild(element.cloneNode(true));
return container.innerHTML;
}
If you want a lighter footprint, but a longer script, get the elements innerHTML and only create and clone the empty parent-
function getHTML(who,lines){
if(!who || !who.tagName) return '';
var txt, ax, str, el= document.createElement('div');
el.appendChild(who.cloneNode(false));
txt= el.innerHTML;
ax= txt.indexOf('>')+1;
str= txt.substring(0, ax)+who.innerHTML+ txt.substring(ax);
el= null;
return lines? str.replace(/> *</g,'>\n<'): str;
//easier to read if elements are separated
}
var x = $('#container').get(0).outerHTML;
as outerHTML is IE only, use this function:
function getOuterHtml(node) {
var parent = node.parentNode;
var element = document.createElement(parent.tagName);
element.appendChild(node);
var html = element.innerHTML;
parent.appendChild(node);
return html;
}
creates a bogus empty element of the type parent and uses innerHTML on it and then reattaches the element back into the normal dom
define function outerHTML based on support for element.outerHTML:
var temp_container = document.createElement("div"); // empty div not added to DOM
if (temp_container.outerHTML){
var outerHTML = function(el){return el.outerHTML||el.nodeValue} // e.g. textnodes do not have outerHTML
} else { // when .outerHTML is not supported
var outerHTML = function(el){
var clone = el.cloneNode(true);
temp_container.appendChild(clone);
outerhtml = temp_container.innerHTML;
temp_container.removeChild(clone);
return outerhtml;
};
};
var el = document.getElementById('foo');
el.parentNode.innerHTML;