Javascript Sections - javascript

I have a website I want to take that always has the same section with the same id with all the content I want to display. I'm not very amazing at javascript and I'm wondering how I could remove everything but a specific section.
Would the best approach be to just do a loop that goes through all the elements in the DOM and remove everything but the section with the id I want to keep? If I go that approach how do I keep it from removing all the elements inside that section?

Perhaps another way to do this more efficiently would be:
document.body.innerHTML = document.getElementById( 'saveContentId' ).innerHTML

Removing one node includes all its children, so you won't need to loop over all elements in the whole document. I see two possibilities:
get the section, remove all its siblings in the current parent, and then walk up the DOM tree until document.body, while removing all siblings.
get the section and detach it from the document. Then clear document.body and re-attach the section there
The first solution seems cleaner to me, so here some sample code:
function removeEverythingBut(el) {
while (el != document.body) {
var par = el.parentNode;
for (var i=par.childNodes.length-1; i>=0; i--)
if (par.childNodes[i] != el)
par.removeChild(par.childNodes[i]);
el = par;
}
}
// usage:
removeEverythingBut(document.getElementById("my-section"));

you can save only the element you want and delete all other elements. Also I recommend using Jquery

Related

.appendChild() an HTML element on click

I wanted to copy an entire row including its' siblings and contents on button click. When I click the button the element, it appears in the console but doesn't append to the page. This is my code:
It doesn't show any error messages. I've tried innerHTML/outerHTML or append() it doesn't work.
$(document).ready(function() {
$('#addSubFBtn').on('click', function() {
var itm = document.getElementById("trFb");
var wrapper = document.createElement('div');
var el = wrapper.appendChild(itm);
document.getElementById("tbFb").append(el);
console.log(el);
});
});
Seems like what you're trying to do is clone the item after you get it from your document. W3schools website explains how to accomplish this. Check out the link: https://www.w3schools.com/jsref/met_node_clonenode.asp
Once you clone the node, [appendchild] should work as intended
Not sure (as said without seeing related HTML) but i see flaw in your logic:
var itm = document.getElementById("trFb");
still exist on the document(so in the page) so you've to retrieve it before you want to add/move it to another place.
using .removeElement will return you removed element(or null if no element matche the selector) so correct script should be:
var itm=document.getElementById("trFb").parentNode.removeChild(document.getElementById("trFb"));
as shown here to remove element you've to use method on to parent element.
So you can add it to any other element existing.
For more specific use or element created in global JS variable (such an createElement not yet appended) you can see :document.createDocumentFragment(); as explained here https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment

Jquery cloned element is replacing himself

I have been getting some issue with cloning element, when I am cloning an element and add it to the DOM it work perfectly but when I am trying to clone a second one its replacing the first added clone, do you know where it could come from ?
var clone_count = 1;
var add_row = $('.modeloRowBlock-hidden').clone(true) // clone my div that is hidden
$('.add-modelo-block').on('click', function() { // binded button to add my div
var current_row = add_row.removeClass('modeloRowBlock-hidden hidden').addClass('modeloRowBlock' + ' ' + clone_count++) ;
$('.modeloRowBlock-hidden').before(current_row);
});
Thanks a lot in advance for your help :).
Jonathan.
EDIT : My bad I made it work, actually cloned that way for another reason, and re integrated it in the .on and it worked.
You clone your row only once.
If you're using before on a single element, it will move the elements.
If an element selected this way is inserted into a single location
elsewhere in the DOM, it will be moved before the target (not cloned):
Read more: http://api.jquery.com/before/

Out-of-the-flow DOM Manipulation

Got this from https://developers.google.com/speed/articles/javascript-dom
From what I understand, appending/removing elements causes reflow. As does changing class. But in the solution, you are appending and removing, thus, causing two times the number of reflows as the problem code. Of course, not all reflows are equal, so are class name change reflows more expensive than appending/removing reflows? What am I missing that makes the solution code more efficient than the problem code?
This pattern lets us create multiple elements and insert them into the
DOM triggering a single reflow. It uses something called a
DocumentFragment. We create a DocumentFragment outside of the DOM (so
it is out-of-the-flow). We then create and add multiple elements to
this. Finally, we move all elements in the DocumentFragment to the DOM
but trigger a single reflow.
The problem
Let's make a function that changes the className attribute for all
anchors within an element. We could do this by simply iterating
through each anchor and updating their href attributes. The problems
is, this can cause a reflow for each anchor.
function updateAllAnchors(element, anchorClass) {
var anchors = element.getElementsByTagName('a');
for (var i = 0, length = anchors.length; i < length; i ++) {
anchors[i].className = anchorClass;
}
}
The solution
To solve this problem, we can remove the element from the DOM, update
all anchors, and then insert the element back where it was. To help
achieve this, we can write a reusable function that not only removes
an element from the DOM, but also returns a function that will insert
the element back into its original position.
/**
* Remove an element and provide a function that inserts it into its original position
* #param element {Element} The element to be temporarily removed
* #return {Function} A function that inserts the element into its original position
**/
function removeToInsertLater(element) {
var parentNode = element.parentNode;
var nextSibling = element.nextSibling;
parentNode.removeChild(element);
return function() {
if (nextSibling) {
parentNode.insertBefore(element, nextSibling);
} else {
parentNode.appendChild(element);
}
};
}
Now we can use this function to update the anchors within an element
that is out-of-the-flow, and only trigger a reflow when we remove the
element and when we insert the element.
function updateAllAnchors(element, anchorClass) {
var insertFunction = removeToInsertLater(element);
var anchors = element.getElementsByTagName('a');
for (var i = 0, length = anchors.length; i < length; i ++) {
anchors[i].className = anchorClass;
}
insertFunction();
}
Suppose you want to change classes of 1 million elements.
Doing it directly would cause 1 million reflows -one for each class-.
But if you remove its parent from the DOM, change all classes, and insert it back, that's only 2 reflows -because changing elements outside the document doesn't cause reflow-.
So basically, removing and reinserting is more efficient if you have lots of elements. No need to do it if you only have a few.
So a document fragment lives 'in memory', not on the page. Manipulating that doesn't trigger any repaints/flows because the fragment is not visually represented anywhere. When you put it on the page, once you're done manipulating it, the browser knows its structure, classes, content, etc, so will only need to reflow/paint once.
In the first example, as you loop through the anchors and change the class name (presumably changing its style as well), it will immediately apply that class, find the new style, and repaint that link. Then do the same for the next one. This is slow.
By yanking it all out into memory and manipulating the DOM there, you only have one repaint/flow when you reinsert the parent wrapper element back into the page.
According to the solution:
To solve this problem, we can remove the element from the DOM, update
all anchors, and then insert the element back where it was.
So, in this case it will trigger 2 reflows (one for remove, and one for insert). So this solution applies when you want to modify more than 2 elements at a time.

JS select child of this with specific class

I am writing a GreaseMonkey script that goes through a page with various elements and each element has text and a button. It uses document.getElementsByClassName to find the parent elements, and it has a for loop to do something to each parent element. In this loop, I need to select a child node with a specific class and find its text value (innerHTML). I can't figure out how to select the child with a specific class of this element.
You'll want to grab the currently iterated element and use querySelector()
For example:
var elements = document.getElementsByClassName('class');
for (var i = 0, len = elements.length; i < len; i++) {
var child = elements[i].querySelector('.class_of_desired_element');
//do stuff with child
}
Note the dot before the class name in querySelector as it works similar to jQuery.
Try querySelectorAll(), which you can use to find elements within the current element.
var parent = document.getElementsByClassName('parentClass'),
parent[0].querySelectorAll('.childClass');
Depending on exactly what you are looking to do, you could also skip selecting the parent, if you don't explicitly need a reference to it.
document.querySelectorAll('.parentClass .childClass');
https://developer.mozilla.org/en-US/docs/Web/API/Element.querySelectorAll
You can use
var yourelement = document.getElementsByClass("");
var i = yourelement.nextSibling;
var e = i.nextSibling;
and keep getting the nextSibling of the element till you get it.
However, like #teddy said in the comments, I would suggest you use jQuery. It has a MUCH easier way to do it:
var value = $('.parentClass .childClass').html();

How to compare if two elements are the same?

I am trying to compare if the two td elements are the same within 1 table.
I have
var element = $('.table td');
$('table:odd td','.table').each(function(){
if(element.is(this)){
console.log('find')
}
)}
I want to check if the element is the same as this but my codes don't seem to work here.
Can anyone give me a hint for it? Thanks a lot
regular DOM nodes can be compared against each other, and using get(0) will get you the first DOM node from the jQuery collection :
var element = $('.table td');
$('table:odd td','.table').each(function(){
if (element.get(0) === this ){
console.log('find');
}
});
It does look like element would contain more than one element, especially as you're iterating the same selector with an added :odd on the next line, so the comparison seems a little strange, and will probably return false ?

Categories