So right now I have this code:
var s = 0;
$('.inner').click(function () {
$(this).addClass("selected");
$(this).removeClass("inner");
s++;
$('#sslots').replaceWith(s);
};
But for some reason, the javascript wont update, it will start out as blank (not zero) and then change to 1 once I click one of the div's with "inner" as the class but then won't do anything after that..
The problem is after your first click the element sslots does not exists because you are replacing it with the number, instead you have to change the content of sslots - you can use .text() for that
var s = 0;
$('.inner').one('click', function() {
$(this).addClass("selected");
$(this).removeClass("inner");
s++;
$('#sslots').text(s);
});
.inner {
color: green;
}
.selected {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="sslots">0</div>
<div class="inner">inner</div>
<div class="inner">inner</div>
<div class="inner">inner</div>
<div class="inner">inner</div>
<div class="inner">inner</div>
Also from the code it looks like you want to execute the click once per inner element(ie if you click multiple times in an element only first one should count), in that cause use .one() to register a handler which will be executed only once
Related
In this websites the user can add as much boxes as he wants, and every box contains a green and blue small boxes, the user should be able to click the blue box to remove the green box. the issue is that every time I click the blue box it doesn't remove the green box unless there is only one parent box is made. I have tried a lot of ways but nothing is working.
let count = 0;
function addBox() {
let box = `
<div class="box">
<div class="lbox" id="lbox">
</div>
<div class="rbox" id="rbox">
</div>
<h1>
${count}
</h1>
</div>
`
$(`#boxes`).append(box);
document.getElementById("lbox").addEventListener("click", function() {
rbox.remove();
})
count++;
}
If you have more than one parent box you need to iterate over each one.
You need to do something like;
let boxes = document.querySelectorAll('.box');
boxes.forEach(function(box){
box.querySelector('lbox').addEventListener('click',function(){
box.remove();
});
})
I haven't tested this, but the key part is the forEach function. This means everything you do inside the function is scoped to that box.
id must, at all times, be unique per-document. Learn about this very basic here: https://www.w3schools.com/hTML/html_id.asp. Your code keeps readding the same id values over and over, making your HTML invalid and your code dysfunctional.
Here's a working code example that doesn't rely on ids to get the job done:
let count = 0;
function addBox() {
let box = document.createElement('div');
box.className = 'box';
box.innerHTML = `
<div class="lbox">
</div>
<div class="rbox">
</div>
<h1>
${count}
</h1>`;
document.getElementById('boxes').appendChild(box);
box.querySelector('.lbox').addEventListener('click', function() {
box.querySelector('.rbox').remove();
})
count++;
}
.lbox, .rbox {
display: inline-block;
height: 40px;
width: 40px;
}
.lbox { background-color: blue; }
.rbox { background-color: green; }
<button onclick="addBox()">Add Box</button>
<div id="boxes"></div>
you need to define to delete the other box inside the same parent div.
I would delete the id because the defenition in class is the same.
I would also change the class names to something, wich makes visible what the green and what the blue box is.
You can do following:
let count = 0;
function addBox() {
let box = `
<div class="box_wrapper">
<div class="blue_box">
</div>
<div class="green_box">
</div>
<h1>
${count}
</h1>
</div>
`
$(`#boxes`).append(box);
$( ".blue_box" ).click(function() {
$(this).parent().find(".green_box").remove();
});
count++;
}
I think document.getElementById will always select the first element only with the given id. Therefore only the first lbox element in the dom keeps getting more and more eventlisteners attached to it, while the others won't get any. Make the id's of your elements unique by appending the count. That will make sure that every element gets it's eventlistener:
let count = 0;
function addBox() {
let box = `
<div class="box">
<div class="lbox" id="lbox${count}">
</div>
<div class="rbox" id="rbox${count}">
</div>
<h1>
${count}
</h1>
</div>
`;
$(`#boxes`).append(box);
document.getElementById("lbox" + count).addEventListener("click", function() {
$(".rbox" + count).remove();
})
count++;
}
I want to show two elements on click, one after the other, whereby a user clicks a button the first element with a class(.show-element-one), is shown and when the user clicks the same button for the second time the second element is shown with class(.show-element-two) , am using the code below to show element one on click but I am stuck with showing the second element on the second click.
jQuery(document).ready(function() {
jQuery('#display-elements').click(function() {
jQuery('.show-element-one,.show-element-two').toggle("slide");
});
});
I will appreciate any guides, thanks.
You can set up a counter variable calculate the modulus value for that to display the element of that two classes in circular manner. Something like the code below:
jQuery(document).ready(function() {
var count = 1;
jQuery('#display-elements').click(function() {
jQuery('.show-element-one, .show-element-two').hide();
if (count % 2 !== 0) {
jQuery('.show-element-one').toggle("slide");
} else {
jQuery('.show-element-two').toggle("slide");
}
count++;
});
});
.show-element-one,
.show-element-two {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="display-elements"> Click me </button>
<div class="show-element-one">
show-element-one
</div>
<div class="show-element-two">show-element-two </div>
Maybe you are missing the definition for .slide CSS class. Try the below code.
$(document).ready(function() {
$('#display-elements').click(function() {
$('.show-element-one,.show-element-two').toggle("slide");
});
});
.slide {
display: none;
}
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<div class="show-element-one">show-element-one</div>
<div class="show-element-two slide">show-element-two</div>
<button id="display-elements">Toggle</button>
I'm using the hash to detect the current slide in a slideshow but I'd like to only do so when the slideshow is advanced using the previous or next buttons. But the event "cycle-after" which detects a transition in the slideshow, is firing even when the previous or next buttons are not clicked.
How do I make that event only run during the click function?
JSFiddle here: https://jsfiddle.net/yd8L3enj/4/
$(document).ready(function() {
var clicked = false;
$('.controls').on('click', function() {
$('.cycle-slideshow').on('cycle-after', function(event, optionHash) {
var hash = window.location.hash;
$('.clicked').removeClass('clicked')
if (window.location.hash === hash) {
$(hash).addClass('clicked')
} else {
$(hash).removeClass('clicked')
}
});
});
$('nav a').on('click', function() {
clicked = !clicked;
$('.clicked').removeClass('clicked');
$(this).addClass('clicked');
$('.content').addClass('visible');
});
$("nav a").mouseenter(function() {
var href = $(this).attr('href');
window.location.hash = href
$('.content').addClass('visible');
}).mouseleave(function() {
var current = $('.clicked').attr('href');
window.location.hash = current
if ($(".clicked")[0]) {
// Do something if class exists
} else {
$('.content').removeClass('visible');
}
});
$('.close').on('click', function() {
$('.content').removeClass('visible');
window.location.hash = ""
clicked = !clicked;
});
});
body {
font-size: 150%;
}
img {
width: 50vw;
height: auto;
}
.clicked {
color: green;
}
.content {
display: none;
}
.visible {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.cycle2/2.1.6/jquery.cycle2.min.js"></script>
<nav>
1
2
3
</nav>
<div class="content">
<div class="cycle-slideshow" data-cycle-slides="> div" data-cycle-timeout="0" data-cycle-prev=".prev" data-cycle-next=".next" data-cycle-speed="1" data-cycle-fx="fadeOut">
<div data-cycle-hash="1">
<img src="https://placeimg.com/640/480/animals">
</div>
<div data-cycle-hash="1">
<img src="https://placeimg.com/640/480/animals/2">
</div>
<div data-cycle-hash="2">
<img src="https://placeimg.com/640/480/arch">
</div>
<div data-cycle-hash="2">
<img src="https://placeimg.com/640/480/arch/2">
</div>
<div data-cycle-hash="3">
<img src="https://placeimg.com/640/480/nature">
</div>
<div data-cycle-hash="3">
<img src="https://placeimg.com/640/480/nature/2">
</div>
</div>
<div class="controls">
<div class="prev">Prev</div>
<div class="next">Next</div>
<div class="close">Close</div>
</div>
</div>
the $(selector).on(... syntax binds an event listener. Your code is adding an event listener to the 'cycle-after' event every time the click listener is executed. That means, as soon it was clicked once, all cycle-after events from then on will have that code executed. If you clicked multiple times, you will have bound multiple listeners, and even more of them will be running on every cycle-after event.
What you probably want to do is, for a click, only perform the code after the first next cycle-after event. To achieve this you could bind the listener, and at the end of the callback, unbind it again. Something like this:
$('.controls').on('click', function() {
$('.cycle-slideshow').on('cycle-after', afterCycle);
function afterCycle(){
... your logic here ...
$('.cycle-slideshow').off('cycle-after', afterCycle);
}
});
Keep in mind that this is still pretty fragile. If you click twice before the first cycle-after happens, the library might only fire cycle-after once and you will still have an unwanted listener bound. If this slide-library supports it, it would be best to simply bind once on 'cycle-after', and then add a check that only continues if the cycle was caused by a click.
$('.title').on('click', function(){
console.log($(this).index('.title'));
});
.title{
cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='title'>lorema</div>
<div class='title'>loremb</div>
<div class='title'>loremc</div>
<div class='title'>loremd</div>
Now, how to SET the index of a clicked element, i.e. change its position?
Is it possible something like:
$('.clicked').setIndex('.title', 3);
One option would be to .remove() the clicked element, then find the third .title element currently in the DOM, and use insertAfter to insert the clicked element after it:
$(document).on('click', '.title', function(){
const $this = $(this);
$this.remove();
$this.insertAfter($('.title').eq(2));
});
.title{
cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='title'>lorema</div>
<div class='title'>loremb</div>
<div class='title'>loremc</div>
<div class='title'>loremd</div>
Note the event delegation there - that's needed because otherwise, the listener will only work once for each .title.
To illustrate why .remove is necessary, check the following snippet - although it's using insertAfter($('.title').eq(2));, the .eq(2) refers to the 3rd element before the clicked one is removed, resulting in inconsistent behavior; if you click the first, second, or third element, it'll get put in the third position, instead of the fourth, as desired.
$(document).on('click', '.title', function(){
const $this = $(this);
$this.insertAfter($('.title').eq(2));
});
.title{
cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='title'>lorema</div>
<div class='title'>loremb</div>
<div class='title'>loremc</div>
<div class='title'>loremd</div>
<div class='title'>loreme</div>
<div class='title'>loremf</div>
I would like to add animation effect to following code when showing tree items.
I know that jquery has slide functions, and css has "transition", but not sure how to apply these to my code. Any ideas?
<head>
<script language="JavaScript">
function show(){
var elements = document.getElementsByClassName("label");
for(var i = 0, length = elements.length; i < length; i++) {
elements[i].style.display = 'block';
}
}
</script>
<style>
.label {
-webkit-padding-start: 20px;
display: none;
}
</style>
</head>
<body>
<div>
<div onclick="show()">1st Row</div>
<div>
<div class="label">First</div>
<div class="label">Second</div>
<div class="label">Third</div>
</div>
<div>2nd Row</div>
</div>
</body>
If you are planning to use jQuery then you can use slideDown and slideUp method to show/hide elements with animation. There is slideToggle method which alternatively show/hides the element with animcation. You can modify your show method as below
Working demo
function show(obj){
var $this = $(obj);//Here obj points to the element clicked
//Now you have to show/hide the next sibling of the element clicked
//We will use next() method which gives the next sibling of element
//And then call slideToggle on it to show/hide alternatively
$this.next().slideToggle();
}
Change in the markup
<div onclick="show(this)">1st Row</div>
function show() {
$('.label').slideDown();
}
This selects all elements with the .label class and slides them into view. There is also a .fadeIn() function.
Also, you can attach click handlers by selectors (like an id or class):
<div>
<div class="row">1st Row</div>
<div>
<div class="label">First</div>
<div class="label">Second</div>
<div class="label">Third</div>
</div>
<div class="row">2nd Row</div>
</div>
Notice I removed the onClick="" statement and added a class to the row div. Then you can select the element you want to attach the click event to and keep all the code in one place:
$('.row').bind('click', function () {
$(this).next().find('.label').slideToggle();
});
This JavaScript above adds a click handler to all elements with the row class and toggles the display of all of the elements with the label class in the next element.
Here is a jsfiddle: http://jsfiddle.net/L34g3/.