I have an image which is an arrow for sorting the list. When i click it has to change to other image which is downward of the same image. But it doesn't stay that way after clicking. . I need if else statement here because i will need the reverse list with new image after first click.
It's not all of my Javascript. I tried to copy the parts which are related to my question. I hope it is an understandable example.
const sorting = document.querySelector('#sortingIcon');
let arr = [];
sorting.addEventListener('click', (event) => {
if (sorting.src = "images/Group74.png") {
sorting.src = "images/Group90.png";
const items = document.getElementsByTagName('li');
for (let i = 0; i < items.length; i++) {
console.log(items[i])
arr.push(items[i].firstChild.value);
}
arr.sort();
for (let i = 0; i < items.length; i++) {
items[i].firstChild.value = arr[i];
}
}
})
<div class="box">
<div id="yellow"></div>
<h1>To-do list</h1>
<img id="sortingIcon" src="images/Group74.png" alt="sorting">
<div id="inputBox">
<input class="input" type="text" name="input1">
<img class="clear" src="images/Group77.png" alt="">
</div>
<button id="plus_button">
<div id="flex">
<div id="plus">+</div>
<div id="enter">Добавить </div>
</div>
</button>
</div>
How can i make it stay that way?
Related
I am cloning a div using jQuery and find that events on cloned elements do not work although they work on the original elements. How can I go about this? Note how the answer in the question states that...
"This is how jQuery's clone() method is able to copy a node with its
event listeners, for example"
let add = document.getElementsByClassName("add"),
rem = document.getElementsByClassName("rem"),
container = document.getElementsByClassName('container')[0];
for (let i = 0; i < add.length; i++) {
add[i].addEventListener("click", () => {
$(".cloneable").clone(true, true).appendTo(".container");
});
}
for (let i = 0; i < rem.length; i++) {
rem[i].addEventListener("click", () => {
if (container.childElementCount > 1) {
$(".cloneable:last").remove();
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="cloneable">
<div>
<a class="btn btn-primary add" role="button">Add cell</a>
<a class="btn btn-primary rem" role="button">Remove cell</a>
</div>
<iframe src="index.php"></iframe>
</div>
</div>
ETA: This code clones all elements named ".cloneable", so on second click it creates TWO clones, and so on. You should clone with $('.cloneable:first') or similar.
The issue seems to arise from you binding javascript native events. Using jQuery Events solves your problem.
let add = document.getElementsByClassName("add"),
rem = document.getElementsByClassName("rem"),
container = document.getElementsByClassName('container')[0];
for (let i = 0; i < add.length; i++) {
$(add[i]).on("click", () => {
$(".cloneable:first").clone(true, true).appendTo(".container");
});
}
for (let i = 0; i < rem.length; i++) {
$(rem[i]).on("click", () => {
if (container.childElementCount > 1) {
$(".cloneable:last").remove();
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="cloneable">
<div>
<a class="btn btn-primary add" role="button">Add cell</a>
<a class="btn btn-primary rem" role="button">Remove cell</a>
</div>
<iframe src="index.php"></iframe>
</div>
</div>
I want to apply function to multiple div pairs in multiple wrappers. Divs should be selected in parallel by order from 2 different classes.
The best what I can think of is to make an array with n pairs of divs from n number of modules, but I don't know if the concept itself and syntax is right.
Now, I want to apply function to first/second/third/... object-1 and descript-1 divs inside only one module at the same time. And the same goes for next module, instead function should be applied to object-2 - descript-2 pair.
Updated code:
Now I have three different functions, one for next-prev buttons, one for thumbnail control and last one for showing object/description class divs and highlighting thumbs.
I've made nested functions attempt but it doesn't work. Should I declare vars, and get content before making 3 separate modules.forEach functions?
<script>
// nodes Array
let modules = Array.prototype.slice.call(document.querySelectorAll(".module"));
// Loop over the modules without index.
modules.forEach(function(module){
var divIndex = 1;
showDivs(divIndex);
// Objects, descr, thumbs
let objects = module.querySelectorAll(".object");
let descripts = module.querySelectorAll(".descript");
let thumbs = module.querySelectorAll(".thumb");
// next-prev buttons
function plusDivs(n) {
showDivs(divIndex += n);
}
// thumb control
function currentDiv(n) {
showDivs(divIndex = n);
}
// div display
function showDivs(n) {
if (n > objects.length) {divIndex = 1}
if (n < 1) {divIndex = objects.length}
// hide content, shade thumb
objects.style.display = "none";
descripts.style.display = "none";
thumbs.className = thumbs.className.replace(" active", "");
// show only selected object-descr pair and highlight thumb
for(var i = 0; i < objects.length; i++) {
objects[divIndex-1].style.display = "block";
descripts[divIndex-1].style.display = "block";
thumbs[divIndex-1].className += " active";
}
}
});
</script>
<div class="module">
<div class="content">LOREM IPSUM 1</div>
<div class="wrapper">
<div class="content">LOREM IPSUM 1</div>
<div class="object">o1</div>
<div class="object">o2</div>
<div class="object">o3</div>
<div class="descript">d1</div>
<div class="descript">d2</div>
<div class="descript">d3</div>
<div class="thumb" onclick="currentDiv(1)">t1</div>
<div class="thumb" onclick="currentDiv(2)">t2</div>
<div class="thumb" onclick="currentDiv(3)">t3</div>
<a class="prev" onclick="plusDivs(-1)">X</a>
<a class="next" onclick="plusDivs(1)">X</a>
</div>
</div>
<div class="module">
<div class="content">LOREM IPSUM 2</div>
<div class="wrapper">
<div class="content">LOREM IPSUM 2</div>
<div class="object">o4</div>
<div class="object">o5</div>
<div class="object">o6</div>
<div class="descript">d4</div>
<div class="descript">d5</div>
<div class="descript">d6</div>
<div class="thumb" onclick="currentDiv(1)">t4</div>
<div class="thumb" onclick="currentDiv(2)">t5</div>
<div class="thumb" onclick="currentDiv(3)">t6</div>
<a class="prev" onclick="plusDivs(-1)">X</a>
<a class="next" onclick="plusDivs(1)">X</a>
</div>
</div>
Is this what you are looking for? See comments inline. Also, don't use .getElementsByClassName().
// Convert the node list into an Array for the best browser compatibility with Array.forEach()
let modules = Array.prototype.slice.call(document.querySelectorAll("div[class^='module-']"));
// Loop over the modules.
// The Array.forEach() method is much simpler than manual loops because you don't have
// to maintain the loop indexer.
modules.forEach(function(module){
// Get the objects and descriptions (no arrays needed here because we're just
// going to need to use indexes against the node lists.
let objects = module.querySelectorAll("div[class='object']");
let descriptions = module.querySelectorAll("div[class='descript']");
// Clear out the objects and descriptions in the module.
// Start by getting all the objects and descriptions into an array.
let objectsDescriptions = Array.prototype.slice.call(
module.querySelectorAll("[class='object'], [class='descript']"));
// Then remove each item in the array from the document
objectsDescriptions.forEach(function(element){ element.parentNode.removeChild(element); });
// Loop the amount of times that matches the number of items in one of the arrays.
// Here, a regular counting loop makes the most sense because it's all about looping
// the correct number of times, not looping over DOM elements.
for(var i = 0; i < objects.length; i++){
// Repopulate the module with the current child elements, but in the new sequence
module.insertBefore(objects[i], module.querySelector(".thumb"));
module.insertBefore(descriptions[i], module.querySelector(".thumb"));
}
// Set up all the clickable elements to have click event handlers
module.addEventListener("click", function(evt){
// Check to see if it was a thumb or a prev/next that was clicked
if(evt.target.classList.contains("thumb")){
// Show the div that has the same index as the thumbnail that was clicked
let thumbs = Array.prototype.slice.call(evt.target.parentNode.querySelectorAll(".thumb"));
showDiv(evt.target.parentNode, thumbs.indexOf(evt.target));
} else if(evt.target.classList.contains("prev") || evt.target.classList.contains("next")){
// Show the div according to the data-offset attribute of the clicked element
showDiv(evt.target.parentNode, +evt.target.dataset.offset, true);
}
});
});
// ****************************************************************
// CODE TO SHOW DIVS
// ****************************************************************
let currentIndex = 0;
// div display
function showDiv(parent, index, nav) {
// Hide all the objects and descriptions
let items = parent.querySelectorAll(".object, .descript");
Array.prototype.slice.call(items).forEach(function(el){
el.classList.add("hidden");
});
if(nav){
currentIndex += index; // Adjust for the offset
if(currentIndex < 0){
currentIndex = 0;
} else if(currentIndex > (items.length / 2) - 1){
currentIndex = (items.length / 2) - 1;
}
// Show just the ones that are supposed to be shown
parent.querySelectorAll(".object")[currentIndex].classList.remove("hidden");
parent.querySelectorAll(".descript")[currentIndex].classList.remove("hidden");
} else {
// Show just the ones that are supposed to be shown
parent.querySelectorAll(".object")[index].classList.remove("hidden");
parent.querySelectorAll(".descript")[index].classList.remove("hidden");
}
}
.hidden { display:none; }
.thumb, .prev, .next { cursor:pointer; color:blue; }
<div class="module-1">
<div class="object">o1</div>
<div class="object">o2</div>
<div class="object">o3</div>
<div class="descript">d1</div>
<div class="descript">d2</div>
<div class="descript">d3</div>
<div class="thumb">t1</div>
<div class="thumb">t2</div>
<div class="thumb">t3</div>
<span class="prev" data-offset="-1"><</span>
<span class="next" data-offset="1">></span>
</div>
<div class="module-2">
<div class="object">o4</div>
<div class="object">o5</div>
<div class="object">o6</div>
<div class="descript">d4</div>
<div class="descript">d5</div>
<div class="descript">d6</div>
<div class="thumb">t4</div>
<div class="thumb">t5</div>
<div class="thumb">t6</div>
<span class="prev" data-offset="-1"><</span>
<span class="next" data-offset="1">></span>
</div>
This code is supposed to be looping and adding multiple divs, but it isn't working. When I click it, only one div appears. If I click again, nothing happens.
<body>
<div class="start" >
<div id = "coba">
</div>
<div id = "cobi">
</div>
</div>
<script>
var divs = document.getElementById("coba").addEventListener("click", function () {
for (var i = 1; i < 100; i++) {
var di = document.createElement('div');
document.getElementById('coba').appendChild(di);
}
});
</script>
</body>
Thanks for your help
Your code does not work because you did not do anything with the variable "i" in the for statement. If you look at the fiddles of user2181397 & meghan Armes you will see how they added a line in the script to put it to work.
I tested the below in my IDE and it works just fine:
<body>
<div class="start" style="margin-top:50px; color:black;">
<div id = "coba">
<p>Click Me</p>
</div>
<div id = "cobi">
</div>
</div>
<script>
var divs = document.getElementById("coba").addEventListener("click", function() {
for (var i = 1; i < 100; i++) {
var di = document.createElement('div');
di.innerHTML=i;
document.getElementById('coba').appendChild(di);
}
});
</script>
</body>
I'm building a "piano-like" music app, where users can click on a certain div (boxes) and it plays a note.
I know I could do this by grabbing all the Ids of both the boxes and the audio file, but I think there's an easier and more flexible way.
I tried looping through the boxes and grabbing the Ids, but I can't seem to get the names of audio files. I had an idea that I could get the Ids and see if they match the value of the name attribute for the audio and play it that way, but I'm stuck.
Here's the sample code:
<div id="main">
<div id="box1" class="box"></div>
<div id="box2" class="box"></div>
<div id="box3" class="box"></div>
<div id="box4" class="box"></div>
<div id="box5" class="box"></div>
<div id="box6" class="box"></div>
<div id="box7" class="box"></div>
</div>
<audio id="box1_sound" name="notes">
<source src="audio/d_note.mp3" type="audio/mp3"></source>
</audio>
JavaScript:
var box1 = document.getElementById('box1');
var box1Note = document.getElementById('box1_sound');
box1.addEventListener('mousedown', function(){
box1Note.currentTime = 0;
box1Note.play();
});
var boxName = document.getElementsByClassName('box');
var notes = document.getElementsByName('notes');
for (var j = 0; j < notes.length; j++) {
var notesVal = notes[j].name;
console.log(notesVal);
}
for (var i = 0; i < boxName.length; i++) {
boxName[i].addEventListener('mousedown', function(){
var boxId = this.id;
console.log(boxId);
});
}
Any help would be awesome, thanks guys!
You can try this work around:
Loop through each box. for each loop, grab the id of the box and concatenate to form the id name of the audio element.
example:
var boxes = document.querySelectorAll('.box');
for ( var i=0 ; i < boxes.length; i++) {
boxes[i].addEventListener('click',function(){
sound = document.getElementById(this.id+'_sound');
sound.currentTime = 0;
sound.play();
});
}
FIDDLE DEMO
What about putting an onclick handler on each div? Something like this:
<span onclick="playMusic('a.mp3')" class="white"> </span>
<span onclick="playMusic('b.mp3')" class="black"> </span>
<span onclick="playMusic('c.mp3')" class="white"> </span>
<span onclick="playMusic('d.mp3')" class="black"> </span>
<span onclick="playMusic('e.mp3')" class="white"> </span>
<span onclick="playMusic('d.mp3')" class="black"> </span>
Then just have some javascript that plays the specified audio file in that function? Here's a jsfiddle that shows my example in action.
I want to hide all divs with the name "mask"
This is my HTML:
<div id="first">
<div id="firsttest"></div>
<div class="one onehelp">
<div id="mask">
<div id="onetip"></div>
</div>
<div id="Div5"></div>
<div id="resultone"></div>
</div>
<div class="two twohelp">
<div id="mask">
<div id="twotip"></div>
</div>
<div id="Div6"></div>
<div id="resulttwo"></div>
</div>
<div class="three threehelp">
<div id="mask">
<div id="threetip"></div>
</div>
<div id="Div7"></div>
<div id="resultthree"></div>
</div>
</div>
I tried to hide "mask" by using the JS code below but it didn't work for all divs, just for the first one.
var hidemask = document.getElementById("mask");
hidemask.style.display = "none";
Is there a way to hide them all by using pure Javascript. No jQuery.
You shouldn't be using duplicate ID's in HTML, consider changing it to a class.
If you change id="mask" to class="mask", then you can do:
var hidemask = document.querySelectorAll(".mask");
for (var i = 0; i < hidemask.length; i++) {
hidemask[i].style.display = "none";
}
Or for browsers still in the stone age (IE7 and below), you can do:
var elems = document.getElementsByTagName('*'), i;
for (i in elems) {
if((' ' + elems[i].className + ' ').indexOf(' ' + 'mask' + ' ') > -1) {
elems[i].style.display = "none";
}
}
The id attribute must be unique per document. You can do what you want with a class, perhaps. So you would have multiple divs like so:
<div id="something" class="mask"></div>
Then you can do:
var divsWithMask = document.querySelectorAll(".mask");
for(var i = 0; i < divsWithMark.length; i++) {
divsWithMak[i].style.display = "none";
}
You cannot assign same ID more than once.
But you can add an attribute class to div with id "mask" E.g.:
<div id="mask-or-something-else" class="mask">...</div>
And select all elements by this class:
var hidemask = document.getElementsByClassName("mask");
for(i = 0; i < hidemask.length; i++)
hidemask[i].style.display = "none";