Select all elements of arrays that are inside an array - javascript

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>

Related

Need to list the items by hiding method

I have a heading to list the items
List Name
List 1
List 2
List 3
List 4
but i need to display the listed items after click the "List Name". The Listed Items are to be hidden until click the "List Name". What is the coding for it in HTML
Need Coding for HTML
it's works for me :
document.getElementById("list-name").addEventListener("click", function() {
var listItems = document.getElementById("list-items");
if (listItems.style.display === "none") {
listItems.style.display = "block";
} else {
listItems.style.display = "none";
}
});
<button id="list-name">List Name</button>
<ul id="list-items" style="display:none;">
<li>List 1</li>
<li>List 2</li>
<li>List 3</li>
<li>List 4</li>
</ul>
You can use jquery or javascript for this.
<script>
$(document).ready(function(){
$(".list-name").click(function(){
$(".list").toggle();
});
});
</script>
<ul class="list">
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
List Name
You can use this script to hide and show the list item on click.

How to individually select < li > and then use modulus to select the odd ones [duplicate]

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

Javascript NodeList.forEach() not updating all found items

I don't understand why this function only seems to update the last item in the nodelist. I want the function to add the indicator element to all li elements that have a child ul element. The function finds all the elements, but only the last one seems to get updated.
var ulElementsWithChildren = document.querySelectorAll('ul.test>li ul');
var indicator = document.createElement('span');
indicator.innerHTML = '+';
ulElementsWithChildren.forEach(function(item) {
item.parentElement.appendChild(indicator);
});
html
<ul class="test">
<li>Item 1</li>
<li>Item 2
<ul>
<li>Child Item</li>
</ul>
</li>
<li>Item 3</li>
<li>Item 4
<ul>
<li>Child Item</li>
</ul>
</li>
<li>Item 5
<ul>
<li>Child Item</li>
</ul>
</li>
</ul>
JS Fiddle
You create one <span>.
You then append it in lots of different places.
Since an element can only appear in one place, you move it each time until you get to the end of the loop.
You need to create a new span each time you go around the loop.
Move your indicator declaration inside of your foreach and it will work.
example:
ulElementsWithChildren.forEach(function(item) {
var indicator = document.createElement('span');
indicator.innerHTML = '+';
item.parentElement.appendChild(indicator);
});
You're only creating a single span element.

Javascript - Fastest way to show and hide lots of list items with in two independent UL items on the same page

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

Problem showing part of navigation menu using jquery

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');
}
});

Categories