Not sure if it is possible. The idea is very basic, list of buttons that onload start changing its background with a short interval and then repeat. I have a list of elements like:
<div class="container">
<div class="button"></div>
<div class="button"></div>
<div class="button"></div>
</div>
Next I want to manipulate it one by one, change background and pass to next with short interval. The problem is that it applies changes to all of them at once.
Here is the way I do it:
var element = $('.button');
element.each(function(){
var thisObj = $(this);
setInterval(function(){
thisObj.css({
'background':'#000'
})
}, 1000)
});
And then simply repeat it till the mouseover event is detected.
Could anyone suggest a way to do this? Thank you.
Here is an example: http://jsfiddle.net/maniator/S7C9h/
Some code to go along with it:
var buttons = $('.button'),
buttons_length = buttons.length;
function sliiide(index, interval){
var button = buttons.eq(index%buttons_length);
if(button.css('background-color') == 'rgb(0, 0, 255)'){ //blue
button.css({
background: 'white'
});
}
else {
button.css({
background: 'blue'
});
}
setTimeout(function(){
sliiide(++index, interval);
}, interval)
}
sliiide(0, 500);
This uses setTimeout instead of setInterval to reduce bubbling of the timeout events.
Update based on your comments below: http://jsfiddle.net/maniator/gMDEM/4/
I don't know if I understood what you want to do. Would this work?
var element = $('.button');
element.each(function(index){
var thisObj = $(this);
setTimeout(function(){
setInterval(function(){
thisObj.css({
'background':'#000'
})
},1000);
},1000 * index);
});
So each interval will begin with 1 second of difference.
Did I understood right?
If you only want the effect to happen once you should use setTimeout not setInterval. setInterval sets up a repeating event. Maybe you should try something like...
var element = $('.button');
var offsetTime = 1000;
element.each(function(){
var thisObj = $(this);
setInterval(function(){
thisObj.css({
'background':'#000'
})
},offsetTime)
offsetTime += 1000;
});
I would say, you should use different intervals for each button. In addition it is better to use setTimeout instead of setInterval, as the latter can cause performance issues:
var $element = $('.button');
$element.each(function(index, button){
var $button = $(button);
setTimeout(function changeColor(){
$button.css({'background':'#000'});
setTimeout(changeColor, 1000);
}, 1000*index);
});
Related
Click on the 5 and it will become 7-9-11...
I'm expecting 6-7-8...
Any help?
function go_plus(e) {
let obj = $(e.target);
let a = parseInt(obj.text());
a += 1;
obj.text(a);
}
var setint = '';
function go_spinn(e) {
setint = setInterval(function() {
go_plus(e);
}, 79);
}
$('#count').on('mouseleave mouseup', function() {
clearInterval(setint);
});
#count {
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='count' onclick='go_plus(event)' onmousedown='go_spinn(event)'>5</div>
So the problem is you can "slow-click" things - hold the mousedown for a second or two, then let it go, and still result in a click.
The best way to solve the problem is to put a timeout before go_spin starts that you can clear when you click.
The drawback is your go_spinn doesn't start up as fast - i.e. you need to hold the mouse down for the duration of your timeout, in my example it was 200ms, before your go_spinn starts. Test it, you might be able to drop it back a little bit (to 150ms or so) to achieve what you want.
EDIT: By the way, I was just making an assumption on what you were trying to achieve - what were you actually trying to achieve with this code?
function go_plus(e){
let obj = $(e.target);
let a = parseInt(obj.text());
a += 1;
obj.text(a);
}
var setint = '';
var startspin;
function go_spinn(e){
startspin = setTimeout(function() {
setint = setInterval(function(){go_plus(e);}, 79);
},200);
}
$('#count').on('click mouseleave mouseup', function(){
clearInterval(setint);
clearInterval(startspin);
});
#count{
cursor:pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='count' onclick='go_plus(event)' onmousedown='go_spinn(event)'>5</div>
Just change your html code to <div id='count' onmousedown='go_spinn(event)'>5</div> so that you remove the onclick event.
just need a little help here. My problem is, how can I count the seconds when i hover a specific element. Like for example when I hover a button, how can i count the seconds did i stayed in that button after I mouseout?
An alternate solution using setInterval. DEMO HERE
var counter = 0;
var myInterval =null;
$(document).ready(function(){
$("div").hover(function(e){
counter = 0;
myInterval = setInterval(function () {
++counter;
}, 1000);
},function(e){
clearInterval(myInterval);
alert(counter);
});
});
A simple example
var timer;
// Bind the mouseover and mouseleave events
$('button').on({
mouseover: function() {
// set the variable to the current time
timer = Date.now();
},
mouseleave: function() {
// get the difference
timer = Date.now() - timer;
console.log( parseFloat(timer/1000) + " seconds");
timer = null;
}
});
Check Fiddle
How about this quick plugin I just knocked out, which will work on multiple elements, and without using any global variables:
(function($) {
$.fn.hoverTimer = function() {
return this.on({
'mouseenter.timer': function(ev) {
$(this).data('enter', ev.timeStamp);
},
'mouseleave.timer': function(ev) {
var enter = $(this).data('enter');
if (enter) {
console.log(this, ev.timeStamp - enter);
}
}
});
};
})(jQuery);
Actually disabling the functionality is left as an exercise for the reader ;-)
Demo at http://jsfiddle.net/alnitak/r9XkX/
IMHO, anything using a timer for this is a poor implementation. It's perfectly trivial to record the time without needing to use an (inaccurate) timer event to "count" seconds. Heck, the event object even has the current time in it, as used above.
This is exam:
var begin = 0;
var end = 0;
$('#btn').hover(function () {
begin = new Date().getTime();
});
$('#btn').leave(function () {
end = new Date().getTime();
sec = (end - begin) / 1000;
alert(sec);
});
One way to go about it would be the event.timeStamp method :
var initial_hover, exit_hover;
$('#ele').hover(
function(event){
initial_hover = event.timeStamp
console.log(initial_hover);
},
function(event){
exit_hover = event.timeStamp
$(this).html(exit_hover - initial_hover);
console.log(exit_hover);
}
);
jsfiddle
You've tagged the question with JQuery, so here's a jQuery solution.
$(element).on('mouseover', function(e){
$(e.target).data('hover-start', new Date().getTime());
});
$(element).on('mouseout', function(e){
// count the difference
var difference = new Date().getTime() - $(e.target).data('hover-start');
// clean up the data
$(e.target).data('hover-start', undefined);
console.log('Mouse was over for', difference/1000, 'seconds');
});
use setInterval and store value in variable. call the function on mouserover.
function mouseover(){
var start = 0;
setInterval(function(){
start++;
var count = start;
}, 1000);
}
I'm trying to make a random text effect kinda like the one at the end of the movie War Games (Matthew Broderick). The idea is to have individual letters change randomly when ever the user hovers over one of the letters in the word. Eventually after a short time the letter would end up being "decoded" meaning that it would end up on the right letter or number. I have built basic effect but the part I am struggling with is setting the timer. I want to create a small delay between the hover-out event and the actual display of the decoded character. When i add a settimeout however. The script breaks and seems to stack timers. I'm not sure what I'm doing wrong. Below is the code I've got so far.. any help would be great.
function setDecodedChar(object){
var decodedMessage = "HELLO WORLD";
var index = object.attr('class').substring(4);
console.log(index);
object.html(decodedMessage[index]);
}
function changeChar(object){
var randomchar = getrandomChar();
object.html(randomchar);
}
function getrandomChar(){
var char = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
char = possible.charAt(Math.floor(Math.random() * possible.length));
return char;
}
$(function() {
typesetting.letters('.title-text');
var target = $(".title-text").children();
console.log(target);
var timer;
var gate = true;
$(target).hover(function(){
var charChar = $(this);
//on hover-over
if(gate){
gate = false;
timer=setInterval(function(){
changeChar(charChar);
},100);
}
},function(){
//on hover-out
setTimeout(function(){ //<-- breaks here
clearInterval(timer)
setDecodedChar($(this));
},1000);
gate = true;
}
);
});
Here is a jsfiddle of the effect as I currently have it working. http://jsfiddle.net/thesnooker/htsS3/
I really like your idea, and I worked on it. I got it working.
First, here a fiddle : http://jsfiddle.net/htsS3/2/
I must say, i don't know if its the optimal way, but it still working!
The problem with you method is that you have 1 timer for every character, they override themselves, so some letters wont stop.
How i solve it:
I set the timer in the data of every letter like that :
$(this).data('timer', setInterval(function () {
changeChar(charChar);
}, 100));
Not every span have their own timer.
On hover out, i ad to save the $(this) reference into a `var since you lost it in the timeout. I alos saved the timeout into the data so i could stop it when you hover it and it's still changing. Well it look like that now :
var $this = $(this);
$this.data('timeout', setTimeout(function(){
clearInterval($this.data('timer'));
setDecodedChar($this);
},1000))
And finally, on hover, i had to clear timeout and interval:
clearInterval($(this).data('timer'));
clearTimeout($(this).data('timeout'));
Well, I find it hard to explain in my own word, so take a good look at the code and enjoy!
setsetTimeout(function(){ //<-- breaks here
clearInterval(timer)
setDecodedChar($(this));
},1000);
You have an extra 'set'
setTimeout(function(){ //<-- breaks here
clearInterval(timer)
setDecodedChar($(this));
},1000);
So the issue could be related to the timer. It changes every time the setInterval is called. If you were to store the interval on the hover object then clear it by using the stored reference it works.
Cool concept by the way.
$(function () {
var target = $(".text").children();
var timer;
$(target).hover(function () {
var charChar = $(this);
if($(this).data("timer") == void(0)) {
if($(this).data("timeout") != void(0)) {
clearTimeout($(this).data("timeout"));
}
$(this).data("timer", setInterval(function () {
changeChar(charChar);
}, 100));
}
}, function () {
//on hover-out
var timerObject = $(this);
timerObject.data("timeout", setTimeout(function() {
clearInterval(timerObject.data("timer"));
setDecodedChar(timerObject);
timerObject.removeData("timer");
}, 1000));
});
I am trying to animate a handful of DIV's to scroll upwards but I want one to scroll up after a pause after the other after the other. And the best I can come up with at the moment is
$('.curtain').each(function()
{
var $elem = $(this);
setTimeout(function()
{
$elem.animate({"height":0+'px'}, 2000);
}, 1000);
});
Problem is they still all animate together without pause. How can I go about doing something in this fashion. The divs are dynamically generated and there can be 5 - 20 of them so doing a hardcoded logic is out, any ideas?
function animateIt () {
var elems = $('.curtain').get();
(function next() {
if(elems.length){
var elem = $(elems.shift());
elem.animate({"height":0+'px'}, 2000, next);
}
})();
}
animateIt();
running example
Another way like queue
function animateIt () {
var divs = $('.curtain');
divs.each( function(){
var elem = $(this);
$.queue(divs[0],"fun", function(next) { elem.animate({"height":0+'px'}, 2000, next); });
});
divs.eq(0).dequeue("fun");
}
Looks like a simple recursive function might work for you here -
function doAnimation(elapsed){
var iterations = $('.curtain').length;
var current = elapsed+1;
if (current <= iterations){
setTimeout(function(){
$('.curtain:eq(' + elapsed + ')').animate(...);
doAnimation(current);
},50);
}
}
doAnimation(0);
Here's a simple demo
After an Ajax request, I perform the following.
$('#change_ts').text('Defaults Changed!');
//blinking part
var t = setTimeout($('#change_ts').fadeIn('slow'), 500);
clearTimeout(t);
var t = setTimeout($('#change_ts').fadeOut('slow'), 500);
clearTimeout(t);
var t = setTimeout($('#change_ts').fadeIn('slow'), 500);
clearTimeout(t);
var t = setTimeout($('#change_ts').fadeOut('slow'), 500);
clearTimeout(t);
var t = setTimeout($('#change_ts').fadeIn('slow'), 500);
clearTimeout(t);
var t = setTimeout($('#change_ts').fadeOut('slow'), 500);
clearTimeout(t);
var t = setTimeout($('#change_ts').fadeIn('slow'), 500);
clearTimeout(t);
var t = setTimeout($('#change_ts').text('Change Text/Size'), 500);
clearTimeout(t);
It is my make-shift fade in/out blinker. It works well.
However, the first line has no effect when I perform the blinking part. If I remove the blinking the text of the span is changed. But as soon as I uncomment the blinker, it doesn't change the text at all?!
Any ideas why this is?
Thanks all for any help
Update
The set timeout is useless for what I need to do. I have removed it now and I have the following, but I still can not change the text before the fade in/outs?
$('#change_ts').text('Defaults Changed!');
$('#change_ts').fadeIn('slow');
$('#change_ts').fadeOut('slow');
$('#change_ts').fadeIn('slow');
$('#change_ts').fadeOut('slow');
$('#change_ts').fadeIn('slow');
$('#change_ts').fadeOut('slow');
$('#change_ts').fadeIn('slow');
$('#change_ts').text('Change Text/Size');
How about using the jQuery Blink plugin instead. You can see the demo here :)
You should pass a callback function to setTimeout, like this:
var t = setTimeout(function() { $('#change_ts').fadeIn('slow') }, 500);
Right now, you're calling the fade function immediately and sending the return value to setTimeout. You should also change the timeout values to be increasing, like 500, 1000, 1500 etc., otherwise all the fade in/out will occur at the same time. You could use a loop to set-up the values for you. And why are you clearing the timers immediately - they won't have any effect if you do so.
for (var i = 1; i <= 6; i += 2) {
setTimeout(function() { $('#change_ts').fadeIn('slow') }, 500 * i);
setTimeout(function() { $('#change_ts').fadeOut('slow') }, 500 * (i + 1));
}
You can also make a generic blinker like this, which will keep blinking until you clear the timer:
var state = true;
function blink() {
state = !state;
if (state)
$('#change_ts').fadeIn('slow');
else
$('#change_ts').fadeOut('slow');
}
var t = setInterval(blink, 500);
This will keep going until you call clearInterval(t).
Update: The reason the first text call has no effect is because the second text call is executed immediately and the text is overwritten. Note that the fadeIn and fadeOut return immediately, before the animation is completed, so the second text call executes right after that. If you want to wait until the animation is complete, you need to attach a callback to the last fade function, like this:
$('#change_ts').fadeIn('slow', function() {
$('#change_ts').text('Change Text/Size');
});