javascript innerHTML adding instead of replacing - javascript

quick question, i know we can change the content of a
<div id="whatEverId">hello one<div> by using:
document.getElementById("whatEverId").innerHTML="hello two";
now, is there a way I can ADD stuff to the div instead of replacing it???
so i can get
<div id="whatEverId">hello one hello two<div>
(using something similar of course)

<div id="whatever">hello one</div>
<script>
document.getElementById("whatever").innerHTML += " hello two";
</script>

Notice that using element.innerHTML += 'content' would empty inputs and textareas to their default, blank state, unclick checkboxes, as well as removing any events attached to those elements (such as onclick, on hover etc.) because the whole innerHTML would be reinterpreted by the browser, which means .innerHTML is emptied and filled again from scratch with the combined content.
If you need to keep the state, you'd need to create a new element (a <span> for instance) and append it to the current element, as in:
let newElement = 'span'
newElement.innerHTML = 'new text'
document.getElementById('oldElement').appendChild(newElement)

document.getElementById("whatEverId").innerHTML = document.getElementById("whatEverId").innerHTML + "hello two" + document.getElementById("whatEverId").innerHTM ;

What jcomeau_ictx suggested is an inefficient way of editing the innerHTML.
Check Ben cherry's PPT http://www.bcherry.net/talks/js-better-faster
The correct way will be detaching the element and making changes to it and then appending it back to the parent node.
Use https://gist.github.com/cowboy/938767 Native javascript from this gist to
detach element.

If you are appending, you can just change your = to a +=
document.getElementById("whatEverId").innerHTML += 'hello two';
If prefixing
document.getElementById("whatEverId").innerHTML = 'hello two' + document.getElementById("whatEverId").innerHTML;
Although I would highly recommend using jQuery or MooTools javascript libraries/frameworks to do this sort of thing. If you're adding tags not just text nodes, then you should use the DOM createElement or one of the aforementioned libraries/frameworks.

You can do it by appending div string like this..
document.getElementById('div_id').innerHTML += 'Hello Two';

Related

jquery's version of ".innerHTML +=" for an array html insertion

I have read through some questions pertaining specifically to innerHTML= vs .html(). But yet have crossed anything to add into the variable like innerHTML+= to the html(). Is there a jquery event that can add more than just one html string? Or shall I rely on innerHTML+= for now?
The coding that best describes the current issue:
var pushy = ['blah', 'blaH', 'blaah'];
for(i=0;i<pushy.length;i++){
document.getElementById("demo").innerHTML +=
"<div>Im one heck of a div and more!</div>" + pushy[i];}
vs
$("#demo").html("<div>Im one heck of a div and more!</div>" + pushy[i]);
//where it will return the last array value and not the first value
Although the first is the go to and failsafe. But wanted to see the exact equivalent than just pop the last value of the array. Here is my innerHTML+= vs .html() for example. The question is not pertaining to the innerHTML = but rather the += thereof.
You are probably looking for .append()
$('element').append('SOME HTML');
You example (updated)
https://jsfiddle.net/4pqegj5f/9/
are you looking for
$("#demo").append("<div>Im one heck of a div and more!</div>" + pushy[i]);
Using .append should get you the desired result. See below:
var pushy = ['blah', 'blaH', 'blaah'];
for(i=0;i<pushy.length;i++){
$("#demo").append("<div>Im one heck of a div and more!</div>" + pushy[i]);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="demo"></div>

Creating elements within elements with javascript

Noob here. I searched on the internet a bit to find an answer to a question and I can't seem to find any (and that brings my hope down). So here I am.
I was wondering if there is a way to create an HTML element with javascript, BUT inside the newly created HTML element to create also another HTML element with javascript. I guess you can call it elementception //wink
To be more specific, I would like to create a paragraph with text, but I would like to include links in that text (or possibly buttons?).
var para = document.createElement("P");
var t = document.createTextNode("This is a paragraph. Can I do this: <a href='blabla'>like so?</a>");
para.appendChild(t);
document.body.appendChild(para);
I tried writing HTML tags inside the strings of the TextNode, but even I can see that was stupid of me. Is there a noobish(simple) way to achieve this, or any way at all? If I'm asking the impossible, please be harsh and blunt about it, so that I never ask questions again.
Thanks.
The simplest way to do this would be:
para.innerHTML = 'This is a paragraph. Here is a link: like so?';
I would use the DOM API approach instead of using innerHTML for readability, maintainability and security reasons. Sure innerHTML has been around for a long time, but just because it is easy doesn't mean you should use it for everything.
As well, if you're going to be learning JavaScript you should get acquainted with the DOM API sooner than later. It will save you a lot of headaches down the road if you get the hang of the API now.
// Create the parent and cache it in a variable.
var para = document.createElement( "p" );
// Create a text node and append it to the child.
// We don't need to cache this one because we aren't accessing it again.
para.appendChild( document.createTextNode( "This is a paragraph. Can I do this: " ) );
// Create our link element and cache it in a variable.
var link = document.createElement( "a" );
// Set the link's href attribute.
link.setAttribute( 'href', 'blabla' );
// Create a text node and append it to the link
// We don't need to cache the text node.
link.appendChild( document.createTextNode( 'like so?' ));
// Append the link to the parent.
para.appendChild( link );
// Append the parent to the body.
document.body.appendChild( para );
DOM API methods used:
Document.createElement()
Document.createTextNode()
Node.appendChild()
Element.setAttribute()
Further reading:
Document Object Model (DOM)
Element.innerHTML Security Considerations
Advantages of createElement over innerHTML?
Simply use innerHTML attribute to put HTML inside your element instead of createTexteNode, here's what you need:
var para = document.createElement("P");
para.innerHTML = "This is a paragraph. Can I do this: <a \"blabla\">like so?</a>";
document.body.appendChild(para);
Because as its name says, document.createTextNode() will only create a text and can't create HTML elements.
var para = document.createElement("P");
para.innerHTML = "This is a paragraph. Can I do this: like so?";
document.body.appendChild(para);

HTML DOM manipulation : properly replace tag by heading tag

I want to replace some tag-inside-a-paragraph-tag by a heading-tag-enclosed-by-a-paragraph tag. This would result in proper W3C coding, but it seems that jQuery is not able to manipulate the DOM in the right way!? I tried several ways of (jQuery) coding, but i can't get it to work ..
Original code:
<p>some text <span>replace me</span> some more text</p>
Desired code:
<p>some text</p><h2>my heading</h2><p>some more text</p>
Resulting code by jQuery replaceWith():
<p>some text<p></p><h2>my heading</h2><p></p>some more text</p>
Demo: http://jsfiddle.net/foleox/J43rN/4/
In this demo, look at "make H2 custom" : i expect this to work (it's a logical replace statement), but it results in adding two empty p-tags .. The other 2 functions ("make code" and "make H2 pure") are for reference.
Officially the W3C definition states that any heading tag should not be inside a paragraph tag - you can check this by doing a W3C validation. So, why does jQuery add empty paragraph tags? Does anybody know a way to achieve this? Am i mistaken somehow?
You can achieve this with this code. However it's pretty ugly:
$('.replaceMe').each(function() {
var $parent = $(this).parent(),
$h2 = $(this).before('$sep$').wrap('<h2>').parent().insertAfter($parent);
var split = $parent.html().split('$sep$');
$parent.before('<p>' + split[0] + '</p>');
$h2.after('<p>' + split[1] + '</p>');
$parent.remove();
});
http://jsfiddle.net/J43rN/5/
If you read the jQuery docs, you will find:
When the parameter has a single tag (with optional closing tag or
quick-closing) ā€” $("<img />") or $("<img>"), $("<a></a>") or $("<a>")
ā€” jQuery creates the element using the native JavaScript
createElement() function.
So that is exactly what it is doing. And as I said in my comment, you can't change a parent node from a child node, you're altering the DOM here, not HTML code. So you'll need to either use replaceWith on the parent node and replace everything or use something like remove and append to split it up in multiple elements which you append after each other.
Try this:
var temp = "<p>some text <span>replace me</span> some more text</p>";
temp.replace(/(\<span\>replace me\<\/span\>)/gi, '</p><h2>my heading</h2><p>');
This will do a case insensitive replace for multiple occurences as well.
Read more about capturing groups here
Original credit to this question!
Please try this I have updated the http://jsfiddle.net/J43rN/6/ example by the below java script function please check I hope it will work for you
function fnMakeCode() {
$('#myP #replaceMe').html("<code id='replaceMe'>My Code</code>");
}
function fnMakeH2pure() {
$('#myP #replaceMe').html("<h2 id='replaceMe'>My H2 pure</h2>");
}
function fnMakeH2custom() {
$('#replaceMe').html("<p></p>").html("<h2>My H2 custom</h2>");
}

How to append text to a div element?

Iā€™m using AJAX to append data to a <div> element, where I fill the <div> from JavaScript. How can I append new data to the <div> without losing the previous data found in it?
Try this:
var div = document.getElementById('divID');
div.innerHTML += 'Extra stuff';
Using appendChild:
var theDiv = document.getElementById("<ID_OF_THE_DIV>");
var content = document.createTextNode("<YOUR_CONTENT>");
theDiv.appendChild(content);
Using innerHTML:
This approach will remove all the listeners to the existing elements as mentioned by #BiAiB. So use caution if you are planning to use this version.
var theDiv = document.getElementById("<ID_OF_THE_DIV>");
theDiv.innerHTML += "<YOUR_CONTENT>";
Beware of innerHTML, you sort of lose something when you use it:
theDiv.innerHTML += 'content';
Is equivalent to:
theDiv.innerHTML = theDiv.innerHTML + 'content';
Which will destroy all nodes inside your div and recreate new ones. All references and listeners to elements inside it will be lost.
If you need to keep them (when you have attached a click handler, for example), you have to append the new contents with the DOM functions(appendChild,insertAfter,insertBefore):
var newNode = document.createElement('div');
newNode.innerHTML = data;
theDiv.appendChild(newNode);
If you want to do it fast and don't want to lose references and listeners use: .insertAdjacentHTML();
"It does not reparse the element it is being used on and thus it does not corrupt the existing elements inside the element. This, and avoiding the extra step of serialization make it much faster than direct innerHTML manipulation."
Supported on all mainline browsers (IE6+, FF8+,All Others and Mobile): http://caniuse.com/#feat=insertadjacenthtml
Example from https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML
// <div id="one">one</div>
var d1 = document.getElementById('one');
d1.insertAdjacentHTML('afterend', '<div id="two">two</div>');
// At this point, the new structure is:
// <div id="one">one</div><div id="two">two</div>
If you are using jQuery you can use $('#mydiv').append('html content') and it will keep the existing content.
http://api.jquery.com/append/
IE9+ (Vista+) solution, without creating new text nodes:
var div = document.getElementById("divID");
div.textContent += data + " ";
However, this didn't quite do the trick for me since I needed a new line after each message, so my DIV turned into a styled UL with this code:
var li = document.createElement("li");
var text = document.createTextNode(data);
li.appendChild(text);
ul.appendChild(li);
From https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent :
Differences from innerHTML
innerHTML returns the HTML as its name indicates. Quite often, in order to retrieve or write text within an element, people use innerHTML. textContent should be used instead. Because the text is not parsed as HTML, it's likely to have better performance. Moreover, this avoids an XSS attack vector.
Even this will work:
var div = document.getElementById('divID');
div.innerHTML += 'Text to append';
An option that I think is better than any of the ones mentioned so far is Element.insertAdjacentText().
// Example listener on a child element
// Included in this snippet to show that the listener does not get corrupted
document.querySelector('button').addEventListener('click', () => {
console.log('click');
});
// to actually insert the text:
document.querySelector('div').insertAdjacentText('beforeend', 'more text');
<div>
<button>click</button>
</div>
Advantages to this approach include:
Does not modify the existing nodes in the DOM; does not corrupt event listeners
Inserts text, not HTML (Best to only use .insertAdjacentHTML when deliberately inserting HTML - using it unnecessarily is less semantically appropriate and can increase the risk of XSS)
Flexible; the first argument to .insertAdjacentText may be beforebegin, beforeend, afterbegin, afterend, depending on where you'd like the text to be inserted
you can use jQuery. which make it very simple.
just download the jQuery file add jQuery into your HTML
or you can user online link:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
and try this:
$("#divID").append(data);
The following method is less general than others however it's great when you are sure that your last child node of the div is already a text node. In this way you won't create a new text node using appendData MDN Reference AppendData
let mydiv = document.getElementById("divId");
let lastChild = mydiv.lastChild;
if(lastChild && lastChild.nodeType === Node.TEXT_NODE ) //test if there is at least a node and the last is a text node
lastChild.appendData("YOUR TEXT CONTENT");
java script
document.getElementById("divID").html("this text will be added to div");
jquery
$("#divID").html("this text will be added to div");
Use .html() without any arguments to see that you have entered.
You can use the browser console to quickly test these functions before using them in your code.
Why not just use setAttribute ?
thisDiv.setAttribute('attrName','data you wish to append');
Then you can get this data by :
thisDiv.attrName;

Find + replace content of an element without losing events

I have a function that reads the content of an element, replaces a word with a link and then rewrites the content back into the element. Obviously this means that all events that were previously set are lost.
Does anyone know of a function/method that could find and replace the content of an element without losing the events?
Edit: Without using a library
Here is my current code that does not destroy the events but turns <, for example, into <, so I can not append HTML. This is the closest I have got:
element.appendChild(document.createTextNode(content));
My original code worked but got rid of the events:
element.innerHTML += content;
By using jQuery you could do it with the text() method
var str = $('#element-id').text();
str = yourReplaceFunction(str);
$('#element-id').text(str);
Edit:
Another option would the innerHTML property. It's not very elegant but works nevertheless.
var strElem = document.getElementById('element-id');
var str = strElem.innerHTML;
str = yourReplaceFunction(str);
strElem.innerHTML = str;
Edit2:
Yet another option would be to wrap the text you want to replace inside of a separate tag, for example <span>.
<div id="container">
<a id="link-with-events">Link</a>
<span id="replaceable">The Text Gets Replaced</span>
<a id="more-links-with-events">Another Link</a>
</div>
Then you'd simply access and replace the contents of the span tag, leaving the surrounding elements untouched.
Assuming the tag contains just text (and not additional tags):
element.firstChild.nodeValue=content;
See https://jsfiddle.net/Abeeee/ubj6hte4/

Categories