Using plain JavaScript to list only direct child elements - javascript

I am trying to list the img elements in my slideshow using JavaScript, which is all children in a container. In that container I also have 2 divs for the navigating arrows. They also contain a child img element.
How do I only list the first set of img elements and not the nav arrows as well using plain JavaScript?
<div id='imgContain'>
<?php
$path = "./resSlide";
$all_files = scandir($path);
$how_many = count($all_files);
for ($i=2; $i<$how_many;$i++) {
$num=$i-1;
echo "<img src=\"./resSlide/$all_files[$i]\" id= \"$num\" class= \"slideImg2\"/>";
}
?>
<div id='imgPosbar'>
<div id='imgPosbarIn'></div>
</div>
<div id='imgPosLeftBut' onclick='LeftClick();'>
<img class='imgBut' src="leftarrow.png" alt='Sorry'>
</div>
<div id='imgPosRightBut' onclick='RightClick();'>
<img class='imgBut' src='rightarrow.png' alt='Sorry'>
</div>
</div>

This will select all img which is a direct child of the #imgContain
var elems = document.querySelectorAll('#imgContain > img');
for (var i = 0; i < elems.length; i++) {
// do something with each img
var el = elems[i];
}

Related

AppendChild in for loop adds every second child?

I need to wrap children element in wrap-of-parent. Before wraping add some attributes to parent and child elements. In the code described below, everything works well if the children are one below the other in a separate row, and if they are in one row, every other child is inserted into the wrap-of-parent. Why is this happening and how to fix it?
I get:
<div id="container">
<div id="parent1">
<div id="child1"></div>
<div id="child2"></div>
<div id="wrap-of-parent1">
<div id="child3"></div>
<div id="child4"></div>
</div>
</div>
I need to get:
<div id="container">
<div id="parent1">
<div id="wrap-of-parent1">
<div id="child1"></div>
<div id="child2"></div>
<div id="child3"></div>
<div id="child4"></div>
</div>
</div>
Code:
var container = document.getElementById("container");
const parentDivs = container.querySelectorAll(":scope *"); //if child elements also have child elements, to wrap in
for (let parent of parentDivs) {
// create a new div
let wrap = document.createElement('div');
wrap.id = 'wrap-of-' + parent.id;
// move the parent's children to it
let children = parent.childNodes;
for (let i = 0; i < children.length; i++) {
if (children[i].nodeType === Node.ELEMENT_NODE) {
children[i].setAttribute("data", "somedata");
wrap.append(children[i]);
}}
// and append it to the parent
parent.appendChild(wrap);
}
<div id="container">
<div id="parent1">
<div id="child1"></div><div id="child2"></div><div id="child3"></div><div id="child4"></div>
</div>
</div>
<! - If the child elements are one below the other in a separate row it works, if they are in one row it does not work ->
If you keep moving the first (index 0) entry, it will work. You need to add an offset when the wrong nodeType is encountered to skip over those ones, and if there are no child nodes then don't process the node:
var container = document.getElementById("container");
const parentDivs = container.querySelectorAll(":scope *"); //if child elements also have child elements, to wrap in
for (let parent of parentDivs) {
// create a new div
if (parent.childNodes.length > 0) {
let wrap = document.createElement('div');
wrap.id = 'wrap-of-' + parent.id;
// move the parent's children to it
let children = parent.childNodes;
const nChildren = children.length;
let offset = 0;
for (let i = 0; i < nChildren; i++) {
if (children[offset].nodeType === Node.ELEMENT_NODE) {
children[offset].setAttribute("data", "somedata");
wrap.append(children[offset]);
} else {
offset++;
}
}
// and append it to the parent
parent.appendChild(wrap);
}
}
<div id="container">
<div id="parent1">
<div id="child1"></div><div id="child2"></div><div id="child3"></div><div id="child4"></div>
</div>
</div>

Hide parent div when it contains <textarea>?

I have got a div structure that is dynamically generated by it's content. It is looking like this:
<div class="fpd-list-row fpd-add-layer" id="1609962837979"><div class="fpd-cell-0"><span></span></div><div class="fpd-cell-1">Dein Foto</div><div class="fpd-cell-2"><span class="fpd-icon-add"></span></div></div>
<div class="fpd-list-row" id="1609962838288"><div class="fpd-cell-0"><span class="fpd-current-color" style="background: #ffffff" data-colors=""></span></div><div class="fpd-cell-1"><textarea>Wanderlust</textarea></div><div class="fpd-cell-2"><span class="fpd-lock-element"><span class="fpd-icon-unlocked"></span></span></div></div>
I want to hide only the textareas and the parents element up to .fpd-list-row but keep the other div like .fpd-list-row .fpd-add-layer untouched. When I set the textarea to display none, the parent divs still exists. Is there a way hide the parent div up to ..fpd-list-row only when it contains <textarea>?
Loop through all divs, and use .find() to check for parent elements matching a certain selector.
$(document).ready(function(){
var divs = $("div");
for(var i = 0; i < divs.length; i++){
var current = divs[i];
if($(current).find("textarea").length != 0){
current.style.display='none';
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="fpd-cell-1"><textarea>My Text</textarea></div>
<div class="fpd-cell-2"><span class="fpd-lock-element">fpd-lock-element<span class="fpd-icon-unlocked">fpd-icon-unlocked</span></span></div>
<div class="fpd-cell-3"><textarea>My Text</textarea></div>
For the most concise solution (one liner), use:
$(document).ready(function(){
jQuery('textarea').parent().hide();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="fpd-cell-1"><textarea>My Text</textarea></div>
<div class="fpd-cell-2"><span class="fpd-lock-element">fpd-lock-element<span class="fpd-icon-unlocked">fpd-icon-unlocked</span></span></div>
<div class="fpd-cell-3"><textarea>My Text</textarea></div>
Check the children of the parent div:
divs = document.getElementsByTagName("DIV")
for (var i = 0; i < divs.length; i++) {
if (divs[i].childElementCount == 1 && divs[i].children[0].tagName.toLowerCase() == "textarea") {
divs[i].style.display = "none";
}
else { //for demonstration purposes
divs[i].style.backgroundColor="red"
}
}
<div class="fpd-cell-1"><textarea>My Text</textarea></div>
<div class="fpd-cell-2"><span class="fpd-lock-element">Outer Span<span class="fpd-icon-unlocked">Inner Span</span></span>
</div>
<div class="fpd-cell-3"><textarea>My Text</textarea></div>
Or, remove the parent of the textarea (idea credit of Spectric):
textareas = document.getElementsByTagName("TEXTAREA")
for (var i = 0; i < textareas.length; i++) {
textareas[i].parentNode.style.display = "none"
}
<div class="fpd-cell-1"><textarea>My Text</textarea></div>
<div class="fpd-cell-2"><span class="fpd-lock-element">Outer Span<span class="fpd-icon-unlocked">Inner Span</span></span>
</div>
<div class="fpd-cell-3"><textarea>My Text</textarea></div>
The first example hides the div only if there is one element in it, and it is the textarea, whereas the second method hides the parent of the textarea. Therefore, the first one can be used in situations where you need a textarea, and the second one just won't show any textareas regardless of the situation.
However, you could just make the dynamic content not generate the textarea and use a div:blank pseudo class in the css.
--------------- UPDATE ---------------
Update after code was updated in question.
textareas = document.getElementsByTagName("TEXTAREA")
for (var i = 0; i < textareas.length; i++) {
textareas[i].parentNode.parentNode.style.display = "none"
}
<div class="fpd-list-row fpd-add-layer" id="1609962837979">
<div class="fpd-cell-0"><span></span></div>
<div class="fpd-cell-1">Dein Foto</div>
<div class="fpd-cell-2"><span class="fpd-icon-add"></span></div>
</div>
<div class="fpd-list-row" id="1609962838288">
<div class="fpd-cell-0"><span class="fpd-current-color" style="background: white" data-colors=""></span></div>
<div class="fpd-cell-1"><textarea>Wanderlust</textarea></div>
<div class="fpd-cell-2"><span class="fpd-lock-element"><span class="fpd-icon-unlocked"></span></span>
</div>
</div>

Javascript replace parent html (remove child)

I would like loop each iframes tags I've on my page and replace them all with a new div and on the way delete also the parent content so the new div will be the only child:
<div id="parent">
<p>this is parent content</p>
<iframe src="http://www.example.com" id="iframe10"></iframe>
</div>
Result should be:
<div id="parent">
<div id="newdiv">this is new div</div>
</div>
Here is my code for looping all iframes on page, the problem I don't understand how I can access each iframe parent and delete its contents:
var i, frames;
frames = document.getElementsByTagName("iframe");
for (i = 0; i < frames.length; ++i)
{
frame_id = frames[i].id;
}
Thanks
Shai
you can write it as following:
function remove_frames() {
var i = 0;
var frames = document.getElementsByTagName("iframe");
while (frames.length > 0) {
var f = frames[0];
var p = f.parentElement;
if (p) {
while (p.children.length > 0) {
p.children[0].remove();
}
p.innerHTML = "<div id=\"newdiv" + i + "\">this is new div" + i + "</div>";
i++; //increase id index
//p.appendChild(
}
}
}
<p><input type="button" value="Execute" onclick="remove_frames()" /></p>
<div id="parent">
<p>this is parent content</p>
<iframe src="http://www.example.com" id="iframe10"></iframe>
</div>
<p style="color:#6595ee">This element does not contain any sibling IFrame and must be exist in final result!</p>
<div id="parent2">
<p>this is parent2 content...</p>
<div>another element</div>
<iframe src="http://www.example.com" id="iframe20"></iframe>
<p>another element after iframe.</p>
</div>
var i, frames;
frames = document.getElementsByTagName("iframe");
for (i = frames.length; i; --i) // the array-like object shrinks every time a frame is removed so we have to loop backwards
{
//frame_id = frames[i].id;
// get the parent element
var parent = frames[i].parentElement;
// empty it (remove all it's elements)
while(parent.firstChild)
parent.removeChild(parent.firstChild);
// add the new div
var div = /* create new div */;
parent.appendChild(div);
}
You could use the parentElement
var iframes = document.getElementsByTagName("iframe");
iframes[0].parentElement.innerHTML = `<div id="newdiv">this is new div</div>`;
<div id="parent">
<p>this is parent content</p>
<iframe src="http://www.example.com" id="iframe10"></iframe>
</div>
You can use Node.parentNode to get the parent and Node.removeChild or Element.innerHTML to delete the content.
var i, frames;
frames = document.getElementsByTagName("iframe");
for (i = frames.length-1; i >=0; i--) {
var frame = frames[i];
if (frame.parentNode) {
var parent = frame.parentNode;
while (parent.firstChild) {
parent.removeChild(parent.firstChild);
}
}
}
<div id="parent">
<p>this is parent content</p>
<iframe src="http://www.example.com" id="iframe10"></iframe>
</div>

Javascript finding parent or sibling

I have this html code:
<div class="comment" id="7" >
<div style="display:inline-block">
<img style="width:64px;height:64px" src="http://origin.black-marketplace.net/content/images/users/1.jpg"><br>
<div class="rating" style="background-position:0px -10px" title="1 stelle su 5"></div>
</div>
<div style="display:inline-block;float:right;width:172px;height:75px">
<b>Xriuk</b>
<div style="font-size:10px;color:#BEBEBE;line-height:10px">ha comprato</div>
<span class="ellips games">mkx brteshtnx</span>
</div>
<span style="font-size:12px;height:50px;width:236px;display:block" class="ellips">sdjchsdui edi0ufwuèè+eè+è+èàùiek ci0hxjomwui9vjko'asdhvfyu8rk cxi0ehfuioweju9cwej icjnweuceioncuiasn cu9wecji0wejucm vuiom fiwefdoeqr hg wgtehwhwtwghrh</span>
<a class="url" style="float:right;font-size:11px;display:none" href="7">Continua a leggere -></a>
</div>
Basically all the elements with the class ellips get ellipsed if overflow the size of the box, what I want to do is to display the if any of two span contains the string "...".
What I already did:
$(".ellips").ellipsis();
var text = document.getElementsByClassName("ellips");
if(text){
for(var i = 0; i < text.length; i++){
if(text[i].innerHTML.indexOf("...") != "-1"){
***HERE***
}
}
}
In ***HERE*** I need to put a code which returns the child element "#url" of the top parent element ".comment" (the top parent element must correspond to the current ".ellips" selected).
Any help?
Thanks!
Try
$(".ellips").ellipsis();
$('.comment .ellips').each(function () {
if (this.innerHTML.indexOf("...") != "-1") {
var $url = $(this).closest('.comment').find('.url');
//here $url refers the element with url class under the same .comment element
}
})
Try this:
$(text[i]).closest('.comment').find('a.url')

Hide DIVs with the same name using Javascript

I want to hide all divs with the name "mask"
This is my HTML:
<div id="first">
<div id="firsttest"></div>
<div class="one onehelp">
<div id="mask">
<div id="onetip"></div>
</div>
<div id="Div5"></div>
<div id="resultone"></div>
</div>
<div class="two twohelp">
<div id="mask">
<div id="twotip"></div>
</div>
<div id="Div6"></div>
<div id="resulttwo"></div>
</div>
<div class="three threehelp">
<div id="mask">
<div id="threetip"></div>
</div>
<div id="Div7"></div>
<div id="resultthree"></div>
</div>
</div>
I tried to hide "mask" by using the JS code below but it didn't work for all divs, just for the first one.
var hidemask = document.getElementById("mask");
hidemask.style.display = "none";
Is there a way to hide them all by using pure Javascript. No jQuery.
You shouldn't be using duplicate ID's in HTML, consider changing it to a class.
If you change id="mask" to class="mask", then you can do:
var hidemask = document.querySelectorAll(".mask");
for (var i = 0; i < hidemask.length; i++) {
hidemask[i].style.display = "none";
}
Or for browsers still in the stone age (IE7 and below), you can do:
var elems = document.getElementsByTagName('*'), i;
for (i in elems) {
if((' ' + elems[i].className + ' ').indexOf(' ' + 'mask' + ' ') > -1) {
elems[i].style.display = "none";
}
}
The id attribute must be unique per document. You can do what you want with a class, perhaps. So you would have multiple divs like so:
<div id="something" class="mask"></div>
Then you can do:
var divsWithMask = document.querySelectorAll(".mask");
for(var i = 0; i < divsWithMark.length; i++) {
divsWithMak[i].style.display = "none";
}
You cannot assign same ID more than once.
But you can add an attribute class to div with id "mask" E.g.:
<div id="mask-or-something-else" class="mask">...</div>
And select all elements by this class:
var hidemask = document.getElementsByClassName("mask");
for(i = 0; i < hidemask.length; i++)
hidemask[i].style.display = "none";

Categories

Resources