Why getting an outer HTML does not work? - javascript

I try to get the outer HTML in two different ways, based on this question. Unfortunately, none of them is giving the expected result:
HTML:
<div id='my_div'>Hello</div>
JS:
$(function() {
document.write('[' + $('#my_div').clone().wrapAll("<div />").parent().get(0).innerHTML + ']<br />');
document.write('[' + (new XMLSerializer().serializeToString(document.getElementById('my_div'))) + ']');
});
The output is:
[
Hello
]
[
Hello
]
I expect the following result: <div id='my_div'>Hello</div>
Live example here
What am I doing wrong ?

First, your first example works fine. Take a look at your output in Firebug. Note, that since your output is HTML it is rendered as HTML. Note that there are newlines before and after the HELLO............... because the HELLOs are inside DIVs!
Take a look:
Second w/ jQuery, you could also use the method in my answer to the question you linked to:
var outerHTML = $('<div>').append( $("#my_div").clone() ).html();
jsFiddle example
This appends a clone of the element in question to a DIV jQuery object and gets the inner HTML of the DIV jQuery object.... which is the outerHTML of the element in question.
The general form of the outerHTML of an element is:
$('<div>').append( $(ElementSelector).clone() ).html();
where ElementSelector is the jQuery selector of the element whose outerHTML you want.
Note: The above adds no new elements to the DOM. $('<div>')...... is never added to the DOM. It remains merely jQuery object independent of the DOM.

Here is a function used in the lib pure.js to get the outerHTML:
function outerHTML(node){
return node.outerHTML || new XMLSerializer().serializeToString(node);
}
And to use it the DOM way:
var html = outerHTML(document.getElementById('my_div'));

UPDATE With DEMO
$(function() {
var html = $('<div>').append($('#my_div').clone()).html();
$('body').html( htmlspecialchars( '[' + html + ']' ) );
});
htmlspecialchars function

try this:
var result = $('<div></div>').append($('#my_div').clone()).html();
alert(result);

You can use get to pull out native DOM element and then use the outerHTML as :
var html = $('#my_div').get(0).outerHTML;
or
var html = $('#my_div')[0].outerHTML;

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>

How to create a Jquery object with containing elements

Forgive me if I haven't been searching in the right places, however, I've been searching all over the internet to find out how to create a jquery object, but I couldn't find a solution that fits my needs.
There is a large amount of html that must be within this object, as I plan to append the object to another element.
Example I have found:
Adding inner Html of element to a string, and adding this to jquery object:
var htmlText = "<div id='foo1'><a class='foo2'><h1 class='foo3'></h1></a></div>"
var $jqueryObject = $("<div>", {
class: "bar",
html: htmlText
});
This seems to have a strange effect when appended however: When appended, the only html left on the webpage was the contents of the jquery object. So in this example, only <div id='foo1'><a class='foo2'><h1 class='foo3'></h1></a></div> would remain (however html, head body tags still existed)
Help is greatly appreciated...
Thanks in advance!
Edit:
I then append this object to an element like so:
$("#foobar").click(function() {
$("#objectContainer").append($jqueryObject);
});
Something like this?
var htmlText = "<div id='foo1'><a class='foo2'><h1 class='foo3'>Test</h1></a></div>";
var $jqueryObject = $("div").append(htmlText).find('.foo3').css("color","red");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>
you can edit the html objects in cache before appending like so:
$(jqueryObject).find('#foo1').css('background-color', 'grey')
https://jsbin.com/vuzosapedu/edit?html,js,output
Maybe your page is being submitted to the server each time you click on your button.
Try
$("#foobar").click(function(e) {
e.preventDefault();
$("#objectContainer").append($jqueryObject);
});

Find And Change Element In a Parsed HTML DOM

I am getting an HTML string in response to an ajax request. It is a large HTML string with a lot of hierarchical child nodes.
I parse it using
jQuery.parseHTML();
to convert it into a DOM. Now i want to change the content of a child node with a certain ID and then regenerate the HTML.
The Problem is when ever i use a jQuery method to select a dom element to make the changes, it returns that particular node and the
jQuery.html()
just changes that node to HTML.
I have tried following code samples
var parsedHTML = jQuery.parseHTML( 'htmlstring' );
jQuery(parsedHTML).find('#element-id').text('changed text').html();
or
jQuery(parsedHTML).filter('#element-id').text('changed text').html();
the problem is it only returns span#element-id and when html() is applied, the generated html has only span text.
How can i generate back the complete html and change the specific node?
Don't chain (or if you do, use end, but simpler really just not to). By chaining, you're saying you only want the HTML of the last set of elements in the chain:
var elements = jQuery(parsedHTML);
elements.filter('#element-id').text('changed text');
var html = elements.html();
But elements.html() will only give you the inner HTML of the first element. To get the full HTML string again, you need to get the outer HTML of each element and join them together:
var html = elements.map(function() {
return this.outerHTML;
}).get().join("");
Note that your use of filter assumes the element is at the top level of the HTML string. If it is, great, that's fine. If it isn't, you'll want find instead.
Example with filter:
var parsedHTML = jQuery.parseHTML(
"<span>no change</span>" +
"<span id='element-id'>change me</span>" +
"<span>no change</span>"
);
var elements = jQuery(parsedHTML);
elements.filter('#element-id').text('changed text');
console.log(elements.map(function() {
return this.outerHTML;
}).get().join(""));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Example with find:
var parsedHTML = jQuery.parseHTML(
"<span>no change</span>" +
"<div>the span is in here<span id='element-id'>change me</span></div>" +
"<span>no change</span>"
);
var elements = jQuery(parsedHTML);
elements.find('#element-id').text('changed text');
console.log(elements.map(function() {
return this.outerHTML;
}).get().join(""));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

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;

jQuery + InnovaStudio WYSIWYG Editor

I am trying to avoid hard-coding each instance of this WYSIWYG editor so I am using jQuery to create an each() loop based on function name. Annoyingly InnovaStudio seems to explode when I try.
Documentation
Attempt #1
<script type="text/javascript">
/*
id = $(this).attr('id');
if(id.length == 0)
{
id = 'wysiwyg-' + wysiwyg_count;
$(this).attr('id', id);
}
WYSIWYG[wysiwyg_count] = new InnovaEditor('WYSIWYG[' + wysiwyg_count + ']');
WYSIWYG[wysiwyg_count].REPLACE(id);
*/
var demo = new InnovaEditor('demo');
demo.REPLACE('wysiwyg-1');
console.log('loop');
</script>
Effect
Works fine, but of course only works for a single instance of the editor. If I want multiple instances I need to use an each.
Attempt #2:
<script type="text/javascript">
var wysiwyg_count = 1;
//var WYSIWYG = [];
var demo;
(function($) {
$(function() {
$('.wysiwyg-simple').each(function(){
/*
id = $(this).attr('id');
if(id.length == 0)
{
id = 'wysiwyg-' + wysiwyg_count;
$(this).attr('id', id);
}
WYSIWYG[wysiwyg_count] = new InnovaEditor('WYSIWYG[' + wysiwyg_count + ']');
WYSIWYG[wysiwyg_count].REPLACE(id);
*/
demo = new InnovaEditor('demo');
demo.REPLACE('wysiwyg-1');
console.log('loop');
});
});
})(jQuery);
</script>
Effect
Replaces the entire HTML body of my page with JUST WYSIWYG related code and complains as no JS is available (not even Firebug, so can't debug).
Notice that I am hardcoding the name still. I only have one instance on the page I am testing it on, so when I get this hard-coded name working I will get the commented out code working along the same lines.
Does anybody know what the hell is going on here?
Solution: Don't bother trying to use InnovaStudio, went with CKEditor instead.
Even though you went for CKEditor you might be interested in a solution. You can supply a second argument to the REPLACE function. This second argument should also be a id, id from a element able to accept html output (like div, span, p).
demo = new InnovaEditor('demo');
demo.REPLACE('wysiwyg-1', 'wysiwyg-1-replaceDiv');
When the second argument is left out, InnovaStudio, writes the html output to the document by simply using:
document.write();
Hope this helps!
Why don't you use their own initialization code since version 4.3:
<textarea class="innovaeditor">
content here...
</textarea>
<script>
oUtil.initializeEditor("innovaeditor",
{width:"700px", height:"450px"}
);
</script>
The method is oUtil.initializeEditor(selector, option). The first parameter is selector and second is editor properties in JSON format.
The selector can be:
Css class name, if class name is specified all textareas with specified class name will be replaced with editor.
Textarea Id. If it is an Id, a prefix '#' must be added, for example oUtil.initializeEditor("#mytextarea").
Textarea object.
The second parameter is editor's properties. All valid editor's properties can be specified here for example width, height, cmdAssetManager, toolbarMode, etc.
Note that this method can be called from page onload or document ready event or during page load (as long as the object referred by selector are already rendered). This method available automatically when the page include the editor script.

Categories