We have:
<ul>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ul>
How do I get second half of this list and move it before first <li>?
var ul = $('ul');
var lis = ul.children('li');
ul.prepend(lis.slice(Math.round(lis.length / 2)))
Example: http://jsfiddle.net/8SNGn/
This first caches the <ul> element and its <li> children using the children()[docs] method.
Then it uses the prepend()[docs] method to add the last li elements to the beginning of the ul.
You get the last ones by using the slice()[docs] method and passing it the total number of li elements divided by 2 (rounded up using Math.round() for when you have odd number).
EDIT:
I just noticed that your question title has the word "clone" in it.
The rest of the question doesn't seem to suggest it, but if you really wanted to clone the last half, you'd use the clone()[docs] method.
var ul = $('ul');
var lis = ul.find('li');
ul.prepend(lis.slice(Math.round(lis.length / 2)).clone())
Example: http://jsfiddle.net/8SNGn/1/
And if you want the rounding to go the other direction, you'd use Math.floor() instead of Math.round.
var items = $("ul li");
items.filter(function(index) {
return index > items.length / 2;
}).prependTo($("ul")[0]);
Should work.
var len = $('li').length - 1;
for(var i = 0; i < len/2; i++){
var $li = $('li').eq(len);
$('ul').prepend($li);
}
DEMO:
http://jsfiddle.net/NiceGuy4263/Ws5ZK/
jquery prepend http://api.jquery.com/prepend/
Look at jQuery's .slice() filter:
http://api.jquery.com/slice
Related
I am trying to find all top li from html .I have this mark up
<ul class="chapters">
<li>
tc_1
</li>
<li>
tc_2<ul>
<li>tc_1_1</li>
<li>tc_1_2</li>
<li>tc_1_3</li>
</ul>
</li>
<li>
tc_3
</li>
</ul>
Expected Answer: tc_1 ,tc_2,tc_3
I tried like that actually I inspect and write my code on console .
I tried like that $('li') and I get null
Then I put a class attribute "chapters" on ul then try like this
$(".chapters") again and I got null.
how to achieve this ?
You could iterate through the childNodes of the topmost li elements and filter their first textNode:
var textArray = $(".chapters > li").map(function() {
var nodes = this.childNodes, len = nodes.length;
for ( var i = 0; i < len; i++ ) {
if ( nodes[i].nodeType === 3 && $.trim(nodes[i].nodeValue).length ) {
return $.trim(nodes[i].nodeValue);
}
}
}).get();
console.log(textArray.join());
Here is a demo.
$('.chapters > li').each(function(){
alert($(this) .clone()
.children()
.remove()
.end()
.text());
});
JSFIDDLE
for more explanation you can read http://viralpatel.net/blogs/jquery-get-text-element-without-child-element/
This locates the ul, takes its immediate children (each of the lis), then removes any subchildren, .end(), to return to the lis, and .text() to get the contents.
$("ul").clone().children().children().remove().end().text()
This returns
"tc_1
tc_2
tc_3"
because of the line breaks and whitespace in between.
$(".chapters li").text()
should work.
This question already has answers here:
JQuery: Remove duplicate elements?
(8 answers)
Closed 9 years ago.
I have a code like below format. I don't want to display contents twice. For instance text 'Issue 1' is repeaded 4 times in first ul tag. I want it to be shown once using javascript/jquery. Thanks.
<h3>Year 2010</h3>
<ul>
<li>Issue 2</li>
<li>Issue 1</li>
<li>Issue 2</li>
<li>Issue 1</li>
<li>Issue 1</li>
<li>Issue 1</li>
</ul>
<h3>Year 2011</h3>
<ul>
<li>Issue 2</li>
<li>Issue 1</li>
<li>Issue 2</li>
<li>Issue 2</li>
</ul>
Try using this:
$('ul').each(function(){
var issues = [];
$(this).find('li a').each(function(){
var text = $(this).text();
if($.inArray(text, issues) > -1){
$(this).parent().remove();
}else{
issues.push(text);
}
});
});
It loops over each ul and then loops through each li a within them. It stores the text of each ul's a elements in an array (issues).
For each li a it checks whether the text has already been added to the array (i.e. it's a duplicate). If it has then it deletes the parent li, if it hasn't then it adds it to the array.
Here it is working: http://jsfiddle.net/3kr2m/1/
Here is a native JavaScript solution using slice to convert NodeList to Array and forEach to loop (using forEach directly on the NodeList seemed to have some problems), followed by a removeChild on nodes similar to what we have seen previously.
Array.prototype.slice.call(document.getElementsByTagName('ul')) // <ul>s to Array
.forEach( // loop over them
function (ul) {
var text = {}; // record what we have seen
Array.prototype.slice.call(ul.childNodes) // <li>s to Array
.forEach( // loop over these
function (li) {
if (li.nodeType !== 1 || li.tagName !== 'LI')
return; // only care about <li>s
if (text[li.textContent])
ul.removeChild(li); // seen it, remove
text[li.textContent] = 1; // mark seen
}
);
}
);
Demo fiddle
Of course, you could use for or while loops instead, which would be a little faster but requires you to keep track of more variables..
var ul, li, i, j, text;
ul = document.getElementsByTagName('ul');
for (i = 0; i < ul.length; ++i) { // loop over <ul>
text = {}; // reset seen for each <ul>
li = ul[i].childNodes;
for (j = 0; j < li.length; ++j) { // loop over <ul> children
if (li[j].nodeType === 1 && li[j].tagName === 'LI') { // only <li>
if (text[li[j].textContent]) ul[i].removeChild(li[j]); // remove seen
text[li[j].textContent] = 1; // mark seen
}
}
}
Demo of this
Here's how the HTML markup looks like
<ul>
<li>red</li>
<li>green</li>
<li>
<ul>
<li>banana</li>
<li>pineapple</li>
<li>peanut</li>
</ul>
</li>
<li>blue</li>
<li>
<ul>
<li>sun</li>
<li>mars</li>
<li>earth</li>
</ul>
</li>
<li>orange</li>
</ul>
how do I count direct children (<li>) in this list? (items containing red,green,blue,orange) ?
Try this:
$('ul > li').length;
'ul > li' selector point only first level of children i.e direct children for all ul.
or
$('ul').children().length;
If your code is string variable like
var html = '<ul><li>.....';
Then
$('ul > li', $(html)).length;
NOTE: Above code will find all li
To find only first level of li use:
$('ul:not(li > ul)').children().length;
You can also use:
$('ul:not(li > ul) > li').length
For html variable string:
$(html).children('ul > li').length;
var ul = document.querySelector('ul');
var count = 0;
for (var ch = ul.firstChild; ch; ch = ch.nextSibling)
if (ch instanceof HTMLLIElement) count++;
Use this:
$("ul > li").length
Other way:
$("ul").children().length
In JQuery documentation you can also find size() method to get the number of elements. However, it is better to use length, since it is simply faster.
The first ul element can be taken by :first selector. Another way is to set the concrete <ul> element ID, and address it with #element_id selector.
DEMO: http://jsfiddle.net/xDYn9/
I want to randomize the children elements of any <div>, <ul> on load with javascript. I am searching for the best approach to do it. Can some one help?
Suppose i have a <ul> with 5 <li> elements. On load i want the <li> elements to appear in random order.
Quicky out of my head:
Remove all the items in the <ul> with detach
Store them in an array.
Shuffle that array
Insert elements in <ul> again.
Also take a look at this question: randomize div elements
Here's how I did it (JSFiddle example here: http://jsfiddle.net/LNvqr/2/)
If you use jQuery and have HTML similar to this:
<div>
<ul id="rndList">
<li id="itemOne">one</li>
<li id="itemTwo">two</li>
<li id="itemThree">three</li>
<li id="itemFour">four</li>
<li id="itemFive">five</li>
</ul>
</div>
Then you could simply use .detach to remove and store the array of the <li> elements.
Next, with a copy of the array, use Math.random() to generate a (pseudo)random integer between 0 and one less than the size of the array. Use this as the random index to be copied from the original (ordered) list in to the new (randomly-ordered) one.
Remove the randomly-chosen element from the original array on each iteration and choose a new random one until all elements have been re-inserted:
function shuffleList() {
var origList = $("#rndList li").detach();
var newList = origList.clone();
for (var i = 0; i < newList.length; i++) {
//select a random index; the number range will decrease by 1 on each iteration
var randomIndex = randomInt(newList.length - i);
//place the randomly-chosen element into our copy and remove from the original:
newList[i] = origList.splice(randomIndex, 1);
//place the element back into into the HTML
$("#rndList").append(newList[i]);
}
}
function randomInt(maxNum) { //returns a random integer from 0 to maxNum-1
return Math.floor(Math.random() * maxNum);
}
You can achieve this with below code:
$(function () {
var parent = $("#parent-container");
var divs = parent.children();
while (divs.length) {
parent.append(divs.splice(Math.floor(Math.random() * divs.length), 1)[0]);
}
});
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?