I have a block of code like this
<span class='Wrapper'>
<span class="title"></span>
<span class="body">
<ul class="items">
<li></li>
<li></li>
</ul>
<span>
</span>
Once I access the span wrapper element using document.getElementsByTagName('span');
how do I access the inner span elements with title class and the ul elements of the span element with class body.I need to do this using plain javascript
First get an array holding all the span elements:
var yourSpans = document.getElementsByTagName('span');
Then then loop over each element in the array checking if the element has the specific class:
for(var i in yourSpans){
if (yourSpans[i].className == "title" || yourSpans[i].className == "body") {
// your code here
}
}
var spans = document.getElementsByTagName('span');
would return an array of spans. You would access the spans using spans[0], spans[1], etc.
Adding to reagan's answer, you would then need to do something like
for( var i = 0, j= spans.length; i < j; i+=1 ) {
var classes = span[i].getAttribute("class");
if( classes ) {
if( classes.indexOf("your_class_name") != -1) {
//span[i] is one of thelements you need containing 'your_class_name'.
}
}
}
I would really recommend using jQuery, it would make your life a lot easier!
$('.title').dostuff...
But if you want a JS only solution, here you go...
function editClass(matchClass,content) {
var elems = document.getElementsByTagName('*'),i;
for (i in elems) {
if((" "+elems[i].className+" ").indexOf(" "+matchClass+" ") > -1) {
elems[i].innerHTML = content;
}
}
}
Here is a fiddle (Pure-JS, no jQuery) as an example.
Related
I have something like this.
<div id="firstDiv">
This is some text
<span id="firstSpan">First span text</span>
<span id="secondSpan">Second span text</span>
</div>
I want to remove 'This is some text' and need the html elements intact.
I tried using something like
$("#firstDiv")
.clone() //clone the element
.children() //select all the children
.remove() //remove all the children
.end() //again go back to selected element
.text("");
But it didn't work.
Is there a way to get (and possibly remove, via something like .text("")) just the free text within a tag, and not the text within its child tags?
Thanks very much.
Filter out text nodes and remove them:
$('#firstDiv').contents().filter(function() {
return this.nodeType===3;
}).remove();
FIDDLE
To also filter on the text itself, you can do:
$('#firstDiv').contents().filter(function() {
return this.nodeType === 3 && this.nodeValue.trim() === 'This is some text';
}).remove();
and to get the text :
var txt = [];
$('#firstDiv').contents().filter(function() {
if ( this.nodeType === 3 ) txt.push(this.nodeValue);
return this.nodeType === 3;
}).remove();
Check out this fiddle
Suppose you have this html
<parent>
<child>i want to keep the child</child>
Some text I want to remove
<child>i want to keep the child</child>
<child>i want to keep the child</child>
</parent>
Then you can remove the parent's inner text like this:
var child = $('parent').children('child');
$('parent').html(child);
Check this fiddle for a solution to your html
var child = $('#firstDiv').children('span');
$('#firstDiv').html(child);
PS: Be aware that any event handlers bounded on that div will be lost as you delete and then recreate the elements
Why try to force jQuery to do it when it's simpler with vanilla JS:
var div = document.getElementById('firstDiv'),
i,
el;
for (i = 0; i< div.childNodes.length; i++) {
el = div.childNodes[i];
if (el.nodeType === 3) {
div.removeChild(el);
}
}
Fiddle here: http://jsfiddle.net/YPKGQ/
Check this out, not sure if it does what you want exactly... Note: i only tested it in chrome
http://jsfiddle.net/LgyJ8/
cleartext($('#firstDiv'));
function cleartext(node) {
var children = $(node).children();
if(children.length > 0) {
var newhtml = "";
children.each(function() {
cleartext($(this));
newhtml += $('<div/>').append(this).html();
});
$(node).html(newhtml);
}
}
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>
I have a tree structure as follows:
<ul id="theul275">
<li>
<div id="red"></div>
<img id="green" />
<script></script>
<div id="blue"></div>
</li>
</ul>
There are multiple UL's likes this on my page each with a different id. I am getting each UL by doing this:
var child = document.getElementById('theul' + id).getElementsByTagName('*');
the problem is, I only want to get the children of each ul which are either div's or img's.
Is there a way to get elements by multiple tag names?
I really appreciate any help because I am kind of new to JavaScript! Thanks!
Depending on what browsers you may to support, you could use the CSS selector interface.
document.getElementById('theul275').querySelectorAll('div, img');
Or use a library. There are plenty of options out there. I am familiar with two,
MooTools
$('theul275').getElements('div, img');
jQuery
$('#theul275').find('div, img');
Or get a reference to the li node, and loop through each node and check if the nodeName is DIV or IMG.
for (var i = 0, l = child.length; i < l; i++)
{
if (child[i].nodeName == 'DIV' || child[i].nodeName == 'IMG')
{
//...
}
}
You could use a iterative method for this.
var elemArray = document.getElementById('theul' + id).childNodes,
getChildByNodeName = function (elem, pattern) {
var childCollection = [],
re = new RegExp(pattern, 'g'),
getChild = function (elements) {
var childs = elements.childNodes,
i = 0;
if (childs) {
getChild(childs);
for (i = 0; i < childs.length; i += 1) {
if (childs[i].nodeName.match(pattern)) {
childCollection.push(childs[i]);
}
}
}
};
getChild(elem);
return childCollection;
}
var childs2 = getChildByNodeName(elemArray, '^(DIV|IMG)$'); // array of match elements
And just change the pattern ('^(DIV|IMG)$') to suite your needs.
If you can use jQuery, try
var child = $("#theul" + id).find("div,img");
Otherwise, see JavaScript NodeList.
I'd like to use Javascript (not jquery) to access all items in a <ul> list and remove the active class from everything except my chosen menu item.
Here is the list:
<ul id='flash-menu'>
<li id="menu1" class='something active'>item 1</li>
<li id="menu2" class='somethingelse'>item 2</li>
<li id="menu3" class='somethingelse'>item 3</li>
</ul>
This is my javascript:
function updateMenu(view_name) {
var list_items = document.getElementById('flash-menu').childNodes;
for (var i=0 ; i<list_items.length ; i++){
list_items[i].className = list_items[i].className.replace('/\bactive\b/','');
}
document.getElementById(view_name).className += " active";
}
The last line of the Javascript (adding the active class) works, but I don't think I'm accessing the list items right to remove the classes from the other items. Any suggestions? - thanks!
First off, your regex is wrong:
list_items[i].className.replace(/\bactive\b/, '');
Note: No quotes on regex'es in JavaScript. A slighty altered, working version is available on JsFiddle.
Furthermore, I get a few instances of HTMLTextElements in list_items. They're breaking the loop (Fx3.6/Win7) when trying to access the non-existing className attribute. You can avoid this by either using:
var list_items = document.getElementById('flash-menu').getElementsByTagName('li');
// Selecting _all_ descendant <li> elements
or by checking for the existence of .className before read/write within the loop body (example). The latter is probably the cleanest choice since it still only affects direct children (you may have several levels of <ul>s in each <li>).
I.e.,
function updateMenu(view_name) {
var list_items = document.getElementById('flash-menu').childNodes;
for (var i=0, j=list_items.length; i<j; i++){
var elm = list_items[i];
if (elm.className) {
elm.className = elm.className.replace(/\bactive\b/, '');
}
}
document.getElementById(view_name).className += ' active';
}
You can use javascript function getElementsByTagName:
var listitems = document.getElementsByTagName("li");
this would return an array of all the lists and can be iterated for each list element and processed as required.
You can try:
In the case that you can have more than ul, first you have to get all references to them and then process each ul:
var uls = document.getElementsByTagName("ul");
for (uli=0;uli<uls.length;uli++) {
ul = uls[uli];
if (ul.nodeName == "UL" && ul.className == "classname") {
processUL(ul);
}
}
An illustration of proccessUL can be:
function processUL(ul) {
if (!ul.childNodes || ul.childNodes.length == 0) return;
// Iterate LIs
for (var itemi=0;itemi<ul.childNodes.length;itemi++) {
var item = ul.childNodes[itemi];
if (item.nodeName == "LI") {
// Iterate things in this LI
in the case that you need it put your code here
.....
}
}
}
Of course you can also use: item.className = "classname"; if you dont need to iterate between childs of LI
document.getElementById('flash-menu').childNodes will also include white space nodes.
function updateMenu(view_name) {
var list_items = document.getElementById('flash-menu').getElementsByTagName('li'), i;
for (i=0 ; i<list_items.length ; i++){
if (list_items[i].className.indexOf('active') > -1) {
list_items[i].className = list_items[i].className.replace(/\bactive\b/,'');
}
}
document.getElementById(view_name).className += " active";
}
i agree with jensgram,and you'd better code like this:
list_items[i].className.replace(/\bactive\b/g, '');
add the regex string a 'g'
g is for Global ,using ‘/g’ can replace all the same Which Match the regex ,but if you don't use '/g',you just replace the first string .
like this :
var test= "testeetest" ;
alert(test.replace(/e/,"")) ;//result
: tsteetest but using 'g' var
test= "testeetest" ;
alert(test.replace(/e/g,"")) ;//result
: tsttst
Have a look at this here: https://developer.mozilla.org/en-US/docs/Web/API/element.classList
It helped me a lot with finding class elements!
This is my solution, maybe not the best, but for my works fine.
window.addEventListener('load', iniciaEventos, false);
function iniciaEventos(e)
{
var menu = document.querySelectorAll('nav li');
for(var i = 0; i < menu.length; i++ )
{
menu[i].addEventListener('mousedown', clickMenu);
}
}
function clickMenu()
{
var menu = document.querySelectorAll('nav li');
for(var i = 0; i < menu.length; i++)
menu[i].classList.remove('active');
this.classList.add('active');
}
i have a page around 500 div as below.
<div onclick='test()' class='test>
<ul class='innermenu'>
<li>1</li>
.....
</ul>
</div>
when the test function is called it need to hide the menu (innermenu) who calls that function.
my problems are
uniquely identify the div without using id
How to hide only the particular ul alone.
OK, first the quick fix, though it is not the best way to use JS on your page:
Change the call to this:
<div onclick="test(this);" class="test">
Then, in test, use this:
function test(el){
var uls = el.getElementsByTagName('ul');
for(var i = 0; i < uls.length; i++){
if(uls[i].className == 'innermenu'){
uls[i].style.display = "none";
break;
}
}
}
This will hide just the child ul of the div that is clicked.
A better way
OK, for the longer answer. Either attach the events after the fact using attachEvent and addEventListener or use a library like jQuery to help you out. Here is the raw solution:
Set up your HTML this way (no onclick):
<div class="test">
And then at the very end of your HTML put this:
<script type="text/javascript">
var divs = document.getElementsByTagName('div');
function test(){
var uls = this.getElementsByTagName('ul');
for(var i = 0; i < uls.length; i++){
if(uls[i].className == 'innermenu'){
uls[i].style.display = "none";
break;
}
}
};
for(var i = 0; i < divs.length; i++){
var div = divs[i];
if(div.className !== "test") continue;
if(window.addEventListener){
div.addEventListener( 'click', test, true ); //FF, Webkit, etc
} else if (window.attachEvent) {
div.attachEvent('onclick', test); // IE
} else {
div.onclick = test; // Fallback
}
}
</script>
Now, you don't have JavaScript code in your HTML, and you can get rid of the extra parameter on the test function.
There is a method
document.getElementsByClassName
but it isn't supported in all browsers.
javascript
function test(elem)
{
var childElem = elem.children[0];
childElem.style.display = 'none';
}
<div onclick='test(this)' class='test'>
<ul class='innermenu'>
<li>1</li>
<li>2</li>
</ul>
</div>
If you can use jQuery then you can do something like this
$("div.test").click(function(){
$(this).find("ul.innermenu").hide();
});
If you don't want assign ids, you can try this to hide the div which gets clicked:
<div onclick="hideMe(this);" class='test>
<script>
function hideMe(elem)
{
elem.style.display = 'none';
}
</script>
Try passing "this" as parameter:
<div onclick='test(this)' class='test>
<ul class='innermenu'>
<li>1</li>
.....
</ul>
function test(sender) {
//sender is DOM element that is clicked
alert(sender.id);
}
If getElementsByClassName is not supported by all browsers as mentioned by #rahul, you can iterate through the dom and find it yourself - provided there is only one <ul> with class name "innermenu"
var uls = document.body.getElementsByTagName("ul");
var len = uls.length;
for(var i = 0; i < len; i++)
{
var ul = uls.item(i);
if(ul.getAttribute("class") == "innermenu")
{
ul.style.display = "none";
break;
}
}