Can I have an event that says: [duplicate] - javascript

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
jQuery: Detecting click-and-hold
I am looking for some way to have an img, and when I hold down the image for maybe 1 or 2 seconds, jQuery changes the CSS to "display","block"... I have looked and looked and could not find what I needed. Please give the best answer possible. I'm making a finger scan app...:) Here is the code I have right now:
HTML:
<body>
<img id="testlaser" src="images/Laser.gif">
<div class="fingerprint">
</div>
<img class="access_denied" src="images/AccessDenied.jpg">
</body>
CSS:
<style>
body{-webkit-user-select: none;overflow:hidden;scrolling:no;}
#testlaser{height:100%;width:100%;position:absolute;display:none;}
.fingerprint{display:block;position:absolute;background-image:url(images/fingerprint.gif);background-repeat:no-repeat;background-position:center center;text-align:center;width:100%;height:90%}
.access_denied{display:none;background-position:center center;width:100%;height:100%;}
.access_granted{display:none;background-position:center center;width:100%;height:100%;}
</style>
Java Script:
<script>
$(".fingerprint").click('click mousedown', function(){
$("#testlaser").css("display","block")
$(".fingerprint").css("display","block")
setTimeout(function(){
$("#testlaser").css("display","none")
$(".fingerprint").css("display","none")
$(".access_denied").css("display","block")
},10000);
});
$(".access_denied").click(function(){
$("#testlaser").css("display","none")
$(".fingerprint").css("display","block")
$(".access_denied").css("display","none")
});
</script>

Add a "mousedown" handler to your image which sets a trigger function after two seconds and a "mouseup" function which clears the timeout function. For example:
(function() {
var foo=$('#foo'), tf=null;
foo.mousedown(function() {
tf = setTimeout(function() {
alert('Two seconds!');
}, 2000);
});
foo.mouseup(function() {
clearTimeout(tf);
});
})();
Here is a working jsFiddle demo to boot.

If you think that you will be doing this a lot you can make a plugin (okay.. so I was intrigued by this).
Here's the calling code:
$('.fingerprint').delayedReaction(function() {
$(".fingerprint").hide();
$(".access_denied").show();
});
$(".access_denied").click(function() {
$(".fingerprint").show();
$(".access_denied").hide();
});
Here's the plugin:
(function($){
$.fn.delayedReaction = function(successFunction, options) {
var settings = $.extend({}, $.fn.delayedReaction.defaults, options);
this.each(function() {
var timeout,
myFunction = successFunction,
$this = $(this);
var run_func = function() {
myFunction.apply($this)
};
$this.bind(settings.startEvent, function() {
timeout = setTimeout(run_func, settings.delayFor);
});
$this.bind(settings.stopEvent, function() {
clearTimeout(timeout);
timeout = null;
});
});
return this;
}
$.fn.delayedReaction.defaults = {
startEvent: 'mousedown',
stopEvent: 'mouseup mouseleave',
delayFor: 3000
}
})(jQuery);
See it in action: http://jsfiddle.net/natedavisolds/Nb7zQ/1/

Related

Consolidate javascript timeout functions

Sorry for the basic level of the question, but js definitely isn't my area of expertise. However, it's one of those questions that's difficult to Google an answer on.
I basically want to do a couple of things when the window is resized. I have a little bit of extra code that also stops the resize event firing twice.
The issue is that I'm duplicating bits of code, that as a coder, I know is wrong. The problem is I don't know how to go about making it right. Here's my current duplicated code:
Event binding
$(window).on("resize", resizeText);
$(window).on("resize", resizeIndicator);
Functions
function resizeIndicator() {
clearTimeout(id);
id = setTimeout(updateIndicator, 200);
}
function resizeText() {
clearTimeout(id);
id = setTimeout(updateText, 200);
}
Thse are not duplicated but included for completeness:
function updateIndicator() {
$tab = $(".tabs li.focus");
if ($tab.length) {
toggleIndicator($tab, true);
}
}
function updateText() {
$tabs = $(".tabs li:not(.indicator) a");
$tabs.each(function () {
$(this).toggleClass("two-line", this.scrollWidth > $(this).outerWidth());
});
}
So you want to avoid code duplication? No problem use higher order of function to create new function.
function createResizeCallback(resizeFunc) {
var id;
return function () {
clearTimeout(id);
id = setTimeout(resizeFunc, 200);
}
}
$(window).on("resize", createResizeCallback(updateText));
$(window).on("resize", createResizeCallback(updateIndicator));
function updateIndicator() {
console.log('updateIndicator');
}
function updateText() {
console.log('updateText');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Declare your timeout id globally and use single handler.
Working demo: http://jsbin.com/nugutujoli/1/edit?js,console,output
$(window).on("resize", resizeEvent);
var timeout;
function resizeEvent() {
clearTimeout(timeout);
timeout = setTimeout(function(){
updateIndicator();
updateText();
}, 200);
}
function updateIndicator() {
console.log("update indicator fired.");
}
function updateText() {
console.log("update text fired.");
}

Trigger function only if mouseenter event lasted 1 second

I need to show a tooltip when a user hovers over a specific tag on my page. However, I want to do it only if the tag was hovered for at least a second. I tried the code below, but - obviously - setTimeout() will trigger after a second every time, even if the cursor is "long gone".
Is there an easy way in jQuery to achieve this? Not really interested in any plugin-solution.
Fiddle
HTML
<div class="tag-tooltip" id="tooltip-1">Followers: 34</div>
<div class="tag js-tag" data-id="1">Star Wars (hover over me!)</div>
jQuery
$(document).on('mouseenter', '.js-tag', function() {
var $this = $(this);
setTimeout(function() {
$('#tooltip-' + $this.data('id')).show();
}, 2000);
});
$(document).on('mouseleave', '.js-tag', function() {
$('#tooltip-' + $this.data('id')).hide();
});
UPDATE ON SOLUTION
Many good suggestions below, many ways to achieve same thing. I find clearTimeout() solution the cleanest, though. Thanks to everyone who contributed:)
You were almost there, here you go:
http://jsfiddle.net/j21wjtwh/4/
var hoverTimer;
$(document).on('mouseenter', '.js-tag', function() {
var $this = $(this);
hoverTimer = setTimeout(function() {
$('#tooltip-' + $this.data('id')).show();
}, 1000);
});
$(document).on('mouseleave', '.js-tag', function() {
clearTimeout(hoverTimer);
$('#tooltip-' + $(this).data('id')).hide();
});
Use a flag. Set it to false on mouseleave. In mouseenter check if variable is set.
var show = false; // Define var
// ^^^^^^^^^^^^^
$(document).on('mouseenter', '.js-tag', function () {
show = true; // Set to `true`
var $this = $(this);
setTimeout(function () {
if (show) { // Check if true
$('#tooltip-' + $this.data('id')).show();
}
}, 1000);
});
$(document).on('mouseleave', '.js-tag', function () {
$('#tooltip-' + $(this).data('id')).hide();
show = false; // Unset
});
Demo: http://jsfiddle.net/tusharj/j21wjtwh/2/
Here is a Fiddle
Here is a Code
$(document).on('mouseenter', '.js-tag', function() {
var $this = $(this);
setTimeout(function() {
if($('.js-tag').is(":hover"))
{
$('#tooltip-' + $this.data('id')).show();
}
}, 1000);
});
$(document).on('mouseleave', '.js-tag', function() {
$('#tooltip-' + $(this).data('id')).hide();
});
But there is one small bug here, try to hover/unhover fast, and you will see it
EDIT
As for me THIS answer much better. It doesn't contains my bug
Just keep track of whether or not you are currently hovering with a variable.
Set the hovering variable to true on mouse enter, and false on mouseleave.
Then in your setTimeout event, check if you are currently hovering.
Updated Fiddle
var hovering = false;
$('.js-tag').mouseenter(function () {
var $this = $(this);
hovering = true;
setTimeout(function () {
if (hovering) {
$('#tooltip-' + $this.data('id')).show();
}
}, 1000);
});
$('.js-tag').mouseleave(function () {
hovering = false;
$('#tooltip-' + $(this).data('id')).hide();
});
You can store timer handle in variable and clear it using clearTimeout on mouseleave.
Here is jsfiddle for it.
http://jsfiddle.net/Lz9snp9t/3/
Try this:
$('.js-tag').on('mouseover', function() {
var $this = $(this);
if(!$this.data('timeout')) {
$this.data('timeout', setTimeout(function() {
$('#tooltip-' + $this.data('id')).show();
}, 2000);
}
});
$('.js-tag').on('mouseout', function() {
var $this = $(this);
if($this.data('timeout')) {
clearTimeout($this.data('timeout'));
}
$('#tooltip-' + $this.data('id')).hide();
});

jQuery stops working after

I have a page which relies heavily on CSS3 animations. I am in the process of creating a script that will be the fallback that will work for those browsers that do not have CSS3 animations (looking at you IE...). I created the following script that will do the basic of what I need:
var $j = jQuery.noConflict();
$j(document).ready(function() {
//Hide All Elements to Fade Them In
$j(".frame-1, .frame-2, .frame-3, .frame-4, #tile-wrap, #copyright").addClass("hide", function() {
//Change Color of "Frames"
$j(".frame-1, .frame-2, .frame-3, .frame-4").addClass("color", function() {
//Frame 1
$j(".frame-1").fadeIn("slow", function() {
$j('.frame-1').delay(3000).fadeOut('slow', function() {
//Frame 2
$j(".frame-2").fadeIn("slow", function() {
$j('.frame-2').delay(3000).fadeOut('slow', function() {
//Frame 3
$j(".frame-3").fadeIn("slow", function() {
$j('.frame-3').delay(3000).fadeOut('slow', function() {
//Frame 4
$j(".frame-4").fadeIn("slow", function() {
$j('.frame-4').delay(3000).fadeOut('slow', function() {
//Tile
$j('#tile-wrap').fadeIn('slow');
});
});
});
});
});
});
});
});
});
});
});​
The first part of the script works without issue (adding the class of .hide). But nothing after that fires or works. I am stuck because no errors are seen and I assume I have an error in my script.
Here is a fiddle of the script with the rest of the code.
Note: I am not very knowledgeable of writing JS and welcome any ways to improve the script, please provide examples.
FIDDLE NOTE Firebug shows a couple errors when running the fiddle. These errors are only on the Fiddle page and I believe are related to the jsFiddle not my code or page.
What I am attempting to Achieve
What I want is for each item (as listed by class or id) is to fade them in then fade them out after a delay then fade in the last div and it stays.
This will work, http://jsfiddle.net/VNfT2/2/. There is no callback for addclass. Having said that. AHHH!!!!!! This is NOT the right way to do it. Hint: When you see more than 10 }); in a row, stop and take a deep breath. :)
Edit: There are hundreds of plugins to do this (google for jquery slideshow). But, if you want to do it manually...look at this: fiddle: http://jsfiddle.net/VNfT2/5/
See http://jsfiddle.net/VNfT2/4/
var $j = jQuery.noConflict();
$j(document).ready(function() {
//Hide All Elements
$j(".frame-1, .frame-2, .frame-3, .frame-4, #tile-wrap, #copyright")
.addClass("hide")
//Change Color of "Frames"
.addClass("color");
//Frame 1
$j(".frame-1").fadeIn("slow", function() {
$j(this).delay(3000).fadeOut('slow', function() {
//Frame 2
$j(".frame-2").fadeIn("slow", function() {
$j(this).delay(3000).fadeOut('slow', function() {
//Frame 3
$j(".frame-3").fadeIn("slow", function() {
$j(this).delay(3000).fadeOut('slow', function() {
//Frame 4
$j(".frame-4").fadeIn("slow", function() {
$j(this).delay(3000).fadeOut('slow', function() {
//Tile
$j(this).fadeIn('slow');
});
});
});
});
});
});
});
});
});
As I said im my comment, you can call addClass with a string (the class) or with a function which return the class. But you can't do it with a string and a function... See api.jquery.com/addClass
And in your callback functions you should use $(this), it's faster because this way you don't search the element again.
The problem that your callbacks aren't called since they're supplied as the second argument.
addClass( className )
Description: Adds the specified class(es) to each of the set of matched elements.
.addClass( className )
.addClass( function(index, currentClass) )
Here are some tips:
1)
Try to only have 1 nested/callback function inside another function.
Refer to tip 4, then function fadeElementsInThenOut for an example.
2)
Don't repeat lookups.
Old code:
// Let's forget about the callbacks for now
$j(".frame-1, .frame-2, .frame-3, .frame-4, #tile-wrap, #copyright").addClass("hide");
$j(".frame-1, .frame-2, .frame-3, .frame-4").addClass("color");
New Code:
$j(".frame-1, .frame-2, .frame-3, .frame-4").addClass("color hide");
$j("#tile-wrap, #copyright").addClass("color");
3)
Use $(this) to reference the same element within a callback.
Old Code:
$j(".frame-4").fadeIn("slow", function () {
$j('.frame-4').delay(3000).fadeOut('slow', function () {
//...
});
});
New Code:
$j(".frame-4").fadeIn("slow", function () {
$j(this).delay(3000).fadeOut('slow', function () {
//...
});
});
4)
Don't use a callback if you don't have to.
Old Code:
$j(".frame-4").fadeIn("slow", function () {
$j(this).delay(3000).fadeOut('slow', function () {
//...
});
});
New Code:
$j(".frame-4").fadeIn("slow").delay(3000).fadeOut('slow', function () {
//...
});
Here's your code rewritten to fix the problems.
var $j = jQuery.noConflict();
$j(function () {
var frames = [ ".frame-4", ".frame-3", ".frame-2", ".frame-1" ];
var fadeElementsInThenOut = function( els, lastCallback ){
var el = els.pop();
if( el ){
$j(el).fadeIn("slow").delay(3000).fadeOut('slow', function(){
fadeElementsInThenOut( els, lastCallback );
});
}else{
lastCallback();
}
};
$j( frames.join( ", " ) ).addClass("color hide");
$j("#tile-wrap, #copyright").addClass("color");
fadeElementsInThenOut( frames, function(){
$j('#tile-wrap').fadeIn('slow');
});
});

jquery disable click until animation is fully complete

i want to disable click function untill every code in it; initialized and completed.
i read these articles and tried what they said but cant make it happen:
event.preventDefault() vs. return false
+
Best way to remove an event handler in jQuery?
+
jQuery - Disable Click until all chained animations are complete
i prepared simple example for this question:
This is DEMO
html
<div class="ele">1</div>
<div class="ele">2</div>
<div class="ele">3</div>
​
jQuery
$('.ele').click(function() {
if ( !$('.ele').is(':animated') ) {//this works too but;
//is:animate duration returns = 2000 but need to be 4000
$('.ele').stop().animate({'top':'0px'},2000);
$(this).stop().animate({'top':'100px'},4000);
}
return false;
});
​
Use on() and off() to turn the click function on/off :
$('.ele').on('click', animateEle);
function animateEle(e) {
$('.ele').stop().animate({'top':'0px'},2000);
$(e.target).off('click').stop().animate({'top':'100px'},4000, function() {
$(e.target).on('click', animateEle);
});
}​
DEMONSTRATION
You can try this:
var exec_a1 = true, exec_a2 = true;
$('.ele').click(function() {
if (exec_a1 && exec_a2) {
exec_a1 = false;
exec_a2 = false;
$('.ele').stop().animate({'top': '0px'}, 2000, function() {
exec_a1 = true;
});
$(this).stop().animate({'top': '100px'}, 4000, function() {
exec_a2 = true;
});
}
return false;
});

Delay in show after 2 second by jquery

I want if user moved the mouse for two seconds (Keep the mouse button for two seconds) on a class, show to he hide class. how is it? ()
If you move the mouse tandem (several times) on class, You will see slideToggle done as automated, I do not want this. How can fix it?
DEMO: http://jsfiddle.net/tD8hc/
My tried:
$('.clientele-logoindex').live('mouseenter', function() {
setTimeout(function(){
$('.clientele_mess').slideToggle("slow");
}, 2000 );
}).live('mouseleave', function() {
$('.clientele_mess').slideUp("slow");
})​
Please try this below link Your Problem will solve
http://jsfiddle.net/G3dk3/1/
var s;
$('.clientele-logoindex').live('mouseenter', function() {
s = setTimeout(function(){
$('.clientele_mess').slideDown();
}, 2000 );
}).live('mouseleave', function() {
$('.clientele_mess').slideUp("slow");
clearTimeout(s)
})
Write your html like this
<div class="clientele-logoindex">Keep the mouse here
<div class="clientele_mess" style="display: none;">okkkkkkko</div></div>
Record when a timer is started and check if one exists before starting a new one:
window.timer = null;
$('.clientele-logoindex').live('mouseenter', function() {
if(!window.timer) {
window.timer = setTimeout(function(){
$('.clientele_mess').slideToggle("slow");
window.timer = null;
}, 2000 );
}
}).live('mouseleave', function() {
$('.clientele_mess').slideUp("slow");
})​
Take a look at hoverIntent is a jquery plugin to ensure hover on elements.

Categories