How to insert elements into html document from string? - javascript

I have a string of html code stored in the localStorage, and what I want is to convert that string into a document and add that doc to an existing page. So far I came up with:
var data = localStorage.getItem("data");
var frag = document.createRange().createContextualFragment(data);
document.body.appendChild(frag);
but in the page the document fragment is just a simple string.
EDIT
I currently have the html:
<html>
<head>
</head>
<body>
</body>
</html>
The string I saved for test purpose to the localStorage was <p>Test</p>
The result I am trying to get:
<html>
<head>
</head>
<body>
<p>Test</p>
</body>
</html>
The result I get:
<html>
<head>
</head>
<body>
"<p>Test</p>"
</body>
</html>

If the text in local storage is HTML, you can insert it at the beginning of, at the end of, in front of, or after any other existing element by using insertAdjacentHTML. For example, to add to the document using the HTML in html inside the document body at the end:
document.body.insertAdjacentHTML("beforeend", html);
Example:
const html = "<p>This is a new paragraph with <em>emphasized</em> text.</p>";
document.body.insertAdjacentHTML("beforeend", html);
<p>This paragraph is already on the page.</p>
You can also use the innerHTML property of an existing element if you want to completely remove that element's current contents and replace them with what's defined in the HTML string:
someElement.innerHTML = html;
Example:
const html = "This is the new content for the paragraph, with <em>emphasized</em> text.";
document.getElementById("existing-paragraph").innerHTML = html;
<p id="existing-paragraph">This paragraph is already on the page.</p>
If it's not HTML, you can put it in an element (such as a p or div) and append that somewhere via appendChild or insertBefore, e.g.:
const p = document.createElement("p");
p.textContent = text;
document.body.appendChild(p);
Example:
const text = "This is plain text, so things like <this> don't get misinterpreted as HTML.";
const p = document.createElement("p");
p.textContent = text;
document.body.appendChild(p);
Or just append it as raw text using createTextNode:
const textNode = document.createTextNode(text);
document.body.appendChild(textNode);
Example:
const text = "This is plain text, so things like <this> don't get misinterpreted as HTML.";
const textNode = document.createTextNode(text);
document.body.appendChild(textNode);
There's lots more to explore on MDN.
In the comments we've figured out that the text in local storage has already been HTML-encoded, like this:
<p>Testing <em> one two three</em></p>
That means that whatever code put the text in local storage encoded it before doing that (because local storage doesn't do that; it faithfully stores and returns the exact string you give it). The best solution is probably to update that code so that it doesn't do that.
If you can't update that code, you can interpret that text as HTML, you just have to do it twice: Once to interpret the < and such so they're < again, then again to insert and parse the resulting HTML. The easy way to do that is to create an element (a div for instance), set its innerHTML, and then read its textContent. Here's an example:
Example:
const textFromLocalStorage = "<p>Testing <em> one two three</em></p>";
const div = document.createElement("div");
div.innerHTML = textFromLocalStorage;
const decodedHtml = div.textContent;
document.body.insertAdjacentHTML("beforeend", decodedHtml);
<p>This paragraph is already on the page.</p>

the arguments of appendChild are html elements.
When you send to this a string, it converts to textnode.
You need to use innerHTML method

may be that ?
const DomParser = new DOMParser();
let data = localStorage.getItem("data");
let frag = DomParser.parseFromString( data, 'text/html').body.firstChild
document.body.appendChild(frag);
expecting data is only 1 html element (it can have many html sub elements)
sample code
const DomParser = new DOMParser();
let data = '<p>Test</p>' // eq: localStorage.getItem("data");
let frag = DomParser.parseFromString( data, 'text/html').body.firstChild;
document.body.appendChild(frag);
p {
font-size: 30px;
color: red;
}

Related

How to add break tags after inserting a paragraph into html using javascript's createElement

I've successfully inserted a paragraph element into html page using javascript but the 2nd consecutive paragraph comes side by side and I wish to add a break tag to print them in another line, how do I do that?
Here is a screenshot of my output:
Here is my javascript code:
function newtask(){
let ask = prompt("Enter the description of task");
const para = document.createElement("p");
const Textnode = document.createTextNode(ask);
para.appendChild(Textnode);
let text= document.getElementById("new")
text.appendChild(Textnode);
}
Here is the relevant html
<script src="index.js"></script>
<h1>To do List</h1>
<button onclick="newtask()">New Task</button>
<div id="new">
<p>test</p>
</div>
You were appending Textnode to your parent element, not your new <p> element. Here's a quick rewrite that should give you your desired results.
Firstly, create the new <p> element, then modify its innerText property. After that, just append your new <p>.
function newtask() {
const text = document.getElementById("new");
const ask = prompt("Enter the description of task");
const para = document.createElement("p");
para.innerText = ask;
text.appendChild(para);
}
You can wrap your p inside a div and add a display: flex configuration.
const paraDiv = document.createElement("div");
// Add your style configuration to your paraDiv
function newtask(){
let ask = prompt("Enter the description of task");
const para = document.createElement("p");
paraDiv.appendChild(para)
const Textnode = document.createTextNode(ask);
para.appendChild(Textnode);
let text= document.getElementById("new")
text.appendChild(Textnode);
}

How to inject html tags within a script in Javascript?

I have a string where I would like to inject a <br> tag based on array values.
My html code:
'Hello people. `<span>`Hello to everyone`</span>`';
<script>
let array = ['Hello', 'to everyone'];
</script>
I need to inject <br> tag between 'Hello' and 'to everyone' inside <span> based on contents of array. How can I do it without replacing the tags and not affecting the first 'Hello' word?
Expected output:
'Hello people. `<span>`Hello `<br>` to everyone`</span>`'
You should do this by clearing the contents of the <span> element, then iterate over the array with a foreach method where you add the contents of the array then a line break(<br>).You can define the line break with const lineBreak = document.createElement('br'); , then you can add it to the span element with some DOM manipulation like this elem.appendChild(lineBreak)
Here is the full code:
<head>
<title>hello world</title>
</head>
<body>
<p>Hello people. <span id='message' style="WHITE-SPACE: br">Hello to everyone</span></p>
<script>
function split_words(){
let array = ['Hello', 'to everyone'];
const elem = document.getElementById('message');
let result = '';
const lineBreak = document.createElement('br');
elem.innerHTML = '';
array.forEach(word => {
elem.innerHTML += word;
elem.appendChild(lineBreak)
});
}
window.onload = split_words();
</script>
</body>
You could just use \n or <br/> within the text.
Your code will look something like so
document.write(`Hello people. <span>Hello <br> to everyone</span>`);

Strip certain html tags and return the rest of the string with all the other tags

I have a basic string with HTML tags in it. I want to remove the "span" tag and all of its contents and return the rest of the string and html.
When I do the following, it returns "here"...which is the contents of the matched query...I want to get everything else not the "span" stuff...what am I doing wrong?
var temp = '<div>Some text</div><p style="color:red">More text<span>here</span></p><p>Even more</p>';
var clean_temp = $(temp).find('span').remove();
var $temp = $(clean_temp).html(); //Returns "here"
alert($temp); // "here"
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
The jQuery remove() function removes and item and then returns the removed item, as you already seem to have discovered. The object from which it was removed is still also there, with its content modified.
Also in this case, due to the nature of your source string, doing $() on the source string returns a jQuery collection that wraps 3 separate DOM elements. Doing .find('span').remove() on that collection modifies the middle of these wrapped DOM elements. To reconstruct the HTML, we have to generate HTML from each wrapped DOM element and then join all these HTML parts together.
I created a helper function getHtml() for that purpose, see demo:
function getHtml(jqueryObj) {
return jqueryObj.toArray().map(el => el.outerHTML).join("");
}
var temp = '<div>Some text</div><p style="color:red">More text<span>here</span></p><p>Even more</p>';
var $temp = $(temp);
console.log(getHtml($temp));
$temp.find('span').remove();
console.log(getHtml($temp));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
You can replace it with an empty string:
var temp = `
<div>Some text</div>
<p style="color:red">
More text <span>here</span>
</p>
<p>
Even more
<span>here as well</span>
</p>`;
// The modifier g looks global, not just the first hit and i is for case-insensitive
var expression = new RegExp(/<span(.*?)<\/span>/gi) // no closing '>' for elements with attributes
var clean_temp = temp.replace(expression, '')
console.log(clean_temp);

How to extract an array of all HTML tags from a textbox using javascript

I want to extract all the HTML tags like from this <body id = "myid"> .... </body> i just want to extract <body id ="myid"> similarly i want to extract all the HTML tags with attributes and using javascript.
I've tried using regex to make an array of all the tags inclosed between '< & >'
<script>
$(document).ready(function(){
// Get value on button click and show alert
$("#btn_parse").click(function(){
var str = $("#data").val();
var arr = str.split(/[<>]/);
$('#result').text(arr);
});
});
</script>
but it's creating an array arr containing empty and garbage also it's removing angular brackets '<>'
which I don't want.
SO in nutshell I want a script that takes
str ='mystring ... <htmltag id='myid' class='myclass'>i_don't_want_anythin_from_here</htmltag> ...';
and produces an array like:
arr = ["<htmltag id='myid' class='myclass'>","</htmltag>",...];
Here is one dirty way. Add it to the dom so it can be accessed via normal DOM functions, then remove the text, and split the tags and push to an array.
str ="mystring ... <htmltag id='myid' class='myclass'>i_don't_want_anythin_from_here</htmltag> ...";
div = document.createElement("div");
div.innerHTML = str;
document.body.appendChild(div);
tags = div.querySelectorAll("*");
stripped = [];
tags.forEach(function(tag){
tag.innerHTML = "";
_tag = tag.outerHTML.replace("></",">~</");
stripped.push(_tag.split("~"));
});
console.log(stripped);
document.body.removeChild(div);
Assuming you can also get the input from a "live" page then the following should do what you want:
[...document.querySelectorAll("*")]
.map(el=>el.outerHTML.match(/[^>]+>/)[0]+"</"+el.tagName.toLowerCase()+">")
The above will combine the beginning and end tags into one string like
<div class="js-ac-results overflow-y-auto hmx3 d-none"></div>
And here is the same code applied on an arbitrary string:
var mystring="<div class='all'><htmltag id='myid' class='myclass'>i_don't_want_anythin_from_here</htmltag><p>another paragraph</p></div>";
const div=document.createElement("div");
div.innerHTML=mystring;
let res=[...div.querySelectorAll("*")].map(el=>el.outerHTML.match(/[^>]+>/)[0]+"</"+el.tagName.toLowerCase()+">")
console.log(res)

javascript find div id inside string and delete it's content

I have a string with some variable html saved inside, among which a div with static id="time",
example:
myString = "<div class="class">blahblah</div><div id="time">1:44</div>"
How can I create a new identical string cutting off only the time? (1:44 in this case).
I can't look for numbers or the ":" because is not safe in my situation.
What i've tried without success is this:
var content = divContainer.innerHTML;
var jHtmlObject = jQuery(content);
var editor = jQuery("<p>").append(jHtmlObject);
var myDiv = editor.find("#time");
myDiv.html() = '';
content = editor.html();
console.log('content -> '+content);
var myString = '<div class="class">blahblah</div><div id="time">1:44</div>';
//create a dummy span
//put the html in it
//find the time
//remove it's inner html
//execute end() so the jQuery object selected returns to the span
//console log the innerHTML of the span
console.log($('<span>').html(myString).find('#time').html('').end().html());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You can achieve this using a regular expression in plain javascript like so:
myString.replace(/(<div id="time">).*(<\/div>)/, '$1$2')
If you want to extract only the 1:44 portion you can use the following:
myString.match(/(<div id="time">)(.*)(<\/div>)/)[2]

Categories