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

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>

Related

how does JavaScript outerHTML function behave?

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.

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

How can I manipulate the child node of this element?

My Chrome Extension needs to change the size of the child node to the following.
Notice how the 'width' is set for the parent DIV...my Chrome Extension did that.
I can show the following element in the console by:
var divContainer2 = $(divContainer)[0];
console.log('Now divContainer is: ', divContainer2);
The element shown in the console by the above (just the start of it, but showing the parent/child relationship):
<div class="v7wOcf ZGnOx" style="margin-top: 80px; width: 1207px;">
<div jscontroller="Zptowf" jsaction="R6jwd:hKrBwc;c96EGd:v8OFqc;QmtCl:.CLIENT;qVp5ue:.CLIENT;AE9bOd:.CLIENT;MmB7ud:.CLIENT;zkkUY:.CLIENT;lyIVcf:.CLIENT;wuANJc:.CLIENT;voP7ud:.CLIENT" jsmodel="PuTOgd IaLzN tZ2gdc dSSknb PTCFbe ephE9e lkzLle OqPTdc nQnzVc VeaFK uArcre" data-without-stream-item-materials="" class="DReKqd" data-submission-id="1" data-view-id="46"><div jscontroller="cs6ocd" jsaction="rcuQ6b:npT2md;KDsQaf:Qp7hp;qFgNIJf-Wvd9Cc Yiql6e iTy5c editable" tabindex="0" role="textbox" aria-required="true" aria-multiline="true"
I want to apply similar styling to the child (the DIV on the second line...with the 'jscontroller').
To make things very explicit I've tried:
var divContainer3 = divContainer2[0];
var divContainer3 = divContainer2.children[0];
And others...
What am I missing? Why can't I grab the childnode of the object I can so clearly push to console and manipulate?
Thank you for any help/direction/guidance...
The issue wasn't syntax...it was dynamic content loading...and so when I was grabbing the childNodes (or trying to) the element didn't exist.
What continues to be confusing for me is that the CONSOLE will show an element called out in console.log even though it didn't exist at the time the particular line of code ran.
So I could SEE the element, and it's nodes/length, in the console but the very next line of code that simply logged the length would come up zero. Because when the length code ran the element didn't really exist.
I added a little 'wait' routine to make sure the thing is there before I try to manipulate it.

Remove and Set an Element's Text

Secrets of the JavaScript Ninja shows how to remove and set an element's text:
HTML
<div id="test">Hey!
<div id="child">delete me</div>
</div>
.
Javascript
var b = document.getElementById("test");
console.log("b before:", b);
while(b.firstChild) {
console.log("removing child:",b.firstChild);
b.removeChild(b.firstChild);
}
console.log("b's value post remove:", b);
b.appendChild(document.createTextNode("Some new text."));
var text = b.textContent || b.innerText;
console.log("text:", text);
Here's the console output:
b before: <div id=​"test">​Some new text.​</div>​
removing child: "Hey!"
removing child: <div id=​"child">​delete me​</div>​
removing child: " "
b's value post remove: <div id=​"test">​Some new text.​</div>​
text: Some new text.
How could b equal Some new text.​ when the HTML is clearly set to Hey!?
Also, why would the b's value post remove: output show up as Some new text even though it hasn't been set yet?
http://jsfiddle.net/X6fYM/
If you're wondering why the console shows you something from later when you logged it before, it's because the console is (partially) a live display of what's in the DOM, not a bunch of strings written out at a moment in time. More about that in this question and its answers.
Basically, if you log an object, the console may treat that as a living display and update it if you change the object. If you log a string, the console will correctly display that as an unchanging thing. So:
var div = document.createElement("div");
console.log("div", div);
div.appendChild(document.createTextNode("foo"));
...can (subject to various conditions) show that the div contains foo, because the console updated the display when we changed it. (Live Example, open the console to see)
If you single-step through the code in a debugger, you can watch the console show one thing, then change it as we change its contents.
Perhaps a little more explanation is in order.
Remember that each item in markup has some sort of element-context. Even text is a Node.
So, there are three Nodes inside of #test at the beginning of your script:
Hey!
<div id="child">delete me</div>
[a blank text node]
This is why you see the output as the while statement works its way through #test's child nodes, removing each one in turn.
Having run your jsFiddle in Firefox, I'm not sure why you're seeing the output you posted:
b's value post remove: <div id=​"test">​Some new text.​</div>​
as it does not display that for me. It only displays that there is a div with the ID of test.
Also, in the beginning, you're creating a pointer to the test node, which is why, when you perform this call:
b.appendChild(document.createTextNode("Some new text."));
b suddenly has content... it never went away, you didn't dispose of the pointer to that object, and so when you test its contents, it displays the new text node that you just added to it.

Counting classes on another page and displaying them

To save me a lot of work editing a number in when adding a document to a site I decided to use javascript to count the number of elements with a class doc .
I am two main problems:
There is trouble displaying the variable. I initially thought this was because I hadn't added function, however when I tried adding this the variable was still not displayed.
The elements with the class I want to count are on another page and I have no idea how to link to it. For this I have tried var x = $('URL: /*pageURL*/ .doc').length; which hasn't worked.
Essentially I want the total elements with said class name and this to be displayed in a span element.
Currently I have something similar to what's displayed below:
<script>
var Items = $('.doc').length;
document.getElementById("display").innerHTML=Items;
</script>
<span id="display"></span>
Found an example of something similar here where the total numbers of articles are displayed.
Edit:
#ian
This code will be added to the homepage, domain.net/home.html. I want to link to the page containing this documents, domain.net/documents.html. I've seen this done somewhere before and if I remember correctly they used url:domainname.com/count somewhere in their code. Hope this helps.
Here is a jQuery call to retrieve the url "./" (this page) and parse the resulting data for all elements with class "lsep" "$('.lsep', data)". You should get back a number greater than 5 or so if you run this from within your debug console of your browser.
$.get("./", function(data, textStatus, jqXHR)
{
console.log("Instances of class: " + $('.lsep', data).length)
});
One important thing to remember is that you will run into issues if the URL your are trying to call is not in the same origin.
Here's an updated snippet of code to do what you're describing:
$(document).ready(
function ()
{
//var url = "/document.html" //this is what you'd have for url
//var container = $("#display"); //this is what you'd have for container
//var className = '.data'; //this is what you'd have for className
var url = "./"; //the document you want to parse
var container = $("#question-header"); //the container to update
var className = '.lsep'; //the class to search for
$.get(url, function (data, textStatus, jqXHR) {
$(container).html($(className, data).length);
});
}
);
If you run the above code from your browser's debug console it will replace the question header text of "Counting classes on another page and displaying them" with the count of instances the class name ".lsep" is used.
First, you have to wait until the document is ready before manipulating DOM elements, unless your code is placed after the definition of the elements you manipulate, wich is not the case in your example. You can pass a function to the $ and it will run it only when the document is ready.
$(function () {
//html() allows to set the innerHTML property of an element
$('#display').html($('.doc').length);
});
Now, if your elements belongs to another document, that obviously won't work. However, if you have used window.open to open another window wich holds the document that contains the .doc elements, you could put the above script in that page, and rely on window.opener to reference the span in the parent's window.
$('#display', opener.document.body).html($('.doc').length);
Another alternative would be to use ajax to access the content of the other page. Here, data will contain the HTML of the your_other_page.html document, wich you can then manipulate like a DOM structure using jQuery.
$.get('your_other_page.html', function(data) {
$('#display').html($('.doc', data).length);
});

Categories

Resources