Does anyone know how to stop this slideshow from 'caching' the amount of clicks through the slides? If I click the arrows 10 times then 10 slides will slide through is there a way to stop this? Or alternatively if you click the opposite arrow for it to cancel the 'cached' clicks from the other?
http://www.switchonthecode.com/tutorials/jquery-creating-a-slideshow
Thanks!
Using the one() function will probably do what you are looking for. Adjust the code to the following:
$(document).ready(function(){
// The "one()" function means that this action is disconnected
// from the element once the action occurs. In other words, click
// it twice, and the second one does nothing.
$("#slideshow-previous").one("click", showPreviousSlide);
$("#slideshow-next").one("click", showNextSlide);
...
});
However just doing that isn't enough. We have to hook up the event handler again after the animation is finished. Use the callback function for animate():
function updateContentHolder()
{
...
$("#slideshow-scroller").animate({scrollLeft: scrollAmount}, 1000, function() {
$("#slideshow-previous").one("click", showPreviousSlide);
$("#slideshow-next").one("click", showNextSlide);
});
}
As was pointed out in the comments this has the problem of attaching showPreviousSlide and showNextSlide multiple times to whichever button was not pressed. You can remedy this by doing just a little more work:
function showPreviousSlide()
{
currentSlide--;
updateContentHolder($(this).attr("id"), showPreviousSlide);
updateButtons();
}
function showNextSlide()
{
currentSlide++;
updateContentHolder($(this).attr("id"), showNextSlide);
updateButtons();
}
...
function updateContentHolder(id, callback)
{
...
$("#slideshow-scroller").animate({scrollLeft: scrollAmount}, 1000, function() {
$("#" + id).one("click", callback);
});
}
You could set a flag to true whenever an arrow is clicked something like isPending. Then check this whenever an arrow is clicked and if it is true, ignore the click. Then when the animation finishes set the flag back to false.
Related
I have three buttons with different onclick animations. On click, it adds the "active" class to start the CSS animation. And with setTimeout, it removes that class to remove the final state of the animation and so the button can be clicked again.
Unfortunately though, when you're quickly clicking on the buttons, certain buttons doesn't go through the setTimeout.
Not sure exactly what's going on but here's my js.
var i=0;
$('button').each(function(){
i++;
$('.btn-' + i).on('click', toggleBtn);
function toggleBtn() {
btn = this;
// btn = btn.querySelector(".btn-" + i);
btn.classList.add('active');
setTimeout(function () {
btn.classList.remove('active');
}, 3000)
}
});
Here's the codepen as well.
https://codepen.io/anon/pen/ZqJxZd
Thanks!
each time you click a different button, you lose the setTimeout reference.
one solution is to put the setTimeout in an external function, like this:
function stOut(btn) {
setTimeout(function () {
btn.classList.remove('active');
}, 3000)
}
and calls the function toggleBtn within its function stOut(btn) and passing btn as parameter
i have the following situation:
i have an animated graph, at the end of the animation i want to add a click handler to a "dead" link, which then hides the actual slide and shows the next. i bind it with .one, cause i dont want to fire it again after loading.
so it works, it shows the next slide, but the event is not unbinding.
even if i unbind it manually it fires the event.
can someone give me a clue?
thx
jesta
$("li#slide3").off().on("click", $(this), function() {
$("#slide3 .device").animate({opacity:1}, 1000, function() {
$("#slide3 .device").animate({opacity:0}, 1000, function() {
console.log($("li#slide3 img.graph_adds").data("height"));
$("li#slide3 img.graph_adds").animate({height:$("li#slide3 img.graph_adds").data("height")}, 1500, function() {
$("#book_container").one("click", "a#book", function(ev) {
ev.stopImmediatePropagation();
ev.preventDefault();
if (!animBook) { initialiseAnimatedImages(); }
$("li.active_slide").fadeOut(500, function() {
$("li#slide4").addClass("active_slide").fadeIn(1000);
resetSlides();
}).removeClass("active_slide");
});
});
});
});
});
so, i think i found the solution. the animation was the problem. cause there were multiple devices and graphs with my code-structure each device was firing the function code, so device1 fired, then the two graphs fired two time, then device2 fired them again and so on.
with the .promise().done() structure all is just fired once, the animation works and all events are just fired once. now it should work too that i bind the elements in the .on()-statements, cause now they should bind only once then...but...nevah change a running system ^^
$("li#slide3").on("click", $("div.slide3"), function(ev) {
$("#slide3 .device").animate({opacity:1}, 1000).promise().done(function() {
$("#slide3 .device").animate({opacity:0}, 1000).promise().done(function() {
console.log("slide3-height: "+$("li#slide3 img.graph_adds3").data("height"));
$("li#slide3 img.graph_adds3").animate({height:$("li#slide3 img.graph_adds3").data("height")}, 1500).promise().done(function() {
console.log("slide3 click");
if(!$("a#book").hasClass("slide_4") ) {
$("a#book").addClass("slide_3"); }
});
});
}).promise().done(function() { console.log("div.slide3 anim don") });
});
Here is JQuery command that removes all bindings from the element:
$("#book_container").unbind(); //to flush previously bound actions
I need to execute one function on single click and other function on double click. Problem I am facing is due to the fact that we can not have double click event without first having two single clicks. I want, whenever we have double click then only double click function should execute not single click function . Below is something I have done so far. Please suggest if there is any better way to do it because below code is not always working perfectly.
HTML
<div class='box'>
JS:
var dblclick = false;
//single click function
$('div.box').on('click',function(){
setTimeout(function(){
if(!dblclick){
console.log('singleClick');
}
},200);
});
//resetting double click flag
$('div.box').on('click',function(){
setTimeout(function(){
dblclick = false;
},400);
});
//double click function
$('div.box').on('dblclick',function(){
dblclick = true;
console.log('doubleClick')
});
CSS:
div.box {
height: 100px;
width: 100px;
border: 1px solid black;
}
I think you can do it easily with one timeout, like this:
// where "selector" is your html element selector
var element = $("selector"),
single_click_timeout;
function clicked(e) {
single_click_timeout = setTimeout(function() {
// do something for a SINGLE click
}, 400);
}
function dblclicked(e) {
// stop the single click function
clearTimeout(single_click_timeout);
// do something for a DOUBLE click
}
element.on("click", clicked);
element.on("dblclick", dblclicked);
The trick here is to set a correct amount of time for the setTimeout function. Obviously an user will not perform a double click clicking with an interval of 1 second between clicks, but neither with an interval of 0.01 seconds. So now you've got to try and choose the correct amount of milliseconds for the double click.
check if this works , fiddle demo
$('div.box').prop("disabled", true);
i am using this line to make sure only one is active at a point, also i have kept timeout for click to 1000 ms, you can modify it to what you like.
the js code:
//single click function
$('div.box').on('click',function(){
setTimeout(function(){
if($('div.box').prop("disabled")) return;
console.log('singleClick');
$('div.box').prop("disabled", true);
//some single click work.
$('div.box').prop("disabled", false);
},1000);
});
//double click function
$('div.box').on('dblclick',function(){
if($('div.box').prop("disabled")) return;
$('div.box').prop("disabled", true);
console.log('doubleClick');
//some work then enable single click again
setTimeout(function(){
$('div.box').prop("disabled",false);
},2000);
});
I have a tooltip(which is just a div) that appears when on the mouseover event of another element.
I am trying to make the tooltip hidden on the mouseleave event of the the main element, however, I want the tooltip to remain visible if the mouse is over the tooltip.
The tooltip is being position directly underneath its element.
My code is as follows:
var option_hide_timeout;
$(".option").mouseover(function () {
showTooltip($(this));
});
$(".option").mouseleave(function () {
option_hide_timeout = setTimeout(hideTooltip(), 2000); // delay the hiding to allow the mouse to enter the tooltip
});
$("#option_tt").mouseenter(function () {
clearTimeout(option_hide_timeout);
});
$("#option_tt").mouseleave(function () {
hideTooltip();
});
function showTooltip(parent) {
var parentPos = parent.position();
$("#option_tt").css({
visibility: "visible",
left: parentPos.left,
top: parentPos.top + $(parent).height()
});
}
function hideTooltip() {
$("#option_tt").css("visibility", "hidden");
}
The problem is that the tooltip hides immediately after the mouse leaves the main element.
The problem is persistent across Chrome, Firefox, Opera and IE.
No matter what the value of the delay(2000 in my code is just an example, it would more likely be shorter in practise), it triggers immediately.
I have tried using both mouseover/mouseout and mouseenter/mouseleave - both produce the same results, which leaves me with the conclusion that the line:
setTimeout(hideTooltip(), 2000);
is not correct.
Placing an alert in the mouseleave event assures me that the code is being called.
Am I missing something obvious? If so, a pointer in the correct direction would be greatly appreciated.
Change
option_hide_timeout = setTimeout(hideTooltip(), 2000);
to
option_hide_timeout = setTimeout(hideTooltip, 2000);
The added parenthesis makes the function being immediately called instead of being given to setTimeout.
I seem to have fixed my own issue.
$(".option").mouseleave(function () {
option_hide_timeout = setTimeout(hideTooltip(), 2000); // delay the hiding to allow the mouse to enter the tooltip
});
should be:
$(".option").mouseleave(function () {
option_hide_timeout = setTimeout(function () { hideTooltip() }, 2000);
});
It was very simple and I should have realised this before posting.
Morning folks. Have an issue with a simple jQuery gallery i'm making. It lets the user cycle through a collection of images via some buttons and at the same time, rotates through these images on a timer. My problem is that the user is able to click the button multiple times which queues up the fade in animation and repeats it over and over, e.g. user clicks button 5 times > same image fades in/out 5 times > gallery moves to next image.
I've tried using:
$('#homeGalleryImage li a').unbind('click');
After the click event is fired and then rebinding:
$('#homeGalleryImage li a').bind('click');
After it's done but this simply removes the click event after pressing a button once and never rebinds to it?
I've also tried disabling the button via:
$('#homeGalleryImage li a').attr('disabled', true);
To no avail... ?
There is a secondary issue where if you manage to click a button while the image is in a transition, the next image appears 'faded' as if the opacity has been lowered? Very strange... Here is the code for button clicks:
var i = 1;
var timerVal = 3000;
$(function () {
$("#homeGalleryControls li a").click(function () {
var image = $(this).data('image');
$('#galleryImage').fadeOut(0, function () {
$('#galleryImage').attr("src", image);
});
$('#galleryImage').fadeIn('slow');
$('.galleryButton').attr("src", "/Content/Images/Design/btn_default.gif");
$(this).find('img').attr("src", "/Content/Images/Design/btn_checked.gif");
i = $(this).data('index') + 1;
if (i == 4) {
i = 0;
}
timerVal = 0;
});
});
Here is the code that cycles through the images on a timer:
//Cycle through gallery images on a timer
window.setInterval(swapImage, timerVal);
function swapImage() {
$('#galleryImage').fadeOut(0, function () {
var imgArray = ["/Content/Images/Design/gallery placeholder.jpg", "/Content/Images/Design/1.jpg", "/Content/Images/Design/2.jpg", "/Content/Images/Design/3.jpg"];
var image = imgArray[i];
i++;
if (i == 4) {
i = 0;
}
$('#galleryImage').attr("src", image);
$('#galleryImage').fadeIn('slow');
});
var currentButton = $('#homeGalleryControls li a img').get(i - 1);
$('.galleryButton').attr("src", "/Content/Images/Design/btn_default.gif");
$(currentButton).attr("src", "/Content/Images/Design/btn_checked.gif");
}
I realise it might be a better idea to use a plugin but I'm very new to jQuery and I'd like to learn something rather than using some ready made code.
Any help at all, is much appreciated.
Thankyou
You could always try adding something to the element to cancel the click event?
For example
$(".element").click(function(e) {
if ( $(this).hasClass("unclickable") ) {
e.preventDefault();
} else {
$(this).addClass("unclickable");
//Your code continues here
//Remember to remove the unclickable class when you want it to run again.
}
}):
In your case you could try adding a check on the click.
$('#homeGalleryImage li a').attr('data-disabled', "disabled");
Then inside your click event
if ( $(this).attr("data-disabled" == "disabled") {
e.preventDefault();
} else {
//Ready to go here
}
Edit
Here is a working example showing the element becoming unclickable. http://jsfiddle.net/FmyFS/2/
if you want to make sure that the registered event is fired only once, you should use jQuery's one :
.one( events [, data ], handler ) Returns: jQuery
Description: Attach a handler to an event for the elements. The handler is executed at most once per element per event type.
see examples:
using jQuery: https://codepen.io/loicjaouen/pen/RwweLVx
// add an even listener that will run only once
$("#click_here_button").one("click", once_callback);
using vanilly JS: https://codepen.io/loicjaouen/pen/gOOBXYq
// add a listener that run only once
button.addEventListener('click', once_callback, {capture: true, once: true});