I have horizontal navigation menu with lot of list items. I want to display only five items and hide the rest. Then add left and right arrow buttons at the both ends of the navigation menu. On click it shows the next 5 list items.
<ul>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
<li>List item 5</li>
<li class="hide">List item 6</li>
<li class="hide">List item 7</li>
<li class="hide">List item 8</li>
<li class="hide">List item 9</li>
<li class="hide">List item 10</li>
</ul>
I appreciate any help.
try it:
HTML code
<ul id="list">
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
<li>List item 5</li>
<li>List item 6</li>
<li>List item 7</li>
<li>List item 8</li>
<li>List item 9</li>
<li>List item 10</li>
</ul>
<input type="button" name="prev" value=" prev " />
<input type="button" name="next" value=" next " />
JavaScript Code
var list = $('#list li');
reset();
function reset () {
step = 5; // number of list items to show (by removing hidden class)
current = 0;
for (i=0; i< list.length; i++) {
if ( i >= step ) { $(list[i]).addClass('hidden'); }
else $(list[i]).removeClass('hidden');
}
}
$('input[name="next"]').live('click', function () {
current += step;
threshold = current + step;
if (threshold > list.length-1+step) { current -= step; threshold = list.length; }
for (i=0; i < list.length; i++) {
if ( (i >= current) && (i < threshold ) ) { $(list[i]).removeClass('hidden'); }
else $(list[i]).addClass('hidden');
}
});
$('input[name="prev"]').live('click', function () {
current -= step;
threshold = current + step;
if (current < 0) { reset(); threshold = current + step;
}
for (i=0; i < list.length; i++) {
if ( (i >= current) && (i < threshold ) ) { $(list[i]).removeClass('hidden'); }
else $(list[i]).addClass('hidden');
}
});
Related
This question already has answers here:
How to select even or odd elements based on class name
(4 answers)
How to select all children of an element with javascript and change CSS property?
(5 answers)
Closed 3 years ago.
ALright so I got a homework from my teacher to first select every individual < li > and then use modulus to select only the odd ones and change their color.
And I have to say that I am completely stumped.
I have tried selecting using child nodes:
var listaOne = document.getElementById ("lista1").childNodes[0];
HTML
<ul id="lista1">
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
<li>List item 5</li>
</ul>
JS
listaOne = document.getElementById ("lista1").childNodes[0];
listaTwo = document.getElementById ("lista1").childNodes[1];
listaThree = document.getElementById ("lista1").childNodes[2];
listaFour = document.getElementById ("lista1").childNodes[3];
listaFive = document.getElementById ("lista1").childNodes[4];
I want to be able to choose an < li > individually
You can use document.querySelectorAll to get the array of li.
var lis = document.querySelectorAll('#lista1 li');
for (var i = 0; i < lis.length; i++) {
lis[i].style.color = 'blue';
}
var oddLis = document.querySelectorAll('#lista1 li:nth-child(odd)');
for (var i = 0; i < oddLis.length; i++) {
oddLis[i].style.color = 'red';
}
<ul id="lista1">
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
<li>List item 5</li>
</ul>
You can use querySelectorAll to select all li elements. Then filter the odd ones using the filter provided by Array. Then you have yourself an array of li elements.
Here, I'm using the spread operator to convert the NodeList returned by querySelectorAll into an Array.
const lis = [...document.querySelectorAll('#lista1 > li')];
lis.filter((li, i) => i % 2).forEach(li => li.style.color = 'red');
<ul id="lista1">
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
<li>List item 4</li>
<li>List item 5</li>
</ul>
Depending on how you want to do it, a forEach loop would package up the code necessary should you select every element.
var nodeList = document.getElementById('parent').childNodes;
nodeList.forEach((node, index) => {
if (index % 2 === 0) {
// code for evens here
} else {
// code for odds here
}
});
https://developer.mozilla.org/en-US/docs/Web/API/NodeList
I have two list with 3 items each one, i want to show an alert message when someone click on any item.
For all List1 items = 'List1 item clicked'
For all List2 items = 'List2 item clicked'
Since the actions is almost the same I want do this in just one code block(so if I need to add an extra list in the future, the code is easy to maintain).
This is my first attemp:
var list1 = document.getElementsByClassName('list')[0].children;
var list2 = document.getElementsByClassName('list')[1].children;
var listArray = [list1, list2];
for(i = 0; i < listArray.length; i++){
(function(){
listArray[i][i].onclick = function(){
alert("element clicked");
}
})();
}
<ul class='list'>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
<ul class='list'>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
But strangely that code assign onclick event to only the first element of first array and only the second element of second array.
So my first problem is I dont know how exactly select all child of all arrays in 'listArray' to assing the onclick event to all of them.
And my second problem would be that I dont know how to do this in javascript without event listeners: "If the clicked element is a child of list1 show "message 1", but if the clicked element is a child of list2 then show "message2". I suposse I need a if condition to do this but I dont know how exactly implement it.
Something like this?
if(elementClicked = childOfParentA){
Do this.
}else if(elementClicked = childOfParentB){
Do this.
}"
Here is a CODEPEN with cosmetics
Please avoid Jquery solutions.
The above code will work for the first item in the first list and the second item in the second list (because you have [i][i], and 0 is in [0, 1]).
Here is a possible fix:
var list1 = document.getElementsByClassName('list')[0].children;
var list2 = document.getElementsByClassName('list')[1].children;
var listArray = [list1, list2];
for(i = 0; i < listArray.length; i++){
(function(){
for (j = 0; j < listArray[i].length; j++) {
var l = i + 1;
listArray[i][j].onclick = function(){
alert("List " + l +" element clicked " + this.innerHTML);
}
}
})();
}
<ul class='list'>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
<ul class='list'>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
Note the usage of the local variable l to save the current list we work on in order to alert the relevant list.
More precise way without storing in separate arrays.
document.querySelectorAll("ul").forEach(function(ul, index){
ul.querySelectorAll('li').forEach(function(li){
li.onclick = function(){
alert("elements of UL-" + index+1 + " clicked");
}
})
})
<ul class='list'>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
<ul class='list'>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
It is normal that only the first/first and second/second ... etc respond to the click. This is because you specify it like that:
listArray[i][i]
Notice that i and i are always the same in that line...
You can do this a lot simpler if you would select all the clickable elements in one iterable with an appropriate selector:
function handler(){
alert("element clicked " + this.textContent);
}
Array.from(document.querySelectorAll('.list>li'), li => li.onclick = handler);
<ul class='list'>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
<ul class='list'>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
.className
window.addEventListener("click", function(e){
console.log (e.target.parentElement.className);
});
<ul class='list1'>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
<ul class='list2'>
<li>List item 1</li>
<li>List item 2</li>
<li>List item 3</li>
</ul>
I am working on a slider which changes the active class on click of next and previous, I want the nth child each time which has class active.
e.g. in current scenario it should return 3
HTML
<div class="my-list">
<ul>
<li> list item</li>
<li> list item</li>
<li class="active"> list item</li>
<li> list item</li>
<li> list item</li>
<li> list item</li>
<li> list item</li>
</ul>
</div>
JavaScript
function getCurrentItem() {
var listItem = $(".my-list ul li");
var items = [];
for (i = 0; i < listItem.length; i++) {
items[i] = listItem;
if($(items[i]).hasClass("active")){
console.log("here: "+i);
}
}
}
getCurrentItem();
index() can be used to the the index of the element. Note that index() will return zero-based index of the element. So, in current example, it'll return 2.
return $('.my-list li.active').index();
If the index need to be start from 1, add one to the zero-based index.
return $('.my-list li.active').index() + 1;
console.log($('.my-list li.active').index() + 1);
.active {
color: green;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="my-list">
<ul>
<li> list item 1 </li>
<li> list item 2</li>
<li class="active"> list item 3</li>
<li> list item 4</li>
<li> list item 5</li>
<li> list item 6</li>
<li> list item 7</li>
</ul>
</div>
You can do it with index():
var currentActive = $('li.active').index() + 1; // 3, in this case
function getCurrentItem() {
var listItem = $(".my-list ul li");
for (i = 0; i < listItem.length; i++) {
if ($(listItem[i]).hasClass("active")) {
console.log("here: " + i);
return i + 1; //weve found it, lets return
break;
}
}
return " empty";
}
alert(getCurrentItem()); //should alert 3 in your case
I have two bid UL elements on the same page and I would like each to show a maximum of 5 list items. Then, they would hide the others that can be seen if a user wanted to by clicking the "See more" li element which is dynamically created by the Javascript.
suppose these below are my "ul" set of elements.
<ul class="setOne">
<li>List item 1</li>
<li>List item 1</li>
<li>List item 1</li>
<li>List item 1</li>
<li>List item 1</li>
<li>List item 1</li>
<li>List item 1</li>
<li>List item 1</li>
</ul>
<ul class="setTwo">
<li>List item 1</li>
<li>List item 1</li>
<li>List item 1</li>
<li>List item 1</li>
<li>List item 1</li>
<li>List item 1</li>
<li>List item 1</li>
<li>List item 1</li>
</ul>
Here is my JS code I have been using;
$('.setOne').each(function(){
var max = 2;
if ($(this).find('li').length > max) {
$(this).find('li:gt('+max+')').hide().end().append('<li class="viewmore"><span class="showMore">View more</span><span class="showLess less">Hide</span></li>');
$('.viewmore').click( function(){
$(this).siblings(':gt('+max+')').toggle().end().find('span').toggle();
});
}else if ($(this).find('li').length === max) {
$(this).find('li:gt('+max+')').hide().end().append('<li class="nomore"><span class="End">End</span></li>');
}else if ($(this).find('li').length < max) {
$(this).find('li:gt('+max+')').hide().end().append('<li class="nomore"><span class="End">No Likes</span></li>');
}
});
I wanted to select all the two ul elements by using $('ul'), but it only works for the last ul element.
You can try this with jquery
Live Demo
http://jsfiddle.net/LhVcc/
Just use the $('ul') selector then, and make sure you don't bind $('.viewmore') twice by adding context:
$('ul').each(function(){
var max = 2;
if ($(this).children('li').length > max) {
$(this).find('li:gt('+max+')').hide().end().append('<li class="viewmore"><span class="showMore">View more</span><span class="showLess less">Hide</span></li>');
$('.viewmore', this).on('click', function(){
$(this).siblings(':gt('+max+')').toggle().end().find('span').toggle();
});
}else if ($(this).find('li').length == max) {
$(this).find('li:gt('+max+')').hide().end().append('<li class="nomore"><span class="End">End</span></li>');
}else if ($(this).find('li').length < max) {
$(this).find('li:gt('+max+')').hide().end().append('<li class="nomore"><span class="End">No Likes</span></li>');
}
});
FIDDLE
Can't think how best to do this. Thought it would be a simple show/hide but it dosn't seem as simple as that.
There is a UL with an indeterminable amount of items in it. It needs to be able to show the first 10 but no more unless a 'show more' button is clicked. When the 'show more' button is clicked it will expand the list open to show the complete list.
http://jsfiddle.net/kbUhW/
Interested to see how this is achieved.
Here is an example: http://jsfiddle.net/WqxGf/
JS:
count = 0;
$('ul li').hide();
$('ul').children().each(function(){
if(count >= 10) return;
$(this).show();
count++;
})
$('.slide').click(function(){$('ul li').show('blind');})
HTML:
<ul>
<li>Item One</li>
<li>Item Two</li>
<li>Item Three</li>
<li>Item Four</li>
<li>Item Five</li>
<li>Item Six</li>
<li>Item One</li>
<li>Item Two</li>
<li>Item Three</li>
<li>Item Four</li>
<li>Item Five</li>
<li>Item Six</li>
<li>Item One</li>
<li>Item Two</li>
<li>Item Three</li>
<li>Item Four</li>
<li>Item Five</li>
<li>Item Six</li>
<li>Item One</li>
<li>Item Two</li>
<li>Item Three</li>
<li>Item Four</li>
<li>Item Five</li>
<li>Item Six</li>
<li>Item One</li>
<li>Item Two</li>
<li>Item Three</li>
<li>Item Four</li>
<li>Item Five</li>
<li>Item Six</li>
</ul>
<a href="#" class='slide'>Slide Down</a>
All the other answers use jQuery, but your question didn't actually specify it. So here's one way to do it with plain JavaScript. Let's assume your <ul> has the ID foo, your "reveal" link has the ID reveal, and that there's a class hide with display: none. Then we have:
(function getChildNodes(id, num) { // ID of element, number to show
var obj = document.getElementById(id),
children = obj.childNodes,
elemcounter = 0;
for (var i = 0; i < children.length; i++) { // loop all children
if (children[i].nodeType === 1) { // examine elements only
elemcounter++;
if (elemcounter > num) { // element number in range to hide?
children[i].className = 'hide';
}
}
}
}('foo', 3)); // id foo, show 3
document.getElementById('reveal').onclick = function() { // handle click
var items = document.getElementsByTagName('li');
for( var i = 0; i < items.length; i++ ){ // for all list elements...
var tempclass = items[i].className;
// if the class is "hide", unhide
items[i].className = tempclass === 'hide' ? '' : tempclass;
}
}
Of course there are many other ways to do this more thoroughly -- and this one doesn't even slide. jQuery does make life a bit easier.
Here's the working example: http://jsfiddle.net/redler/jsQ47/
Here's with the slide down effect:
http://jsfiddle.net/deNzh/
That's what you're looking for, right?
you could assign the first ten < li >s a class like < li class="always_show">Stuff goes here< /li > and then make a script that hides all, shows the "always_show" class and waits for a button click to show the whole thing.
might look something like:
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(function(){
$("#listorama").hide();
});
$(function(){
$(".always_show").show();
});
$(function(){
$("#show_all").click(function(){
$("#listorama").show();
});
});
</script>
<ul id="listorama">
<li class="always_show"></li>
<li class="always_show"></li>
<li class="always_show"></li>
<li class="always_show"></li>
<li class="always_show"></li>
<li class="always_show"></li>
<li class="always_show"></li>
<li class="always_show"></li>
<li class="always_show"></li>
<li class="always_show"></li>
<li>stuff to hide first</li>
<li>stuff to hide first</li>
<li>stuff to hide first</li>
<li>stuff to hide first</li>
<li>stuff to hide first</li>
</ul>
<button id="show_all">Show All</button>
Hope this helps!
Andy
function toggleListDisplay (list, cap) {
cap = parseInt(cap);
if (cap == null || cap < 0) { return; }
var elements = $(list).children();
if ($(elements[cap]).css('display') == 'none') {
// means we need to expand the list
elements.each(function(ind, ele) {
if (ind >= cap) { $(ele).slideDown(); }
});
$('.slide').html('Slide Up');
} else {
// means we need to shorten the list
elements.each(function(ind, ele) {
if (ind >= cap) { $(ele).slideUp(); }
});
$('.slide').html('Slide Down');
}
}
$('.slide').click(function(){
toggleListDisplay('#tester', 10);
})
toggleListDisplay('#tester', 10);
JSFiddle: http://jsfiddle.net/WqxGf/7/
I don't know why the others feel like making such a simple task more complicated than it is, but here is a much easier, shorter, and simpler way of achieving this:
$("a").click(function() {
var ul = $("#myid");
ul.animate({"height": ul[0].scrollHeight}, 1000);
});
Example: http://jsfiddle.net/kbUhW/13/