I have a list of items that I want to be inside multiple columns. These columns can be arbitrary based on a series of factors so there's some other stuff going on. Unfortunately I'm getting tricked up on how to close the containing div.
Let's say I have a structure like this:
<div class="col-md-4 JS-columnGrid">
<li>one</li>
<li>two</li>
<li>three</li>
<!--</div>-->
<!--<div class="col-md-4">-->
<li>four</li>
</div>
I want to close the col-md-4 div after the third list element, and wrap the fourth list element in another div class="col-md-4">
This would create two columns.
Here's some javascript that would grab each list, throw it into an array and then my intention is that I can use that array to decide where I'm going to cut the column.
var cutoffArray = [];
$(".JS-columnGrid > li").each(function(){
cutoffArray.push(this);
console.log(cutoffArray);
});
$(cutoffArray[3]).before("</div><div class='col-md-3'>");
Unfortunately this is the output HTML after this:
<div class="col-md-4 JS-columnGrid">
<li>one</li>
<li>two</li>
<li>three</li>
<div class="col-md-3"></div>
<li>four</li>
</div>
Where am I going wrong?
// select and remove all the elements you want to re-package
var $lis = $(".col-md-4.JS-columnGrid li").remove(),
i,
divs = [];
$(".outer-container").empty();
// slice into packs of three and append each pack to container
for (i = 0; i < $lis.length; i += 3) {
$("<div class='col-md-3'></div>")
.append( $lis.slice(i, i + 3) )
.appendTo(".outer-container");
}
You can try this:
$(function(){
var cutoffArray = [],
$col = $('<div class="col-md-3"></div>');
$(".JS-columnGrid > li").each(function(){
cutoffArray.push(this);
});
$('.JS-columnGrid').after($col);
$(cutoffArray[3]).appendTo($col);
});
Working fiddle
Updated answer:
if you want to add more li's change the above to this:
var $col = $('<div class="col-md-3"></div>');
$('.JS-columnGrid').after($col);
$(".JS-columnGrid > li").each(function(index){
if(index > 2) {
$col.append($(this));
}
});
updated fiddle
despite the fact that you have <li> elements in the "wrong" place, browsers wont just ignore them and you can still manipulate them
var div = document.querySelector('.col-md-4.JS-columnGrid');
var lis = div.querySelectorAll('li');
var newDiv = document.createElement('div');
newDiv.className = 'col-md-3';
for (var i = 3; i < lis.length; i++) {
newDiv.appendChild(lis[i]);
}
div.parentElement.insertBefore(newDiv, div.nextElementSibling);
That will do what you want
You can't use "</div><div>" in .before() etc, since the argument is expected to be one or more properly formatted HTML elements (or plain text). You're working on the DOM here, not plain text, and the textual HTML representation of the argument is purely convenience.
You could instead simply move the elements:
var els = $('.JS-columnGrid > li');
var x = $( "<div class='col-md-4 JS-columnGrid'></div>" );
els.parent().after( x );
for (var i = 0; i < els.length; i ++ )
if ( i >= 3 )
x.append( els[i] );
Related
I have a ul tag with an ID and on a click of a button I want to change height and display of the div itself and same for each a tag inside that div.
I have trouble select each a tag and changing their style.
I want to use just javascript.
My mark-up
<ul id="mobile_nav" >
<a href="about.html" class="images" ><li><p>about me</p></li></a>
<li><p>work</p></li>
<li ><p>let's talk</p></li>
</ul>
My js
var but = document.getElementById('mobile_menu')
but.onclick=function() {
var ul = document.getElementById('mobile_nav')
var a = document.getElementById('mobile_nav').getElementsByTagName('a');
console.log(ul) //SEEMS TO WORK
console.log(a) //AS ABOVE
console.log(typeof(a)) // THAT S AN OBJECT
ul.style.display="block" // THAT S WORK
ul.style.height="auto";//WORKING
//TRYING TO GO THOUGHT MY OBJECT AND CHANGE HEIGHT
for (var x in a) {
a[x].style.height="42px";//IT SAID PROPERTY OF UNDEFINED
console.log('done')// IT S PRINTING THAT AS MANY AD MY A TAGS
console.log(a[x].)// NUMBER OF A TAGS IN MY DIV
}
}
As you wrote, you find all elements you are after with:
var elements = document.getElementById('mobile_nav').getElementsByTagName('a');
The result of above is NodeList. You can traverse it like that:
for (var i = 0, len = elements.length; i < len; i++){
elements[i].style.height = "25px";
}
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 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.
I have a HTML code like this:
<li>one</li>
<li>two</li>
<li>era</li>
<li>jeu</li>
<li>iuu</li>
<li>iij</li>
<li>emu</li>
<li>our</li>
I need to wrap them into 2 element equally (or like 5:6 if total is 11), like this:
<ul>
<li>one</li>
<li>two</li>
<li>era</li>
<li>jeu</li>
</ul>
<ul>
<li>iuu</li>
<li>iij</li>
<li>emu</li>
<li>our</li>
</ul>
This should work on any amount of <li>'s. Can you suggest an elegant solution with jQuery?
var $li = $('li'),
half = Math.floor($li.length/2);
$li.filter(function(i){ return i < half; }).wrapAll('<ul>');
$li.filter(function(i){ return i >= half; }).wrapAll('<ul>');
Demo
You can divide by 2 and then round down or up (depending on whether you want 4:5 or 5:4). After doing that, replace the lis with a ul containing the lis (first clone them, because otherwise the lis would have been moved around, and would not be able to be replaced because their original position is lost).
http://jsfiddle.net/TBhYX/
var li = $('li'),
amount = li.length,
left = amount / 2 | 0, // '| 0' rounds down
right = amount - left;
var leftElems = li.slice(0, left);
leftElems.replaceWith($('<ul>').append(leftElems.clone(true)));
var rightElems = li.slice(left, amount);
rightElems.replaceWith($('<ul>').append(rightElems.clone(true)));
You could also generalize these last two parts: http://jsfiddle.net/TBhYX/1/.
var li = $('li'),
amount = li.length,
left = amount / 2 | 0,
right = amount - left;
$.each([ [ 0, left],
[left, amount] ], function(i, v) {
var elems = li.slice.apply(li, v);
elems.replaceWith(
$('<ul>').append(elems.clone(true))
);
});
First you can use .each from jQuery and count them...
http://api.jquery.com/jQuery.each/
Then create the 2 ul, and then take only half of them and put them in the first ul. and then in the second...
Example code:
<div class="take_those">
<li>One</li>
<li>Ein</li>
</div>
<ul class="first">
</ul>
<ul class="second">
</ul>
See what the elements are like
$(document).ready(function() {
var total_items = 0;
total_items = $(".take_those li").length;
$(".take_those li").each(function(i) {
if(i<(total_items/2)) {
$(".first").append("<li>"+$(this).html()+"</li>");
} else {
$(".second").append("<li>"+$(this).html()+"</li>");
}
});
});
Or something like that...
Did this help you?
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.