Move all elements with class inside div - javascript

I'm brand new to js, and tried to move every elements with certain class inside a certain div.
I made some research and saw a solution that works with id, but when I tried to change it to classNames it didn't work anymore.
Is there anything more to write ?
Here is my HTML
<div class="bottom">bottom 1</div>
<div class="bottom">bottom 2</div>
<div id="top">top</div>
and my script so far
document.getElementById('top').appendChild(document.getElementsByClassName('bottom'))
console.log(document.getElementById('top').innerHTML)
I understood that appendChild didn't work because document.getElementsByClassName('bottom') is an array string instead of a node, but I have absolutely no idea what a node is, neither how to change my code for it to work.
I would really appreciate any help at all !
Thanks.

const t = document.getElementById('top');
[...document.getElementsByClassName('bottom')].map(el => t.appendChild(el));
<div class="bottom">bottom 1</div>
<div class="bottom">bottom 2</div>
<div id="top">top</div>

You can try this:
const top = document.getElementById('top');
Array.from(document.getElementsByClassName('bottom')).forEach(bottom => top.appendChild(bottom))

const top = document.getElementById('top');
var elements = document.getElementsByClassName("myclass");
[].forEach.call(elements, function(el) {
el.appendChild(bottom);
});
u can also use this syntax but its not compatible with older browsers like IE:
document.querySelectorAll('.myclass').forEach(...)

var html = '';
var elems = document.getElementsByClassName('bottom');
for (let i = 0; i < elems.length; i++) {
html += elems[i].outerHTML;
}
document.getElementById('top').innerHTML = html;

Related

How to access a <p> inside three layers of <div> using Javascript?

I'm trying to use Javascript so that a paragraph will alternate between two texts when the user presses a button on the webpage. The problem is that the <p> element I'm trying to manipulate lies within a <div> within a <div> within a <div>.
A low-level mockup of my code can be seen below:
<div id="div1">
<div id="div2">
<div id="div3">
<p>text1</p>
</div>
</div>
</div>
All solutions I've found only state what to do if the <p> is within one <div>; solutions which have not worked for me.
Here's my latest attempt:
function translate() {
var x = document.getElementById("div1").getElementById("div2").getElementById("div3").getElementsByTagName('p')[0];
if (x.innerHTML === "text1") {
x.innerHTML = "text2";
} else {
x.innerHTML = "text1";
}
}
How would I get this to work?
Edit: Nothing seems to be working so far. The <div> element all have classes, but that shouldn't affect things, right?
Edit2: My apologies for taking up your time, but I've found the issue was something else entirely. I'd been using a reserved word for my function call this whole time and had somehow never noticed that that was the issue instead. Thanks again to those who answered, and I shall look deeper at my code before posting my next question.
Why not just use
var x = document.getElementById("div3")
If accessing by the Id directly, it does not really matter what the other DIVs are.
If divs are always in that order, you can do it like this:
var x = document.querySelector('#div1 #div2 #div3 p');
You can use document.querySelectorAll to get an array of all p tags on the page.
const pTags = document.querySelectorAll('p')
pTags.forEach((p, i) => {
if(i % 2 === 0) {
p.innerHTML = 'text1'
} else {
p.innerHTML = 'text2'
}
})
Instead of Ids, you can be more specific & try the following:
var x = document.querySelector('div > div > div > p')
This will be a very strict implementation & follows the condition without the ids or classes.
Use querySelector in order to use the CSS selector #div3 p which means "pick up the paragraph element that is inside the element that has a div3 id".
Then, as you're just changing a string of text, change either the textContent of that element, or its innerText (there are subtle differences between them.)
const para = document.querySelector('#div3 p');
const button = document.querySelector('button');
button.addEventListener('click', translate);
function translate() {
if (para.textContent === 'text1') {
para.textContent = 'text2';
} else {
para.textContent = 'text1';
}
}
<div id="div1">
<div id="div2">
<div id="div3">
<p>text1</p>
</div>
</div>
</div>
<button type="button">Translate</button>

Getting infinity loop when I append div to existing divs?

I had took some program test online,from there I got some infinity loop error in appending new div to existing div.
<div id="one">
<div id="two"></div>
</div>
And this JS code is to add new div:
appendChildren();
function appendChildren() {
var allDivs = document.getElementsByTagName("div");
for (var i = 0; i < allDivs.length; i++) {
var newDiv = document.createElement("div");
allDivs[i].appendChild(newDiv);
console.log(allDivs[i]);
}
}
I want the HTML to look like this:
<div id="one">
<div id="two">
<div></div>
</div>
<div></div>
</div>
But at run time the program doesn't stop looping. Why? I couldn't guess! So can I run that appendChildren() only one time or is there another solution?
document.getElementsByTagName("div") is a live collection - it always reflects the actual data.
It means that when you append a div item, it is automatically appended to your collection. So, it never ends.
You can copy your collection using [].slice.call so that it doesn't change.
Here is the working demo snippet:
function appendChildren() {
var allDivs = [].slice.call(document.getElementsByTagName("div"));
for (var i = 0; i < allDivs.length; i++) {
var newDiv = document.createElement("div");
allDivs[i].appendChild(newDiv);
console.log(allDivs[i]);
}
}
appendChildren();
// For demonstration purposes only:
document.getElementById('html').innerText = document.getElementById('one').outerHTML;
<div id="one">
<div id="two">
</div>
</div>
<pre id="html"></pre>
The html element displays the HTML result - however, it looks bad. You may use developer tools to see the actual structure in a familiar way.

Why wont my onclick not remove any of my classes?

I have a huge problem here.
I can't get my onclick to work as I want .. So I hope someone here can help me.
#NiceToKnow
<div id="cards" class="nice"></div>
<div id="cards" class="nice"></div>
<div id="cards" class="nice"></div>
<div id="cards" class="video"></div>
I want it to display: none; every of my class="nice", so you only can see class="video", but nothing happens at all.
You are selecting the elements of the class not the class itself. So you will have to loop through the elements as javascript can only edit what is in the DOM not the CSS classes that effect your elements. So getElementsByClassName returns an array of nodes in which we must loop through and hide each one. Click runsnippet below to see this work
function changeNice(){
//ASSIGN ELEMENTS TO ARRAY
elementsofClass=document.getElementsByClassName('nice');
for(i=0; i<elementsofClass.length; i++){
//HIDE SELECTED ELEMENT
elementsofClass[i].style.display='none';
}}
#NiceToKnow
<div id="cards1" class="nice">TEST 1</div>
<div id="cards2" class="nice">TEST 2</div>
<div id="cards3" class="nice">TEST 3</div>
<div id="cards4" class="video">I don't HIDE</div>
Also don't use duplicate ID. This will cause errors later when trying to select your elements.
The getElementsByClassName will return an array, so we need to iterate through the array and hide one by one.
So it is better to declare a function and define the logic inside that. Please see the example below.
window.hideAllniceClass = function () {
var elems = document.getElementsByClassName('nice');
for (var i = 0; i != elems.length; ++i) {
elems[i].style.display = "none"; // hidden has to be a string
}
}
#NiceToKnow
<div id="cards1" class="nice">Test Content</div>
<div id="cards2" class="nice">Test Content</div>
<div id="cards3" class="nice">Test Content</div>
<div id="cards4" class="video">Test Video Content</div>
DEMO
Change your code to something like that:
var elems = document.getElementsByClassName('nice');
for(var i = 0; i < elems.length; i++) {
elems[i].style.display = 'none'
}
You have to iterate on the results returned by getElementsByClassName.
jsfiddle
You can create a loop that will loop through all the nice elements and then display none like this: https://jsfiddle.net/7vf9pz8u/
<script>
function hide(){
for(ct=0; ct < 3; ct++){
document.getElementsByClassName('nice')[ct].style.display='none'
}
}
</script>
getElementsByClassName returns array of all the match elements so you will have to provide index or loop through all of them to change their property.
Change your code to this
document.getElementsByClassName('nice')[0].style.display='none'
//For every element
var e = document.getElementsByClassName('nice');
for (i = 0; i < e.length; i++) {
e[i].style.display = "none";
}
As your divs do not have unique names they are in an array cards[].
So to access a particular div you need to reference the the array to that particular div. The quoted solution should work.

How to choose the elements from the jQuery object

I'm sorry for stupid title.
Problem: I need to select only .special element from $elements variable.
<div class="element"></div>
<div class="element special"></div>
<div class="element"></div>
Jquery:
var $elements = $('.element'),
$special = $element.find('.special'); // Not working.
UPD:
Please, don't write something like "$('.element.special')". It's wrong for my case.
You need to use .filter()
var $elements = $('.element'),
$special = $element.filter('.special');
Since the element you are targeting is a member of the $element set, you need to use .filter(), .find() is used to find descendant members of the elements in the calling set
< div class="element">bbb< /div>
< div class="element special">aaa< /div>
< div class="element">aaa< /div>
var $special = $('.element.special');
$special.html("test");
you can use
var $special = $('.element.special');

Iterating through all the <div> tags on a page

I want to go through all the elements on a page using Javascript and see if they have a property set. Is there an easy way to do this, or do I have to use a recursive solution?
You can use:
var divs = document.getElementsByTagName("div");
for(var i = 0; i < divs.length; i++){
//do something to each div like
divs[i].innerHTML = "something new...";
}
To find a property in one or more of all divs on a page:
var divs = document.getElementsByTagName("div"), i=divs.length;
while (i--) {
if (divs[i].getAttribute([yourProperty]) === 'yourValue'){
//do something
}
}
[edit october 2022] Very old answer. Today I would advise to use a css selector. For example:
const withStyle = document.querySelectorAll('[style]');
console.log(`Found ${withStyle.length} elements with style:\n${
[...withStyle]
.map(el =>`<${el.tagName}>: ${el.getAttribute('style')}`)
.join(`; `) }` );
<div style="color:#777">
<div style="color:red;background:#EEE">red</div>
<div>no color</div>
<div data-something>data-attribute</div>
<div style="color:green">green</div>
<span>Hello</span>
<h3 style="font-family:monospace">That's all folks</h3>
</div>
Using JS ES6 For ... of
for (elem of document.getElementsByTagName('div')){
elem.style.marginTop='20px'
}
You might also be able to use a selector engine such as Sizzle.
Steve

Categories

Resources