how does JavaScript outerHTML function behave? - javascript

I just started learning about DOM Web API and the behavior of outerHTML function seems a bit odd for me.
This is my code:
const heading = document.getElementById('heading');
heading.innerHTML = 'This is a <span>Heading</span>';
console.log(heading.innerHTML);
heading.outerHTML = '<h2>Hello World!</h2>';
console.log(heading.outerHTML);
Output:
This is a <span>Heading</span>
<h1 id="heading">This is a <span>Heading</span></h1>
For what I know DOM changes happen synchronously and therefore I expect the result for the second log to be <h2>Hello World!</h2> but the output is quite confusing.

Ok lets try to give an answer to that step by step.
First, you get the elemnet 'heading' ID and assign it to the heading variable.
Sets the innerHTML of the heading element ('This is a Head...)
Log innerHTML of the heading element.
Set outherHTML of heading element (Hello World!.. which replaces the heading element with th enew element in the DOM
Log otherHTML of the heading element. BUT , heading element has been replaced in the DOM. OutherHTML property refers to the serialized HTML of the element as it was before, and that is why u see the original tag h1 in the output.
to get what you want, you could try to define a new variable using DOM:
const heading2 = document.getElementById('heading');
console.log(heading2.outerHTML);
this will give you the output ure looking for.

Related

How to get whole element, innerHTML gets only inner part?

I have a function that gets the product and the id of this product, I need to put the entire HTML into local storage, I try it like this, but the innerHTML gets only the inner part, please tell me how to fix it?
function storagePlusQuantity(product, productId) {
const storageId = 'product' + productId;
localStorage.removeItem(storageId);
localStorage.setItem(storageId, product);
console.log(product)
}
The photo shows an example of the product of which I receive a functionenter image description here
If you have code like this:
<div id="outer-div">
~~something~~
</div>
getting the innerHTML of the div will only get the ~~something~~ part.
What you want to do is just get the div with outerHTML.
See codepen example: See Codepen Here
innerHTML returns the HTML code or text inside the selected element and outerHTML returns the elements whole code.
Let's see by examples
innerHTML Example
<div id="container">Whoa!</div>
<script>
var x = document.getElementById('container').innerHTML;
console.log(x);
</script>
Output (In the console)
Whoa!
In the above code you can see JavaScript returns the code inside the selected element
outerHTML Example
<div id="container">Whoa!</div>
<script>
var x = document.getElementById('container').outerHTML;
console.log(x);
</script>
Output (In the console)
<div id="container">Whoa!</div>
As you can see outerHTML returns all the elements code including tag, attributes and also the inner code
This Is The Difference Between InnerHTML and outerHTML.
Although outerHTML is rarely seen

Show H1 somwhere else on the page again without typing it manually (as a kind of variable)?

I am searching for a way to display an H1 somwhere else on the page again with just HTML or JavaScript.
What I mean: I do have a H1-title which is typed in manually. And I want it automatically be displayed at the bottom on the page again, without having to type it in manually again. (The thing with the bottom on the page is just an example, my project is a bit more complex).
I'm searching kind of a variable, I think.
Thanks in advance for your help.
x = document.getElementById("title").innerHTML ;
document.getElementById("reap").innerHTML = x;
<h1 id="title">Your manually written title</h1>
<h1 id="reap">Where You want to show it again</h1>
you can do this with the help of the backend or just create an id for H1 eg...
<h1 id="title">Your manually written title</h1>
<h1 id="reap">Where You want to show it again</h1>
just select with
x = document.getElementById("title").innerHTML ;
document.getElementById("reap").innerHTML = x;
Just create a variable with query selector
Consider you have a heading element. First you need to select the heading then create its clone using the cloneNode() function, it accepts a deep parameter which basically means the node and its whole subtree, including text that may be in child Text nodes, is also copied. After that we basically append the cloned element to the document body.
// select the heading
let el = document.querySelector('.heading');
// clone the element
let clone_el = el.cloneNode( true );
// append it to the body
document.body.append(clone_el);
<h1 class="heading">This is a heading</h1>

How to set an "id" to a tag using the execCommand in Javascript?

I am trying to make up a basic text editor, and I used execCommand a lot for this.
However, I want to create a heading in such a way, so that whenever user will click on the heading button(in text editor), the execCommand will make up a new heading and should add id to the newly created heading, so that, later I can create interlinks in document with just a single click.
Let say my input in for heading text editor is:
Create a heading with id
I've tried this to create a heading with id:
document.execCommand('formatBlock', false, header).id = userSelection;
HTML output for this:
<h3>Create a heading with id</h3>
As you can see, the id is not added to the HTML output, so how can I add an id to it?
I've also tried this link but didn't get much:
How to add class or id or CSS style in execCommand formatBlock 'p' tag?
Please help :)
EDIT :
Well, I got a hack to do this:
We can add the id to the newly created tag by using the Query selector so that whenever I will create a new tag using execCommand, I will find that tag by selecting the main div(in which editing is going on), and after finding that header tag, I can simply add the id to it.
Like I used this to create a header tag in div(contenteditable="true"):
document.execCommand('formatBlock', false, header);
And to add 'id' to this newly created tag, use this:
let elemMain = $("#editor " + header);
// this will find the div with id="editor" and then find the header tag inside it.
elemMain[elemMain.length - 1].id = userSelection;
//this will add an id to the last header tag inside of div.
Well, this is just a hack to get work done, but if anyone finds out a direct way to add 'id' to tag using execCommand then most welcome :)
Adding id attribute to the <body> tag here using execCommand.
Using javascript :
var idValue = "body-element";
document.execCommand(document.body.setAttribute("id", idValue));
Using jquery :
var idValue = "body-element";
document.execCommand($('body').attr('id', idValue));
Working snippet for newly created element:
var para = document.createElement("p");
var node = document.createTextNode("This is newly created paragraph ( inspect this element and see the id.)");
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
var idValue = "new_id";
document.execCommand(para.setAttribute("id", idValue));
<html>
<body>
<div id="div1">
<p id="p1">This is an old paragraph.</p>
</div>
</body>
</html>
Had the same requirement to use document.execCommand to manipulate a contenteditable element, and eventually resorted to the innerHTML option of execCommand. For example...
document.execCommand("insertHTML", false, "<div id='myId'>Hello World!</div>")
...adds the specified HTML at the insertion point, leaving the HTML element addressable by myId. The drawback to this technique is that one has to construct the HTML string. An alternative is to employ the createElement function, and then reference the outerHTML of the element node when calling execCommand...
let elemNode = document.createElement('div')
elemNode.id = 'myId'
elemNode.innerText = 'Hello World!'
document.execCommand('insertHTML', false, elemNode.outerHTML)
Note that I only tested this on Chrome.
Hope this helps anyone else finding this nook of the internet.

How do the document object model values filled by last changed values?

while studying the DOM , i wrote the below script :
console.log(document);//how this will generate the last update id value
var x = document.getElementById("old").getAttribute("id");
var y = document.getElementById("old").setAttribute("id","IDChanged");
console.log(document);
<div id="old">first</div>
both of results are :
<div id="IDChanged"><div>
after running this snippet, i found that both of the results are generating the html document with the same id which is the IDCHANGED , and what I expect is that the first console.log will generate a document with div , its id is old and the second console.log will generate the document with the div id is IDChanged.
SO, HOW to do this work?
You are logging the document object (for some reason that makes no sense), when you are really more interested in the div element. I don't know why you say that you see IDChanged logged twice when neither of your console.log() statements would produce that at all, they would both log the document object, not the div.
If you get rid of your first console.log() and change the last one to:
console.log(x,y);
you will see the results you wanted., but really, forget about document and focus on the div. I think this is what you are looking for to see the id before and after the changes.
// Get a refernece to the div
var x = document.querySelector("div");
// Report the contents of the document before doing anything:
console.log(x);
// Change the ID of the element
x.setAttribute("id","IDChanged");
// Report the contents of the document after DOM manipulation:
console.log(x);
<div id="old">first</div>

jQuery "add" Only Evaluated When "appendTo" Called

this has been driving me crazy since yesterday afternoon. I am trying to concatenate two bodies of selected HTML using jQuery's "add" method. I am obviously missing something fundamental. Here's some sample code that illustrated the problem:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
<p id="para1">This is a test.</p>
<p id="para2">This is also a test.</p>
<script>
var para1 = $("#para1").clone();
var para2 = $("#para2").clone();
var para3 = para1.add(para2);
alert("Joined para: " + para3.html());
para3.appendTo('body');
</script>
</body>
</html>
I need to do some more manipulation to "para3" before the append, but the alert above displays only the contents of "para1." However, the "appendTo appends the correct, "added" content of para1 and para2 (which subsequently appears on the page).
Any ideas what's going on here?
As per the $.add,
Create a new jQuery object with elements added to the set of matched elements.
Thus, after the add, $para3 represents a jQuery result set of two elements ~> [$para1, $para2]. Then, per $.html,
Get the HTML contents of the first element in the set of matched elements or set the HTML contents of every matched element.
So the HTML content of the first item in the jQuery result ($para1) is returned and subsequent elements (including $para2) are ignored. This behavior is consistent across jQuery "value reading" functions.
Reading $.appendTo will explain how it works differently from $.html.
A simple map and array-concat can be used to get the HTML of "all items in the result set":
$.map($para3, function (e) { return $(e).html() }).join("")
Array.prototype.map.call($para3, function (e) { return $(e).html() }).join("")
Or in this case, just:
$para1.html() + $para2.html()
Another approach would be to get the inner HTML of a parent Element, after the children have been added.

Categories

Resources