I'm working with this slider, all works great but why on small screen
(less than 480) or on responsive view it don't run?!
how can i fix this problem?!
More details in the fiddle below
http://jsfiddle.net/roXon/tMxp5/1/
$(function() {
var c = 1,
timeOut,
fit,
isStopped = false,
boxw = $('.box').outerWidth(true),
boxh = $('.box').outerHeight(true),
boxn = $('.box').length;
$('#slider').width(boxw*boxn);
$('#gal, #slider').height(boxh);
//////////////////////////////////
function measure() {
var winw = $(window).width();
fit = Math.ceil(winw/boxw)-1; // math ceil -1 to get the number of COMPLETELY visible boxes
$('#gal').width(winw);
$('#t').html('Boxw='+boxw+' Boxh='+boxh+' Winw='+winw+' VisibleBoxes='+ fit);
}
measure();
$(window).resize(function() {
measure();
});
//////////////////////////////////
function b(){
cc = (c === 1) ? $('.prev').hide() : $('.prev').show();
ccc =(c >= boxn/fit) ? $('.next').hide() : $('.next').show();
}
$('.btn').hide();
/////////////////////////////////
function a(cb){
$('#slider').animate({left: '-'+ (boxw*fit)*(c-1) },800, cb);
}
////////////////////////////////
function auto() {
if(isStopped){ return };
clearTimeout(timeOut);
timeOut = setTimeout(function() {
$('.btn').hide();
c++;
if (c >= (boxn/fit)+1) {
c = 1;
}
a(function(){
auto();
});
}, 2000);
}
auto();
/////////////////////////////////////////////////////////////////
$('.next').click(function() {
c++;
b();
a();
});
$('.prev').click(function() {
c--;
b();
a();
});
/////////////////////////////////////////////////////////////////
$('#gal').bind('mouseenter mouseleave', function(e) {
( e.type === 'mouseenter' ) ?
( isStopped=true, b(), clearTimeout(timeOut) ) :
( isStopped=false, auto() );
});
});
thank you
It's because your measure function set the number of visible boxes to 0
try changing the measure function to:
function measure() {
var winw = $(window).width();
fit = Math.ceil(winw/boxw)-1; // math ceil -1 to get the number of COMPLETELY visible boxes
$('#gal').width(winw);
if (fit == 0) fit = 1;
$('#t').html('Boxw='+boxw+' Boxh='+boxh+' Winw='+winw+' VisibleBoxes='+ fit);
}
And it should fix your problem: http://jsfiddle.net/tMxp5/270/
Related
I have a function that will perform an action when the timer reaches 5000ms:
var timer = new Timer(function () {
console.log("refreshingBid");
refreshBid();
}, 5000);
timer.pause();
if (isElementInViewport() === true) {
console.log("element in view");
timer.resume();
} else {
timer.pause();
console.log("element is out of view")
}
//I am trying to loop this 5 times with the 5000ms delay - the code I am using for this is:
for (i=0;i<=5;i++)
{
MyFunc();
}
It seems regardless of whether I put the for loop in the timer or whether I put the timer inside the for loop the result is the same where all 5 loops happen instantaneously instead of with a delay of the timer being applied? I'm not sure what i'm doing wrong here... Any help would be appreciated!
Sorry, edit to include the complete code below:
<script>
var iframe2 = document.getElementById('postbid_if');
function isElementInViewport() {
var el = document.getElementById('postbid_if')
console.log(el)
var rect = el.getBoundingClientRect();
console.log(rect)
return rect.bottom >= 0 &&
rect.right >= 0 &&
rect.left < (window.innerWidth || document.documentElement.clientWidth) &&
rect.top < (window.innerHeight || document.documentElement.clientHeight);
}
function Timer(callback, delay) {
var timerId, start, remaining = delay;
this.pause = function () {
window.clearTimeout(timerId);
remaining -= new Date() - start;
};
this.resume = function () {
start = new Date();
window.clearTimeout(timerId);
timerId = window.setTimeout(callback, remaining);
};
this.resume();
}
for (i = 0; i <= 5; i++) {
MyFunc();
}
var timer = new Timer(function () {
console.log("refreshingBid");
refreshBid();
}, 5000);
timer.pause();
if (isElementInViewport() === true) {
console.log("element in view");
timer.resume();
} else {
timer.pause();
console.log("element is out of view")
}
</script>
It's because it's looping through quickly 5 times then all 5 loops are delaying after the 5 seconds. The timeout pauses it after 5 seconds, not for 5 seconds up front.
Perhaps you could revise your code in this way to achieve the timer based iterations as required:
//Track the current iteration
var i = 0;
function MyFunc() {
var timer = new Timer(function () {
console.log("refreshingBid");
refreshBid();
// The current timer has completed. If the current
// iteration is less than 5...
if(i < 5) {
i++;
// .. then start another timer for the next iteration
MyFunc();
}
}, 5000);
timer.pause();
if (isElementInViewport() === true) {
console.log("element in view");
timer.resume();
} else {
timer.pause();
console.log("element is out of view")
}
}
// Start the first iteration
MyFunc();
I have used the setTimeout function so my object stays on y<0 for a while and at that time i want to my increment to trigger only once but it keeps on triggering ...more i delay my function using the setTimeout function higher times the increment operation gets trigger......so what is the solution through which my increment triggers only once no matter how long my object stays in y<0
Player.prototype.checkInWater = function () {
if (this.y < 0) {
++scoreGot
setTimeout(function(){
player.x = 202;
nplayer.y = 405;
}, 300);
}
};
Player = function(){
....
this.checkedInWater = false;
}
Player.prototype.checkInWater = function () {
if (this.y < 0 && !this.checkedInWater) {
++scoreGot;
t = this;
t.checkedInWater = true;
setTimeout(function(){
player.x = 202;
nplayer.y = 405;
t.checkedInWater = false;
}, 300);
}
};
I have the below code:
var intervalId = "";
var isRunning = false;
var iCount = 0;
function animation() {
switch (iCount++ % 2) {
case 0:
$('.class1').removeClass("is-active");
$(".class2").addClass("is-active");
break;
case 1:
$('.class2').removeClass("is-active");
$(".class1").addClass("is-active");
break;
}
isRunning = true;
}
if (window.innerWidth > 1024) {
intervalId = setInterval(animation, 3000);
}
$(window).on("orientationchange resize", function () {
debounce(function () {
if (window.innerWidth < 1024) {
if (isRunning == true) {
clearInterval(intervalId);
isRunning = false;
}
} else if (window.innerWidth > 1024) {
if (isRunning == false) {
intervalId = setInterval(animation, 3000);
}
}
}, 250);
});
What I'm trying to get, is on a 1024+ screen the setInterval is fired, anything below 1024 isn't fired. But on resize to lower than 1024 the setInterval still being fired.
Any help would be greatly appreciated.
The isRunning logic is useless and redundant with intervalId being defined or not. You're using two variables for the same thing, and that's overkill.
Besides, you test window.innerWidth twice : is it <1024 or is it >1024 ? The second test is useless, and what happens if it's exactly 1024?
This block code makes things clearer and simpler :
debounce(function () {
if (window.innerWidth < 1024) {
clearInterval(intervalId);
} else {
if(!intervalId) intervalId = setInterval(animation, 3000);
}
})
I got it working by using this code for my resize function.
$(window).on("orientationchange resize", debounce(function () {
if (window.innerWidth < 1024) {
clearInterval(intervalId);
intervalId = "";
} else {
if (!intervalId) intervalId = setInterval(animation, 3000);
}
}));
I'm using the following code below, to scroll two divs in different directions () but I'm curious to know if you can limit the scroll so it only fires once per scroll (rather than it continually scrolling and sending my functions into an endless loop.
$('.page-left, .page-right').bind('mousewheel', function(event, delta) {
var windowHeight = $(window).height();
if (delta < 0) {
prevProject();
}
if (delta > 0) {
nextProject();
}
});
You can see where I'm up up to here: http://dev.rdck.co/lyonandlyon/
Thanks in advance,
R
Animation functions for reference:
var prevProject = function() { // up arrow/scroll up
var windowHeight = $(window).height();
$('.page-left .page-left-wrapper').css({bottom:'auto'});
$('.page-left .page-left-wrapper').animate({top:0},800, function() {
$('.page-left .page-left-wrapper').prepend($('.page-left .project-left:last-of-type'));
$('.page-left .page-left-wrapper').css({top:-windowHeight});
});
$('.page-right .page-right-wrapper').css({top:'auto'});
$('.page-right .page-right-wrapper').animate({bottom:+windowHeight*2},800, function() {
$('.page-right .page-right-wrapper').append($('.page-right .project-right:first-of-type'));
$('.page-right .page-right-wrapper').css({bottom:+windowHeight});
});
};
var nextProject = function() { // down arrow/scroll down
var windowHeight = $(window).height();
$('.page-left .page-left-wrapper').animate({top:0},800, function() {
$('.page-left .page-left-wrapper').prepend($('.page-left .project-left:last-of-type'));
$('.page-left .page-left-wrapper').css({top:-windowHeight});
});
$('.page-right .page-right-wrapper').animate({bottom:+windowHeight*2},800, function() {
$('.page-right .page-right-wrapper').append($('.page-right .project-right:first-of-type'));
$('.page-right .page-right-wrapper').css({bottom:+windowHeight});
});
};
You can just check for animation within the mousewheel function (demo)
$('.page-left, .page-right').on('mousewheel', function(event, delta) {
if ($('.page-left-wrapper, .page-right-wrapper').is(':animated') ) {
return false;
}
var windowHeight = $(window).height();
if (delta < 0) {
prevProject();
}
if (delta > 0) {
nextProject();
}
});
Update: we resolved to use debounce as the long scroll (sliding a finger down a touchpad) needed to be stopped (updated demo).
$(document).keydown( $.debounce( 250, function(e) {
switch (e.which) {
case 38: // up arrow
prevProject();
break;
case 40: // down arrow
nextProject();
break;
}
}) );
$('.page-left, .page-right').on('mousewheel', $.debounce( 250, function(event, delta) {
var windowHeight = $(window).height();
if (delta < 0) {
prevProject();
}
if (delta > 0) {
nextProject();
}
}) );
You can get around this problem with a flag. You can use a global flag isAnimating and set it to true, if you are currently animating the position of the divs of your website.
So the code can look something like this:
var isAnimating = false;
$('.page-left, .page-right').bind('mousewheel', function(event, delta) {
// if the div will be animated at this moment return
if(isAnimating) {
return;
}
var windowHeight = $(window).height();
if (delta < 0) {
prevProject();
}
if (delta > 0) {
nextProject();
}
});
var prevProject = function() {
isAnimating = true;
var oneIsDone = false,
finish = function() {
// if both animations are done, set the flag to false
if(oneIsDone) {
isAnimating = false;
}
// at least one is done...
oneIsDone = true;
};
// animate the previous project and set the flag to false (in the callback)
$('.page-left .page-left-wrapper').css({bottom:'auto'});
$('.page-left .page-left-wrapper').animate({top:0},800, function() {
$('.page-left .page-left-wrapper').prepend($('.page-left .project-left:last-of-type'));
$('.page-left .page-left-wrapper').css({top:-windowHeight});
finish();
});
$('.page-right .page-right-wrapper').css({top:'auto'});
$('.page-right .page-right-wrapper').animate({bottom:+windowHeight*2},800, function() {
$('.page-right .page-right-wrapper').append($('.page-right .project-right:first-of-type'));
$('.page-right .page-right-wrapper').css({bottom:+windowHeight});
finish();
});
};
var nextProject = function() {
// the same as in the prevProject function, but only in the other direction
};
I suggest to detect extremums to fire the function:
var mw1 = 0;
var mw2 = 0;
var lock;
$(document).bind('mousewheel', function(evt) {
var delta = evt.originalEvent.deltaY
if(((delta > 0 && delta < mw2 && mw2 > mw1) || (delta < 0 && delta > mw2 && mw2 < mw1)) && !lock){
console.log(mw1 + " " + mw2 + " " + delta)
// call some function here
lock = true;
window.setTimeout(function(){
lock = false;
},200)
}
mw1 = mw2;
mw2 = delta;
})
lock is actually should not be necessary but extremums sometimes are found more than once per scroll for some reason.
I wrote this javascript to make an animation. It is working fine in the home page. I wrote a alert message in the last.
If I go other then home page, this alert message has to come, but I am getting alert message, if I remove the function, alert message working on all pages, any thing wrong in my code?
window.onload = function(){
var yellows = document.getElementById('magazine-brief').getElementsByTagName('h2');
var signUp = document.getElementById('signup-link');
if (yellows != 'undefined' && signUp != undefined){
function animeYellowBar(num){
setTimeout(function(){
yellows[num].style.left = "0";
if(num == yellows.length-1){
setTimeout(function(){
signUp.style.webkitTransform = "scale(1)";
},num*250);
}
}, num * 500);
}
for (var i = 0; i < yellows.length; i++){
animeYellowBar(i);
}
}
alert('hi');
}
DEMO: http://jsbin.com/enaqu5/2
var yellows,signUp;
window.onload = function() {
yellows = document.getElementById('magazine-brief').getElementsByTagName('h2');
signUp = document.getElementById('signup-link');
if (yellows !== undefined && signUp !== undefined) {
for (var i = 0; i < yellows.length; i++) {
animeYellowBar(i);
}
}
alert('hi')
}
function animeYellowBar(num) {
setTimeout(function() {
yellows[num].style.left = "0";
if (num == yellows.length - 1) {
setTimeout(function() {
signUp.style.webkitTransform = "scale(1)";
},
num * 250);
}
},
num * 500);
}
DEMO 2: http://jsbin.com/utixi4 (just for sake)
$(function() {
$("#magazine-brief h2").each(function(i,item) {
$(this).delay(i+'00').animate({'marginLeft': 0 }, 500 ,function(){
if ( i === ( $('#magazine-brief h2').length - 1 ) )
$('#signup-link')[0].style.webkitTransform = "rotate(-2deg)";
});
});
});
For starters you are not clearing your SetTimeout and what are you truly after here? You have 2 anonymous methods that one triggers after half a second and the other triggers a quarter of a second later.
So this is just 2 delayed function calls with horribly broken syntax.
Edited Two possibilities, one fixes your current code... the latter shows you how to do it using JQuery which I would recomend:
var yellows, signUp;
window.onload = function(){
yellows = document.getElementById('magazine-brief');
if(yellows != null){
yellows = yellows.getElementsByTagName('h2');
}else{
yellows = null;
}
signUp = document.getElementById('signup-link');
if (yellows != null && signUp != null && yellows.length > 0)
{
for(var i = 0; i < yellows.length; i++)
{
animeYellowBar(i);
}
}
alert('hi');
}
function animeYellowBar(num)
{
setTimeout(function(){
yellows[num].style.left = "0";
if(num == yellows.length-1){
setTimeout(function(){
signUp.style.webkitTransform = "scale(1)";
},num*250);
}
}, num * 500);
}
The below approach is a SUMMARY of how to use JQuery, if you want to use JQuery I'll actually test it out:
//Or using JQuery
//Onload equivelent
$(function(){
var iterCount = 0,
maxIter = $("#magazine-brief").filter("h2").length;
$("#magazine-brief").filter("h2").each(function(){
setTimeout(function(){
$(this).css({left: 0});
if(iterCount == (maxIter-1))
{
setTimeout(function(){
signUp.style.webkitTransform = "scale(1)";
},iterCount*250);
}
}, iterCount++ * num );
});
});