HTML:
<div class="page">111111</div>
<div class="page">222222</div>
<div class="page">333333</div>
<div class="page">444444</div>
<div class="page">555555</div>
JavaScript:
var div = document.getElementsByClassName("page");
for (i = 0; i < div.length; i++) {
bt = document.createElement("button");
bt.innerHTML = "kill my followings";
div[i].appendChild(bt);
bt.onclick = function (i) {
return function () {
kill(div[i]);
}
}(i);
}
function kill(obj) {
// ...
}
See FIDDLE here.
I constructed some divs which class="page". I used JavaScript to add buttons to each div, and add onClick event to each of them.
I need to remove the divs after my current operating div. e.g, If user click button in No.3 div, No.4 and 5 should be removed.
How to realized it?
(if not necessary, the structure of original html is not allowed to change)
Thanks a lot!
This should be the simplest way to go:
function kill(obj) {
while (obj.nextSibling) {
obj.parentNode.removeChild(obj.nextSibling);
}
}
DEMO: http://jsfiddle.net/BtSKJ/3/
Related
I've written this to change the background of a div that represents hours on a daily planner. The first instance (onclick) works but the others don't. Do I need to give each .container their own id and their own function?
var changeStatus = document.querySelector("#changeStatus");
var container = document.querySelector(".container");
changeStatus.addEventListener("click", function () {
container.setAttribute("class", "filled");
}
querySelector() is designed to return a single element only. If there are multiple elements matching the .container selector then it will only return the first.
In your case you need to use querySelectorAll() to retrieve all relevant elements, then you need to loop through them to update the class.
var changeStatus = document.querySelector("#changeStatus");
var container = document.querySelectorAll(".container");
changeStatus.addEventListener("click", function () {
container.forEach(el => el.setAttribute("class", "filled"));
});
You can add click listener with loops, something like this:
changeStatus.addEventListener("click", function () {
for(var i=0; i<container.length; i++) {
container[0].setAttribute("class", "filled");
}
}
Here's an example with querySelectorAll as #pilchard answered above:
var changeStatus = document.querySelector("#changeStatus");
var containers = document.querySelectorAll(".container");
changeStatus.addEventListener("click", function () {
containers.forEach(function (container) {
container.setAttribute("class", "filled");
});
});
.filled {
color: #f00;
}
<button id="changeStatus">change status</button>
<div class="container">container 1</div>
<div class="container">container 2</div>
<div class="container">container 3</div>
I am trying to check if an element in an array has a specific class, and if it doesn't, add that class. This is happening when a segment of a pie chart created with chart.js is clicked. When a segment is clicked, a corresponding hidden div should appear, and any unhidden divs should disappear. When the segment is clicked, a class is removed from the relevant div to unhide it, and any unhidden divs should have the class added back to hide it again.
My issue is that I am not sure how to loop through the array to check if any divs don't have the class, and if they don't, to add the class back.
HTML
<div id="mod0" class="m-d-hide">Some content</div>
<div id="mod1" class="m-d-hide">Some content</div>
<div id="mod2" class="m-d-hide">Some content</div>
<div id="mod3" class="m-d-hide">Some content</div>
Javascript
var activePoints = window.modulePie1.getElementsAtEvent(event);
var modDescription = [];
for(var i=0; i<9; i++) {
modDescription[i] = document.getElementById("mod"+i);
if (activePoints.length > 0) {
var clickedSegmentIndex = activePoints[0]._index;
if (clickedSegmentIndex==[i]) {
modDescription[i].classList.remove("m-d-hide");
//Everything works until here - can't add class
if (!modDescription.classList.contains("m-d-hide")) {
modDescription.classList.add("m-d-hide");
}
}
}
}
Thanks in advance for any help.
I've managed to fix this issue by adding an else statement to the
if (clickedSegment==[i])
loop, so there was no need to loop through the array and check all the classes.
Code now looks like:
var activePoints = window.modulePie1.getElementsAtEvent(event);
var modDescription = [];
for(var i=0; i<9; i++) {
modDescription[i] = document.getElementById("mod"+i);
if (activePoints.length > 0) {
var clickedSegmentIndex = activePoints[0]._index;
if (clickedSegmentIndex==[i]) {
modDescription[i].classList.remove("m-d-hide");
} else {
if (!modDescription[i].classList.contains("m-d-hide")) {
modDescription[i].classList.add("m-d-hide");
}
}
}
}
I have this simple dropdown faq system, I only want one content div to be open at a time, so I tried to use an if / else condition, but I can only make it work halfway.
I'm checking if the content div next to the trigger div has class is-visible — if not, add that class (this works)
But if the previous content div has (contains) class is-visible, I want to remove it, so only one content div is open at a time.
I've tried so many different conditions but I think I'm overcomplexifying it, this should be simple enough right?
https://jsfiddle.net/notuhm05/1/
var faqTrigger = document.querySelectorAll('.mm-faq-trigger');
for (var i = 0; i < faqTrigger.length; i++) {
faqTrigger[i].addEventListener('click', function() {
if (!this.nextElementSibling.classList.contains('is-visible')) {
this.nextElementSibling.classList.add('is-visible');
} else if (this.previousElementSibling.classList.contains('is-visible')) {
this.nextElementSibling.classList.remove('is-visible');
} else {
console.log("doesn't work");
}
});
}
Would greatly appreciate some pointers here! :-)
Here is a working solution:
Toggle the class is-visible on the clicked node
Iterate through all triggers and remove the class is-visible if the id of the href tag does not match the clicked nodes id. NOTE: I had to add an id property to the trigger href tag like <a id="1" href="#" class="mm-faq-trigger">Trigger</a>
Source Code:
var faqTrigger = document.querySelectorAll('.mm-faq-trigger');
for (var i = 0; i < faqTrigger.length; i++) {
faqTrigger[i].addEventListener('click', function() {
this.nextElementSibling.classList.toggle('is-visible');
for (var i = 0; i < faqTrigger.length; i++) {
var trigger = faqTrigger[i];
if (trigger.nextElementSibling !== null && trigger.id !== this.id) {
trigger.nextElementSibling.classList.remove('is-visible');
}
}
});
}
I need to add an EventListener function on every div with a certain class, I tried this:
var a = document.getElementsByClassName('linkto');
for (var i = 0; i<a.length;i++) {
a[i].addEventListener('click',function(){
console.log(a);
}); }
But that gives me all the divs. My divs are generated in a foreach loop:
#foreach($faqs['My_Stay'] as $faqheading)
<div class="row lowboarder linkcolor-darkblue linkto">
{{ link_to('#div'.$faqheading->id,$faqheading->heading) }}
</div>
#endforeach
Is there a good way to determine which div was clicked on?
try like below, "this" inside your click function refer to the clicked div
for (var i = 0; i<a.length;i++) {
a[i].addEventListener('click',function(){
console.log(this.innerText);
}); }
I have a lot of click handler functions which are almost (textually and functionally) identical. I've got a menu with maybe 10 items in it; when I click on an item, the click handler simply makes one div visible, and the other 9 div's hidden. Maintaining this is difficult, and I just know there's got to be a smart and/or incomprehensible way to reduce code bloat here. Any ideas how? jQuery is Ok. The code at the moment is:
// repeat this function 10 times, once for each menu item
$(function() {
$('#menuItem0').click(function(e) {
// set 9 divs hidden, 1 visble
setItem1DivVisible(false);
// ...repeat for 2 through 9, and then
setItem0DivVisible(true);
});
});
// repeat this function 10 times, once for each div
function setItem0DivVisible(on) {
var ele = document.getElementById("Item0Div");
ele.style.display = on? "block" : "none";
}
Create 10 div with a class for marking
<div id="id1" class="Testing">....</div>
<div id="id2" class="Testing">....</div>
<div id="id3" class="Testing">....</div>
and apply the code
$('.Testing').each(function() {
$(this).click(function() {
$('.Testing').css('display', 'none');
$(this).css('display', 'block');
}
}
$(document).ready(function (){
$("div").click(function(){
// I am using background-color here, because if I use display:none; I won't
// be able to show the effect; they will all disappear
$(this).css("background-color","red");
$(this).siblings().css("background-color", "none");
});
});
Use .siblings() and it makes everything easy. Use it for your menu items with appropriate IDs. This works without any for loops or extra classes/markup in your code. And will work even if you add more divs.
Demo
Fiddle - http://jsfiddle.net/9XSJW/1/
It's hard to know without an example of the html. Assuming that there is no way to traverse from the menuItem to ItemDiv - you could use .index and .eq to match up the elements based on the order they match with the selector.
var $menuItems = $("#menuItem0, #menuItem1, #menuItem2, ...");
var $divs = $("#Item0Div, #Item1Div, #Item2Div, ...");
$menuItems.click(function(){
var idx = $(this).index();
// hide all the divs
$divs.hide()
// show the one matching the index
.eq(idx).show();
})
Try
function addClick(i) {
$('#menuItem'+i).click(function(e) {
// set nine divs hidden, 1 visble
for( var j = 0; j < 10; ++j ) {
var ele = document.getElementById("Item"+j+"Div");
ele.style.display = (i == j ? "block" : "none");
}
});
}
// One click function for all menuItem/n/ elements
$('[id^="menuItem"]').on('click', function() {
var id = this.id; // Get the ID of the clicked element
$('[id^="Item"][id$="Div"]').hide(); // Hide all Item/n/Div elements
$('#Item' + id + 'Div').show(); // Show Item/n/Div related to clicked element
});
Obviously this would be much more logical if you were using classes instead:
<elem class="menuItem" data-rel="ItemDiv-1">...</elem>
...
<elem class="ItemDiv" id="ItemDiv-1">...</elem>
$('.menuItem').on('click', function() {
var rel = $(this).data('rel'); // Get related ItemDiv ID
$('.ItemDiv').hide(); // Hide all ItemDiv elements
$('#' + rel).show(); // Show ItemDiv related to clicked element
});
Save the relevant Id's in an array - ["Item0Div", "Item1Div", ...]
Create a generic setItemDivVisible method:
function setItemDivVisible(visible, id) {
var ele = document.getElementById(id);
ele.style.display = visible ? "block" : "none";
}
And set your click handler method to be:
function(e) {
var arrayLength = myStringArray.length;
for (var i = 0; i < idsArray.length; i++) {
setItemDivVisible(idsArray[i] === this.id, idsArray[i]);
}
}
I think this will do the trick