Checking a parent container for children javascript - javascript

Just wondering how you can check an element (i.e. a div container) for elements (i.e. buttons) and if they exist, remove them?
If I append a child to a div, how can I on the next look check for that child or those type of children? i.e. adding;
example = document.getElementById('div');
example.appendChild(aButton);
//loop to look for aButton / button type in example div
Cheers

Get the childNodes array, loop through and look for one matching your criteria ( input tag with type button, or possibly a button tag)
var children = example.childNodes;
for(var i = 0; i<children.length; i++){
if( children[i].tagName == "INPUT" && children[i].type=='button' ) {
example.removeChild( children[i] );
i--; //Decrement counter since we are removing an item from the list
}
}
Example: http://jsfiddle.net/BZMbk/3/

To get elements that are of a node type from a subset of the document you can simply do
document.getElementById('div').getElementsByTagName("button")
This will return any buttons under an element with the id of "div" (not a good name for an id btw)

You could use children and then loop through the children. For example if you have a div with the following set up:
<div id='div'>
<input type='button'>
<p>here</p>
</div>
You could then get the children an loop through them like this:
var example = document.getElementById("div");
var children = example.children;
alert(children.length);
for(var i = 0; i < children.length; i++)
{
alert(children[i].tagName);
}
And as to remove them it would be as simple as
example.removeChild( children[i] );

Related

select html element by its full html tag - JS

I am looking for a way to be able to select an HTML element by its tag, like:
document.querySelector("<div id='myDiv'\>hello world</div\>")
//instead of: document.querySelector("#myDiv")
However, this code returns an error. The code should return the HTML element.
Does anybody know a way to achieve this? (vanilla JS preferred)
It seems a bit odd that you wouldn't want to select element via ID. But regardless one way of selecting the element in your example would be to look for its innerHTML.
e.g
var div = document.getElementsByTagName('div');
for (var i=0;i<div.length;i++){
console.log(div[i].innerHTML)
if(div [i].innerHTML == 'hello world'){
var element = div[i].parentElement
console.log(element)
break;
}
}
You could use outerHTML to search for it, however this only works if the element has a parent element.
var els = Array.from(document.querySelector('body *')); //this selects all elements in the body
var el;
for(var i = 0; i < els.length; i++) {
if(els.outerHTML === "<div id='myDiv'\>hello world</div\>") {
el = els[i];
}
}
//Use the el variable for your element

Show/Hide Elements with multiple attributes by attribute selection (Javascript)

I try to find an easy solution (I am a totally coding beginner, just use javascript in widgets of a "out of the box" page) for the following problem:
There are multiple attributes visitor can select by click Remove/Show
attribute a (Remove/Show)
attribute b (Remove/Show)
attribute c (Remove/Show)
a.s.o.
based on visitors "selection", I would like to show or hide the list of elements:
element 1 (attribute a and b) - Remove if "a" OR "b" has been selected
element 2 (attribute a) - remove if "a" has been selected
element 3 (attribute a and c) - remove, if "a" OR "c" has been selected
a.s.o.
I am able already to hide elements based on a "selection", but in my solution every element show and hide only based on the unique ID (and so also only on the single selection).
The Javascript I found for that is:
<script type="text/javascript">
//<![CDATA[
function swap(openlink,closelink, linkid, dataid)
{
if( document.getElementById(dataid).style.display == 'none')
{
document.getElementById(dataid).style.display='inline';
document.getElementById(linkid).firstChild.nodeValue=closelink;
} else
{
document.getElementById(dataid).style.display='none';
document.getElementById(linkid).firstChild.nodeValue=openlink;
}
}
//]]>
</script>
And than I could use this HTML Code to Remove/Show the elements:
attribute a Remove
attribute b Remove
attribute c Remove
And my element will be Remove/Show by this:
<div id="showmeA" style="display:inline">Element 1</div>
<div id="showmeB" style="display:inline">Element 2</div>
<div id="showmeB" style="display:inline">Element 3</div>
Is there an easy way to add 2 ids to one "element", so that for example Element 1 could be hidden by id=showmeA AND id=showmeB?
You said the issue yourself: IDs are unique.
This is exactly why you should use something else than id, and class attribute is perfectly fine as it does not have to be unique.
Then, this means that the function will not look for your elements using getElementById() but getElementsByClassName().
Note that this function get elements, this involves that you have to loop through these elements and hide / show the ones targeted.
function swap(openlink, closelink, linkid, dataclass) {
var elements = document.getElementsByClassName(dataclass);
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if(element.style.display == 'none') {
element.style.display='inline';
document.getElementById(linkid).firstChild.nodeValue=closelink;
} else {
element.style.display='none';
document.getElementById(linkid).firstChild.nodeValue=openlink;
}
}
}
Do not forget to replace id by class attributes to your HTML, you can put in as much as you want, they simply must be separated by a space:
<div class="showmeA showmeB">Element 1</div>
<div class="showmeB">Element 2</div>
<div class="showmeC">Element 3</div>
Here is an example that you can use to better understand the function and attributes used in your solution, this solves your issue: https://jsfiddle.net/sy2mxscf/
It is also important to inform you that inline Javascript is bad, you should reconsider your code when your Javascript skill will increase.
In order to solve the issue pointed out in the comments, you have to use some kind of counter and increment it when you hide the element, decrement it when you show element of one of his class, and displaying the associate element when this counter is 0.
This is also why you need two differentiated links: the "Remove" to increment, and the "Show" to decrement.
There are several way to implement this solution:
Use an associative array in Javascript
Use a custom attribute on the element
Add and remove specific classes
I chose the last one but this may be not the best one, this is just one of the possibilities.
https://jsfiddle.net/sy2mxscf/2/
The idea is to add or remove a custom "hidemeX" class. If you click on two different "Remove" links targeting the same element, two classes will be added. If you then click on any "Show" link, the associate class will be removed. But there is still a "hidemeX" class remaining until you click on the second link, so the element is not displayed thanks to CSS.
As Delgan says, its better to use class here, and you can use those <a>'s id as their class, so when you use your function swap, you can easily trace back to decide if the elements is selected, so the div should be removed.
Below is how you can separate javascript logic and html structure.
var swap = function(e) {
var close = 'Remove', open = 'Show';
var next = this.text === close ? open : close;
// Set the clicked <a>'s text.
this.text = next;
// Get divs that will affect by this <a>
var affectTarget = this.id;
// Affected div elements
var targets = document.getElementsByClassName(affectTarget);
var i, len = targets.length;
var visible;
var watch, wLen, j;
// For each <div> that will be affect by the clicked <a>, we have to chec :
for (i = 0; i < len; ++i) {
// Get the classes that used as a list to show which <a> will have a effect on it.
watch = targets[i].classList;
wLen = watch.length;
// visibilty is default to inline, if no <a> that it watches is selected, then it'll show
visible = "inline";
for (j = 0; j < wLen; ++j) {
// If any of the <a> it watches is selected, set the visibilty to none.
if (document.getElementById(watch[j]).text === open) {
visible = "none";
break;
}
}
targets[i].style.display = visible;
}
};
// For each switcher, we register a click event for it.
var switchers = document.querySelectorAll("a.showSwitcher");
var i, len = switchers.length;
for (i = 0; i < len; ++i) {
switchers[i].addEventListener('click', swap);
}
attribute a Remove
attribute b Remove
attribute c Remove
<hr/>
<div class="swaplinkA swaplinkB" style="display:inline">Element 1</div>
<div class="swaplinkA"style="display:inline">Element 2</div>
<div class="swaplinkA swaplinkC"style="display:inline">Element 3</div>

Deleting all div children from a parent without a for loop in javascript

I have the following code in my javascript:
for (var a = 0; a < cnt; a++) {
var element = document.getElementById("button" + a).getElementsByTagName("div");
for (index = element.length - 1; index >= 0; index--) {
element[index].parentNode.removeChild(element[index]);
}
$("#button" + a).append("Some large html data");
}
I am deleting all the children from parent id "button0","button1"... and so on, which are divs.
and then appending new data to those parents.
However, this particular piece of code takes a long time to execute when the cnt is more than 200, which it usually is. How will I be able to speed it up? Is there an alternative way to delete all children divs without going through each of it?
<div class="main">
<p>hello p1</p>
<p>hello p2</p>
<span> hello world this is span </span>
</div>
$('.main p').remove(); // any number of depths
$('.main > p').remove(); // immediate children
Try this : You can use children selector to remove them, no need to iterate through children.
for (var a = 0; a < cnt; a++) {
//remove div elements inside button
$("#button"+a+" > div").remove();
$("#button" + a).append("Some large html data");
}
DEMO
IF you can have particular class to button div then you can get rid of for loop.
Lets say class="buttonDiv" is assigned to all button div, for example
<div id="button0" class="buttonDiv">
Now your jQuery script to remove child div will be like
$('div.buttonDiv').each(function(){
$(this).children("div").remove();
$(this).append("Some large html data");
});
DEMO with Class
You can use jQuery to delete them, but I don't know how much faster it will be. Under the covers it has to do pretty much the same work:
for (var a = 0; a < cnt; a++) {
$("#button" + a + " div").remove().end().append("Some large html data");
}
It would be much easier if you just add one class to all the buttons you want to remove the children of. Lets say you add the class button to all of them. Then you could just do this:
$('.button > div').remove(); // Removes all direct children divs of the .button element.
Or
$('.button div').remove(); // Removes all divs inside the `.button` element.

Count how many elements in a div

I have a div with span inside of it. Is there a way of counting how many elements in a div then give it out as a value. For Example there were 5 span in a div then it would count it and alert five. In Javascript please.
Thank you.
If you want the number of descendants, you can use
var element = document.getElementById("theElementId");
var numberOfChildren = element.getElementsByTagName('*').length
But if you want the number of immediate children, use
element.childElementCount
See browser support here: http://help.dottoro.com/ljsfamht.php
or
element.children.length
See browser support here: https://developer.mozilla.org/en-US/docs/DOM/Element.children#Browser_compatibility
You can use this function, it will avoid counting TextNodes.
You can choose to count the children of the children (i.e. recursive)
function getCount(parent, getChildrensChildren){
var relevantChildren = 0;
var children = parent.childNodes.length;
for(var i=0; i < children; i++){
if(parent.childNodes[i].nodeType != 3){
if(getChildrensChildren)
relevantChildren += getCount(parent.childNodes[i],true);
relevantChildren++;
}
}
return relevantChildren;
}
Usage:
var element = document.getElementById("someElement");
alert(getCount(element, false)); // Simply one level
alert(getCount(element, true)); // Get all child node count
Try it out here:
JS Fiddle
Without jQuery:
var element = document.getElementById("theElementId");
var numberOfChildren = element.children.length
With jQuery:
var $element = $(cssSelectocr);
var numberOfChildren = $element.children().length;
Both of this return only immediate children.
i might add just stupid and easy one answer
<div>this is div no. 1</div>
<div>this is div no. 2</div>
<div>this is div no. 3</div>
you can get how many divs in your doc with:
const divs = document.querySelectorAll('div');
console.log(divs.length) // 3
With jQuery; checks only for spans inside a div:
JSFiddle
$(function(){
var numberOfSpans = $('#myDiv').children('span').length;
alert(numberOfSpans);
})();​
With jQuery you can do like this:
var count = $('div').children().length;
alert( count );​​​
Here's a Fiddle: http://jsfiddle.net/dryYq/1/
To count all descendant elements including nested elements in plain javascript, there are several options:
The simplest is probably this:
var count = parentElement.getElementsByTagName("*").length;
If you wanted the freedom to add more logic around what you count, you can recurse through the local tree like this:
function countDescendantElements(parent) {
var node = parent.firstChild, cnt = 0;
while (node) {
if (node.nodeType === 1) {
cnt++;
cnt += countDescendantElements(node);
}
node = node.nextSibling;
}
return(cnt);
}
Working Demo: http://jsfiddle.net/jfriend00/kD73F/
If you just wanted to count direct children (not deeper levels) and only wanted to count element nodes (not text or comment nodes) and wanted wide browser support, you could do this:
function countChildElements(parent) {
var children = parent.childNodes, cnt = 0;
for (var i = 0, len = children.length; i < len; i++) {
if (children[i].nodeType === 1) {
++cnt;
}
}
return(cnt);
}
The easiest way is to select all the span inside the div which will return a nodelist with all the span inside of it...
Then you can alert the length like the example below.
alert(document.querySelectorAll("div span").length)
<div>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>

get value of child <div> of a parent <div>

<div id="parent">
<div id="child">
some-value
</div>
</div>
how do I get "some-value"?
I tried
var parent = document.getElementById("parent");
var child = parent.childNodes[0];
var childval = child.value;
document.getElementById("output").innerHTML=childval;
it outputs "undefined".
The value property only exists for form elements. If you want to get the content of any other elements, you can either use innerHTML [MDN] to get the content as HTML string, or textContent [MDN] resp. innerText [MSDN] to only get the text content without HTML tags.
childNodes [MDN] returns all child nodes, not only element nodes. That means, it also contains text nodes for example. The line break you have after <div id="parent"> is a text node as well. Hence, parent.childNodes[0] returns the text node which consists only of a line break.
If you want to get the first element node, you can either use children [MDN] (see browser compatibility), or iterate over the child nodes, testing what kind of node each of them is. 1 indicates an element node, 3 a text node:
var child = parent.firstChild;
while(child && child.nodeType !== 1) {
child = child.nextSibling;
}
There are also other ways to retrieve elements, e.g. with getElementsByTagName [MDN].
Or in your case, you can just use getElementById [MDN] to get a reference to both of the elements.
The problem is that parent <div> actuially has three children: a TextNode containing a new line after parent opening tag, the actual child <div> and yet another TextNode with newline after closing child tag. But hard-coding second item is a bad idea:
var parent = document.getElementById("parent");
console.info(parent.childNodes.length);
var child = parent.childNodes[1];
var childval = child.innerHTML;
I would suggest iterating over children and finding the actual child or using
parent.getElementsByTagName('div')
shorthand.
That's one of the reasons why people love jQuery so much:
$('#parent div').text()
var parent = document.getElementById("parent");
var child = parent.children[0];
var childVal = child.innerHTML;
document.getElementById("output").innerHTML = childVal;
DEMO : http://jsfiddle.net/bcqVC/2/
document.getElementById("output").innerHTML = document.getElementById("child").innerHTML;
This will solve your problem.
Using your way of approach try as shown below
var parent = document.getElementById("parent");
var child = parent.childNodes[0];
var childval = child.innerHTML;
document.getElementById("outPut").innerHTML=childval;
This will also solve your problem
To get all the <div> elements you can use:
var div_val=prompt("Enter a div to Get the Child Elements","");
var div_ele=document.getElementById(div_val).childNodes;
for (var i=0, max=div_ele.length; i < max; i++) {
alert(div_ele[i]); //All your Div Elements
}
try this way by this pointer.
var childs = document.getElementById('myDropdown').children; //returns a HTMLCollection
for (var indx = 0; indx < childs.length; indx++) {
// iterate over it
childs[indx].onclick = function() {
// attach event listener On Symbole Dive THIS .
this.style.color = "#ff0000";
// add to note form the symbole .
document.getElementById("Note_form").value += this.innerHTML;
}
}
<div class="dropdown">
<div id="myDropdown" class="dropdown-content">
<div>♥</div>
<div>☺</div>
<div>π</div>
<div>•</div>
<div>Σ</div>
<div>°</div>
<div>Ω</div>
<div>∞</div>
<div>×</div>
<div>÷</div>
<div>≥</div>
<div>≤</div>
<div>≠</div>
<div>®</div>
<div>©</div>
<div>¥</div>
<div>£</div>
<div>€</div>
</div>
</div>
<textarea id="Note_form" class="copy_erea" placeholder="The Content.." oninput="note_Edite(this.value);"></textarea>

Categories

Resources