Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Why bind won't work after setInterval?
var i = 0;
$('.click').bind('click').click(function(){
var thisclick = $(this);
var move = setInterval(function(){
if(i < 30){
i++;
thisclick.unbind('click');
}
else{
thisclick.bind('click');
clearInterval(move);
}
},3000)
})
As of jQuery 1.7 .on() method is preferred, but the actual issues you have are
you are not providing handler for the second binding ( in case you want to rebind the click with the same handler )
you need to reset/clear the counter, since it's a closure variable it'll always be in 30 once reached.
$('.click').on('click', handler);
var i = 0;
function handler(e) {
e.preventDefault();
var thisclick = $(this);
var move = setInterval(function () {
if (i < 10) {
i++;
thisclick.off('click');
} else {
thisclick.on('click', handler);
i = 0; // reset here
clearInterval(move);
}
}, 1000);
};
DEMO
You have to pass function and time to setInterval. Like following example and you are missing time is your code.
setInterval(function(){alert("Hello")}, 3000);
So Change would be
setInterval(function(){
if(i < 30){
i++;
thisclick.unbind('click');
}
else{
thisclick.bind('click');
clearInterval(move);
}
},3000)//Give your value here
Binding to the click event has nothing to do with the issue.
setInterval() expects two parameters: the function to call when triggered, and the time interval in which to trigger said function (in milliseconds)
For example:
var myInterval = setInterval(myFunction, 200);
This will trigger the "myFunction" method every 200 milliseconds.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last year.
Improve this question
I have the below code whichs executes every 5 seconds. However i would like to return different data each time.
For example:
First interval = top level data (level.php)
Second interval = top skill data (skill.php)
Third interval = top magic data (magic.php)
And once the third interval is done... return to level.php to start the sequence again
Can someone tell me how would i modify the code to achieve what i want?
<script>
var text = "";
var toplevel = function() {
$.ajax({
type : 'GET',
url : '/pages/level.php',
success : function(data){
text = data;
$("#tops").fadeOut( "normal", function() {
$('#tops').html(data);
$("#tops").fadeIn( "normal", function() {});
});
},
});
};
$(document).ready(function(){
setInterval(toplevel, 5000);
toplevel();
});
</script>
You could have an array of URLs, always send the request to the first one, and rotate the array order on success:
function toplevel(urls) {
return function () {
$.get(urls[0]).done(function (data) {
urls.push(urls.shift());
$("#tops").fadeOut("normal", function () {
$('#tops').html(data).fadeIn( "normal");
});
});
}
};
$(function () {
var switcher = toplevel(['/pages/level.php', '/pages/skill.php', '/pages/magic.php']);
setInterval(switcher, 5000);
switcher();
});
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I need to customize single click event to double click. And it have to work if second click is clicked in 300 ms.
Something like this should work. Basically you can save the first click, and set a timer to reset that click if no other click is there.
I'm sure there are plenty of better ways to do this, but this works:
let clicked = false;
const timeout = 300;
let timer;
function onClickHandler(e) {
console.log('click');
document.querySelector('#result').innerText = '';
if (timer) window.clearTimeout(timer);
if (!clicked) {
console.log('first time');
clicked = true;
timer = window.setTimeout(() => clicked = false, timeout);
} else {
console.log('double click');
clicked = false;
document.querySelector('#result').innerText = 'Double click!';
}
}
#result{background:red;}
<div onclick="onClickHandler(event)">Click me twice</div>
<div id="result"></div>
Description
Here is an example using the Timeout built into JavaScript
Example:
// the double click time amount
const doubleClickTimeout = 300
// timer variable used to store our timeout pointer
let timer = undefined
// clear function that kills the timeout/timer and variable
let clear = () => {
if (timer) clearTimeout(timer)
timer = undefined
}
// starts the timeout/timer
let clickStart = () => {
timer = setTimeout(clear, doubleClickTimeout)
}
// gets the area you want to monitor
const doubleClick = document.getElementById("doubleClick")
// set up a onclick event on the doubleClick variable that points to the doubleClick div
doubleClick.onclick = () => {
// if timer isn't undefined then we have a double click
if (timer) {
console.log("double click detected")
// call the clear function: clear the timer
clear()
} else {
// call the clickStart function: start a timer
clickStart()
}
}
<div id="doubleClick">this is a clickable area with custom double clicking</div>
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I have around 20 buttons that view different type av boxes when clicked, so my JS code is really long. The function works perfect but im wondering if there is a way to shorten this code or make it more cleaner?
// Content lvl 1
function show(sel) {
var el = $(sel);
el.fadeToggle();
$('.showmore-1').not(el).fadeOut("slow");
}
$('.showmore-1').hide();
$('#click-1a').click(function () {
show('#showmore-1a');
});
$('#click-1b').click(function () {
show('#showmore-1b');
});
// Content lvl 2
function show(sel) {
var el = $(sel);
el.fadeToggle();
$('.showmore-2').not(el).fadeOut("slow");
}
$('.showmore-2').hide();
$('#click-2a').click(function () {
show('#showmore-2a');
});
$('#click-2b').click(function () {
show('#showmore-2b');
// Content lvl 3
function show(sel) {
var el = $(sel);
el.fadeToggle();
$('.showmore-3').not(el).fadeOut("slow");
}
$('.showmore-3').hide();
$('#click-3a').click(function () {
show('#showmore-3a');
});
$('#click-3b').click(function () {
show('#showmore-3b');
});
And this will continue to click 20 i maybe will do even more.
YES
$("[id^=click]").click(function (e) { //match elements with ID's starting with "click"
oldSelector = e.target.id; //get the ID of the clicked element
newSelector = oldSelector.replace("click", "showmore"); //replace string
show(newSelector);
});
Advantage is that the code keeps working if you add more or less buttons the same way. No need to update this code for it, nor the HTML itself.
Body as 1 liner:
$("[id^=click]").click(function (e) {
show(e.target.id.replace("click", "showmore"));
});
If your HTML is editable, try something like this:
<button class="clickable" data-for="#showmore-1">Click</button>
Then your jQuery becomes:
$(function() {
$(document.body).on("click",".clickable",function(e) {
e.preventDefault();
show(this.getAttribute("data-for"));
});
function show(sel) { ... }
});
If your elements are like:
<div id="click-1">click me</div>
make them like:
<div class="showing-trigger" data-target-id="showmore-1">click me</div>
and then your handlers could be:
$('.showing-trigger').on('click', function () {
show('#' + $(this).data('target-id'));
});
Note that with this code your triggers can show a div with any id.
for ( var counter = 0; counter < 20; counter++)
{
$('#click-' + counter).click(function () {
var idCounter = $( this ).attr( "id" ).split( "-" )[1];
show('#showmore-' + idCounter );
});
}
or better yet, bind a click event to a class rather than on id
Try this:
for(var i=1,l=21; i<l; i++){
(function(i){ // closure scopes off i so it's not at end of loop when Event occurs
$('#click-'+i).click(function(){
$('.showmore').fadeOut('slow', function(){ // fade showmore class out
$('#showmore-'+i).show(); // show just the one you want
});
});
})(i);
}
It can be shortened to this:
$("[id^= click]").click(function (e) {
oldSelector = e.target.id; //get the ID of the clicked element
newSelector = oldSelector.replace("click", "showmore");
show(newSelector);
});
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Can someone assist me in trying to get pause on hover working with this example. Essentially I need it to do the following.
Pause interval On Hover
Highlight item hovered over
on hover out resume rotate
Code (fiddle demo):
var $f = $('ul').find('.frame');
function recursive(i) {
$f.removeClass('showing').eq(i).addClass('showing');
setTimeout(function () {
recursive(++i % $f.length)
}, 1000);
}
recursive(0);
Working DEMO
You might need to tweak this a bit to fit into your requirements. Basically the idea is to clear interval on mouse over and resume recursion on mouseout & keep a reference to count.
var $f = $('ul').find('.frame'),
timeOut,
count;
function recursive(i) {
count = i;
$f.removeClass('showing').eq(i).addClass('showing');
timeOut = setTimeout(function () {
recursive(++i % $f.length)
}, 1000);
}
$('ul li').hover(function(){
clearTimeout(timeOut);
});
$('ul li').mouseout(function(){
recursive(count);
});
recursive(0);
Add this
$(".frame").hover(function () {
clearTimeout(t);
console.log(this);
$(this).addClass("showing");
}, function () {
recursive(0);
});
Fiddle
Try this:
var $f = $('ul').find('.frame');
$('ul li').hover(function(){
$f.removeClass('showing');
$(this).addClass('showing');
clearTimeout(timer);
}, function(){
recursive($(this).index());
});
function recursive(i) {
$f.removeClass('showing').eq(i).addClass('showing');
timer = setTimeout(function () {
recursive(++i % $f.length)
}, 1000);
}
recursive(0);
demo
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
jquery add a fade to an .addClass
Here is my jsFiddle example: http://jsfiddle.net/sLzGc/
I am trying to create an effect where it appears options 1 through 3 are being rotated. Every 1.2 seconds the green class is removed from the option that has it and the green class is added to the next option. The idea is that the rotation through the three options happens five times (i<5) before the final function alert('Finished') is executed.
I'm trying to use setTimeout(), but I'm open to using .delay(), another jQuery function, or some other option.
Here is my JavaScript/jQuery:
alert('Start');
sampleFunction();
function sampleFunction() {
for (i=0; i<5; i++) {
setTimeout(function() {
$('#option2').addClass('green');
$('#option1').removeClass('green');
},1200);
setTimeout(function() {
$('#option3').addClass('green');
$('#option2').removeClass('green');
},1200);
setTimeout(function() {
$('#option1').addClass('green');
$('#option2').removeClass('green');
},1200);
}//end for loop
}
alert('Finished');
My whole example is on jsFiddle: http://jsfiddle.net/sLzGc/
Thanks for any help or insight you can offer!
Here's how I would approach the problem:
(function() {
var options = [$("#option1"), $("#option2"), $("#option3")],
cycles = 5,
i = 0,
$last = $(null);
(function next() {
if(i < cycles * options.length) {
$last.removeClass("green");
$last = options[i % options.length].addClass("green");
i++;
setTimeout(next, 1200);
} else {
$last.removeClass("green");
alert("finished!"); //do any other "we're done" stuff here.
}
}());
}());
It's pretty straightforward and the cool part is that you can add elements to the list of elements to cycle through pretty easily (just add them to options). You can also set the number of cycles if you want. I didn't make the class or delay length a variable, but that would be very simple in case you wanted to do that.
You can see a demo here:
http://jsfiddle.net/D7SR8/
You might also consider having a callback function at the end and putting the alert() in there. That would be more reusable.
If you are wanting to use setTimeouts then your code could look something like this:
var iteration = 0;
alert('start');
rotateColors();
function rotateColors() {
setTimeout(function() {
$('#option2').addClass('green');
$('#option1').removeClass('green');
setTimeout(function() {
$('#option3').addClass('green');
$('#option2').removeClass('green');
setTimeout(function() {
$('#option1').addClass('green');
$('#option3').removeClass('green');
iteration += 1;
if(iteration < 5)
rotateColors();
else
alert('finished');
},1200);
},1200);
},1200);
}
Live DEMO
alert('Start');
var varobj=0;
sampleFunction();
function sampleFunction() {
setTimeout(function() {
$('#option2').addClass('green');
$('#option1').removeClass('green');
},1200, setTimeout(function() {
$('#option3').addClass('green');
$('#option2').removeClass('green');
},1200,setTimeout(function() {
$('#option1').addClass('green');
$('#option3').removeClass('green'); if(varobj<5){varobj=varobj+1;sampleFunction();}else{ alert('finished');}
},1200);););}
this is a approch how call function after execution of other in settimeout
I use both setTimeout() and setInterval() to do this and then clear the interval after 5 executions. If you want them to all end on a certain color or any other modifications let me know! I just modified it to loop through how you asked.
http://jsfiddle.net/sLzGc/9/
sampleFunction();
function sampleFunction() {
alert('Start');
$('#option1').addClass('disabled');
var i = 0;
var shift = function() {
setTimeout(function() {
$('#option1').toggleClass('disabled');
$('#option2').toggleClass('disabled');
}, 0);
setTimeout(function() {
$('#option2').toggleClass('disabled');
$('#option3').toggleClass('disabled');
}, 400);
setTimeout(function() {
$('#option3').toggleClass('disabled');
$('#option1').toggleClass('disabled');
}, 800);
};
var interval = setInterval(function() {
++i;
if (i == 5) {
clearTimeout(interval);
alert('Finished');
} else {
shift();
}
}, 1200);
shift();
}