I've run into an issue with jQuery code that I'd like some help on. While the next and previous buttons work correctly, there appears to be an issue correctly stopping a slideshow. This is probably something we're completely overlooking, but I can't see what.
There is no JavaScript errors showing in the console. The interrupt method was being reached - at one point I had console.log calls in there to verify (cleaned up for presentation reasons).
http://jsfiddle.net/eLn83ep0/
Your help is much appreciated.
The below code is the functionality for prev/stop/start/next:
if ($(settings.next).size()) {
$(settings.next).bind('click.scrollface', function (e) {
methods.interrupt.call($this);
methods.next.call($this);
});
}
if ($(settings.pause).size()) {
$(settings.pause).bind('click.scrollface', function (e) {
methods.interrupt.call($this);
});
}
if ($(settings.play).size()) {
$(settings.play).bind('click.scrollface', function (e) {
methods.interrupt.call($this);
methods.start.call($this);
});
}
/*
* Setup up prev bindings
*/
if ($(settings.prev).size()) {
$(settings.prev).bind('click.scrollface', function (e) {
methods.interrupt.call($this);
methods.prev.call($this);
});
}
Here is the method for interrupt:
interrupt: function (time) {
return $(this).each(function () {
var data = $(this).data('scrollface');
console.log(data);
console.log('...');
if (!data) {
return false;
}
var $this = $(this),
period = 0;
/*
* Stop the timer, and wait a period of time before restarting it.
* Period defaults to the timer interval
*/
if (data.timer) {
if (typeof time !== "number") {
period = data.interval;
} else {
period = time;
}
methods.stop.call(this);
setTimeout(function resume_timer () {
clearInterval(data.timer);
data.timer = null;
methods.start.call($this);
}, period);
}
});
},
if ($(settings.pause).size()) {
$(settings.pause).bind('click.scrollface', function (e)
methods.stop.call($this);
});
}
if ($(settings.play).size()) {
$(settings.play).bind('click.scrollface', function (e) {
methods.start.call($this);
});
}
and delete the interrupt call in prev and next
//methods.interrupt.call(this);
because the interrupt method stopping the interval method and after timeout starting again, so most time you pause in this timeout but after this timeout the interrupt method starting the intervall again and dont care if you stoped it manually
see your updated fiddle working here http://jsfiddle.net/7ko4rdda/
Edit:
if you call interrupt with 0 for the buttons prev next click handler then you have the expected behavier that the period for the intervall starts new after next/prev click
if ($(settings.prev).size()) {
$(settings.prev).bind('click.scrollface', function (e) {
methods.interrupt.call($this,0);
methods.prev.call($this);
});
}
if ($(settings.next).size()) {
$(settings.next).bind('click.scrollface', function (e) {
methods.interrupt.call($this,0);
methods.next.call($this);
});
}
http://jsfiddle.net/7ko4rdda/1/
Related
I met some problem when I use CasperJS to scrape a website. The website is dynamically loaded like Twitter, so I want to do infinite scroll,
and thanks to #Artjom B. I found you code to do this.
var tryAndScroll = function (casper) {
try {
casper.echo('SCROLL!!');
casper.scrollToBottom();
if (casper.exists('div.loading')) {
var curItems = casper.evaluate(getCurrentInfosNum);
casper.echo(curItems);
casper.waitFor(function check() {
return curItems != casper.evaluate(getCurrentInfosNum);
}, function then() {
casper.wait(800);
tryAndScroll(casper);
}, function onTimeout() {
casper.emit('scroll.timeout',curItems);
}, 15000);
} else {
casper.echo("No more items");
return true;
}
} catch (err) {
casper.echo(err);
}
} //casper.tryAndScroll
And now, I want to continue to scroll many times when the timeout function invoked so I create my own event listener,‘scroll.timeout’.
var SRCOLL_NUM = 0;
var PreOfLoaded = 0;
casper.on('scroll.timeout', function (NumOfLoaded) {
if (SRCOLL_NUM <= 4) {
if (PreOfLoaded == NumOfLoaded)
SRCOLL_NUM++;
this.echo("Scroll Timeout,reScroll");
PreOfLoaded = NumOfLoaded;
tryAndScroll(casper);
} else {
this.echo("Scroll Timeout,reScroll times maximum");
SRCOLL_NUM = 0;
PreOfLoaded = 0;
}
});
However, when scroll timeout occurred, it printed Scroll Timeout,reScroll on the console. Then it skips tryAndScroll() and go to the next step in the main function. I want to continue to next step after retry scroll many times. What should I do?
I found CasperJS author illustrate :Automatic retry when open fails
var casper = require('casper').create();
casper.tryOpen = function(url, then) {
return this.then(function() {
this.open(url);
this.waitFor(function testStatus() {
return this.getCurrentHTTPStatus === 200;
}, then, function onFail() {
console.log('failed, retrying');
this.tryOpen(url);
}, 2000);
});
};
casper.start().tryOpen('http://failing.url.com/foo.bar', function() {
this.echo('wow, it worked, wtf');
}).run();
unfortunately, it doesn't work for me.
Try this
return this.currentHTTPStatus === 200;
I tested with the newest version of casperjs 1.1.1, it's working fine
Please See the below code runs at the rate of 60 frame per second..If any button is clicked isjump will be set to true and below code start excuting.What i am trying is i need to exit out jump() function after 1 second.I tried setout like below...but still lines inside settime out is running indefinitely..Please help me.
What i am actually trying is exit jump function after 1 second.
function jump() {
if (isjump) {
player.posx +=10;
console.log("jumping"); //this line is stopped after 1 second
setTimeout(function () {
isjump = false;
console.log("stopped"); //but this line is continuing
}, 1000);
}
}
I also tried clearTimeout still no use.
var timeoutHandle = window.setTimeout(function () {
isjump = false;
console.log("stopped");
clearTimeout(timeoutHandle);
}, 500);
Edit : For those who think this jump function is called continously...yea it is called continously...For every frame game character position will be updated.
Ok I found The solution..I solved it by running the settimeout function only once inside a loop.
var once = true;
function jump() {
if (isjump) {
player.posx +=10;
console.log("jumping"); //this line is stopped after 1 second
if(once)
{
setTimeout(function () {
isjump = false;
console.log("stopped"); //but this line is continuing
}, 1000);
}
once = false;
}
}
I have an image gallery that rotates through the rotator class divs on www.creat3dprinters.com that pauses on mouseenter and then fires again 1 second after mouseleave.
However, if a user moves the mouse in and out of the rotator class div quickly the function calls stack up and the visible changes until the 'stack' is completed.
I want the 1 second delay that has not been completed to be cancelled on the 2nd and subsequent mouseenter so that this does not happen.
I have tried using clearTimeout within the mouseenter function but it does not seem to work.
I know there is also the stop() function but that did not work either.
Any suggestions greatly appreciated.
jQuery(document).ready(function () {
var initList = setInterval('RotateIt()', 4000);
$('.rotator').mouseenter(function () {
clearInterval(initList);
}).mouseleave(function () {
timeout = setTimeout(function () {
RotateIt()
}, 1000);
initList = setInterval('RotateIt()', 4000);
})
});
function RotateIt() {
clearTimeout(timeout);
if ($('#rotator-visible').next('.rotator').length == 0) {
$('.rotator:first').attr('id', 'rotator-visible');
$('.rotator:last').removeAttr("id");
} else {
$('#rotator-visible').removeAttr("id").next('.rotator').attr("id", "rotator-visible");
}
}
If a user moves the mouse in and out of the rotator class div quickly the function calls stack up
Then clearTimeout it - and in exactly that place, not only in the delayed RotateIt. The simplest solution would be to call clearTimeout every time before setTimeout, so that you can be sure there is only one active timeout at once.
jQuery(document).ready(function($) {
var initList = setInterval(rotateIt, 4000),
delay = null;
$('.rotator').mouseenter(function(e) {
clearInterval(initList);
}).mouseleave(function(e) {
clearTimeout(delay);
delay = setTimeout(function () {
rotateIt();
initList = setInterval(rotateIt, 4000);
}, 1000);
})
});
function rotateIt() {
if ($('#rotator-visible').next('.rotator').length == 0) {
$('.rotator:first').attr('id', 'rotator-visible');
$('.rotator:last').removeAttr("id");
} else {
$('#rotator-visible').removeAttr("id").next('.rotator').attr("id", "rotator-visible");
}
}
I'm putting together some code to essentially replace the contents of a div when I mouseover a specific link. I then added the changer function to cycle through the content replacement automatically. I set flags for mouseover and mouseout and I can actually get the changer function to stop on mouseover but I can't quite figure out how to make it start up again on mouseout. Any advice is appreciated.
var pause=false;
$('.banner-nav a').mouseover(function () {
pause=true;
setFeature(this);
return false;
});
$('.banner-nav a').mouseout(function () {
pause=false;
});
changer(0, 5000);
function setFeature(f) {
var m = $(f).attr('rel');
$('.banner-nav a').not(f).removeClass('active');
$(f).addClass('active');
$('#featureContainer').html($(m).html());
}
function changer(index, interval) {
var buttons = $('.trigger'),
buttons_length = buttons.length;
var button = buttons.eq(index % buttons_length);
setFeature($(button));
setTimeout(function() {
if (!pause) {
changer(++index, interval);
}
}, interval)
}
The issue is that changer is responsible for its own delayed execution, but pausing it stops the scheduled execution. Another problem is that the next scheduled execution (if any) still happens after pausing.
Use setInterval instead of setTimeout. Instead of using a flag, clear the interval to pause and start it again to unpause.
(function() {
var index=0;
function changer() {
var buttons = $('.trigger'),
buttons_length = buttons.length;
var button = buttons.eq(index % buttons_length);
setFeature($(button));
++index;
}
var changerInterval,
period = 5000;
function startChanger() {
if (! changerInterval) {
changerInterval = setInterval(changer, interval);
}
}
function stopChanger() {
clearInterval(changerInterval);
changerInterval = 0;
}
$('.banner-nav a').mouseover(function () {
stopChanger();
setFeature(this);
return false;
});
$('.banner-nav a').mouseout(function () {
startChanger();
});
/* could implement other functions to e.g. change the period */
function setChangerPeriod() {
...
}
window.setChangerPeriod = setChangerPeriod;
...
})
I have a website which I would like to auto refresh ONLY if user is not using it for a specific time (ie.180 sec).Is there a way to auto refresh HTML only if there has been no activity on a page?
Thank you!
Two approaches:
1. Use a once-a-second timer and a "timeout" value.
You probably want to wrap this up in an object:
var activityHandler = (function() {
var timerHandle = 0,
timeout;
flagActivity();
function start() {
stop();
flagActivity();
timerHandle = setInterval(tick, 1000);
}
function stop() {
if (timerHandle != 0) {
clearInterval(timerHandle);
timerHandle = 0;
}
}
function flagActivity() {
timeout = new Date() + 180000;
}
function tick() {
if (new Date() > timeout) {
stop();
location.reload();
}
}
return {
start: start,
stop: stop,
flagActivity: flagActivity
};
})();
Then start it on page load:
activityHandler.start();
And ping it every time you see "activity":
activityHandler.flagActivity();
So for instance, you might do this:
if (document.addEventListener) {
document.addEventListener('mousemove', activityHandler.flagActivity, false);
}
else if (document.attachEvent) {
document.attachEvent('onmousemove', activityHandler.flagActivity);
}
else {
document.onmousemove = activityHandler.flagActivity;
}
2. Use a timer you reset every time there's "activity".
This is less ongoing work (we don't have something happening every second), but more work when you flag that activity has happened.
Set up a timer to do the refresh:
var handle = setTimeout(function() {
location.reload();
}, 180000);
...and then cancel and reschedule any time you see whatever you consider to be "activity":
clearTimeout(handle);
handle = setTimeout(...);
You can wrap this up in a function:
var inactivityTimerReset = (function() {
var handle = 0;
function reset() {
if (handle != 0) {
clearTimeout(handle);
}
handle = setTimeout(tick, 180000);
}
function tick() {
location.reload();
}
return reset;
})();
// Kick start
inactivityTimerReset();
// ...and anywhere you see what you consider to be activity, call it
// again
inactivityTimerReset();
Then, again, ping it on every activity. But this is a lot more work than I'd put in a mousemove handler, hence solution #1 above.
var docTimeOut;
function bodyTimeOut()
{
docTimeOut=setTimeout(function(){location.reload();},18000);
}
function resetTimeOut()
{
clearTimeout(docTimeOut);
bodyTimeOut();
}
document.onload = bodyTimeOut;
document.body.onmouseover= resetTimeOut;
you could declare a variable pageActive or something, set it to false, and whenever user does something set it to true.
Then, set a function to execute periodically as frequently as you want with setinterval() that checks this variable, if it's true set it to false to start again, if is false then refresh page.
You can use onblur and onfocus on body element to see if there is a kind of activity on your page.