I'm working on creating my own responsive JavaScript/jQuery slider. It seems to be working pretty awesome for the most part, however, when I click on the arrows or navigation circles the timeout / animations seem to bug out. It is not consistent. When the arrows/nav circles are clicked, it should just reset the timeout and go to the corresponding slide.
For example if you click on a nav circle when it gets to the last slide it quickly goes right back to the first slide without the 5000 pause.
Here is the fiddle with all the code: http://jsfiddle.net/23712cwb/2/
Why is the timing bugging out like that? How do I fix it? As you can see I added clearTimeout($timeout); to the top of the nextSlide() function, but that didn't totally resolve it and I'm unsure this is the correct approach to the problem. However, before I added this line of code it was even more buggy.
Also if anyone has any tips they can give me or suggestions on how to make this even better that would be awesome. I am not very familiar with jQuery plugins so I am just kind of winging it here.
I figured it out. This code was causing the issue:
$('.slider .slides li .caption, .slider .slide-arrows li, .slider .slide-nav').mouseout(function () {
$timeout = setTimeout(function () { nextSlide('right', $slides, $height, $caption_speed, $slide_speed, 'null'); }, $slide_speed);
});
So every time I took my mouse off of the arrows or nav or caption it was doubling up on executing the nextSlide function.
I removed that code and it's all gravy now.
Actually, your code doesn't work on Firefox, because he is less forgiving than Chrome about errors.
You should define the functions captionActive and nextSlide you use outside of $(document).ready block
With your example it gave me this error on the console :
captionActive is not defined
Working fiddle
Edit : I guess you should be careful with the scope of $timeout : as you use it in the block document.ready and in functions, you should make use of global variables and work with window.$timeout instead of $timeout
That might solve some of your problems.
Related
I have a test page to better explain my problem. I have several items on a list (they're images on the test page); when I click on one of them, a corresponding slideshow, using flexslider, sldes down.
The problem is that, on page load, the slideshow shows all slides at once, at a much smaller size than intended. But then, if I switch the focus from the window (i.e. switch between browser tabs or move to another program and come back), the slideshow is now working and the slides are the proper size. This happens in mobile devices too.
When I check with firebug, there's an element.style rule applying to ul.slides:
transform: translate3d(-89px, 0px, 0px);
Which hides one of the slides. Additionally, there's another rule for the list items inside ul.slides that gives them their initial width, which is not even the same for all sliders so I don't understand where it is coming from.
Can someone take a look and suggest a fix? I've tried overriding the element.style rule but so far unsuccessfully.
I think I've figured it out, in principal at least...
.flexslider{display:none;} seems throw off the re-size function of Flexslider.
You could just remove it, but that makes for some ugly loading.
To avoid said ugly loading I put together a quick, work-around- jsFiddle
$(document).ready(function(){
$(".flexslider").css('display','block').slideUp();
});
There's a still a quick glitch while loading, but hopefully it will at least steer you in the right direction.
Another method I played with a bit was to try and force the re-size function like so-
$(".client").click(function () {
$('.flexslider').resize(); // Problematic but promising
var project = this.id;
var project_id = '#' + project + '-project';
var elem = $(".flexslider:visible").length ? $(".flexslider:visible"): $(".flexslider:first");
elem.slideUp('slow', function () {
$(project_id).slideDown('slow');
});
});
This sort of solved the mini-picture issue, but was spotty at best.
I'm very confused with my current webpage: http://armandbakx.nl/ - (adjusted it, I'm not here for self-promotion).
The idea is that I have a couple of images on my page, which are clickable. Once clicked a scrollable container should pop up, showing more information and images.
So far, with the help of some great people here, I've managed to make the JavaScript work. The only problems I'm running into right now are that when I click an image, the entire 'back-page' shifts. I'm not sure what's causing this, and even more unsure how to solve it.
Secondly, when an image is clicked and the scrollable container 'hovers' over the main page, it seems that other images still respond to clicking.. I've already hammered the z-index up to ridiculous amounts but it still does this. I don't think this is a JavaScript issue, but can't fathom what causes this in the css.
Thirdly, when an .img is clicked, and you scroll through the content of the scrollable container, when you click back towards the main page, it often also ends up scrolled upwards or downwards. How do I prevent this from happening?
I hope it's somewhat comprehensible and I hope someone is willing to help me.
I have a codepen here with everything this page runs on at the moment, except for the images.
Codepen
$('img').on('click', show);
$('.overlay').on('click', hide);
function show(){
$('.scroll-container').eq($(this).parent().index()).addClass('show');
$('.content-container').addClass('no-scroll');
$('.overlay').addClass('opacity');
}
function hide() {
$('.scroll-container').removeClass('show');
$('.content-container').removeClass('no-scroll');
$('.overlay').removeClass('opacity');
}
I decided to just answer your third question, and this approach might prevent the other issues as well.
Inside of your show function, make the keep track of the position the browser was in when the content opened. Then, in your hide function, return the browser to that position. This should prevent your boxes from moving around.
Here is an example. I wrapped everything in an immediately-invoked function to prevent the variables from being globals.
(function(){
var currentTop = 0;
$('img').on('click', show);
$('.overlay').on('click', hide);
function show(){
currentTop = $(window).scrollTop();
$('.scroll-container').eq($(this).parent().index()).addClass('show');
$('.content-container').addClass('no-scroll');
$('.overlay').addClass('opacity');
}
function hide() {
$(window).scrollTop(currentTop);
$('.scroll-container').removeClass('show');
$('.content-container').removeClass('no-scroll');
$('.overlay').removeClass('opacity');
}
})();
I am having a problem with the SKrollr.js plugin for Parallax and smooth scrolling. Everything works fine except Bootstrap carousel's, and im sure any carousel for that matter. It's clearly a display:none problem when the plugin is setting itself up on load and can't see any of the .item classes. But I can't figure out how on earth to get Skrollr to see all of the slides/.item classes when it's rendering.
I even tried this kinda stuff. My Skrollr markup isn't the problem that code always works for me.
Skrollr Markup
data-10p-top-bottom="background-position-y: 100%;" data-bottom-top="background-position-y: 0%;"
CSS
.displaying {
display: block !important;
}
JS
var sk = skrollr.init({
forceHeight: false,
beforerender: function(data) {
$(".item").addClass('displaying');
},
render: function(data) {
$(".item").removeClass('displaying');
}
});
EDIT
I made a JSFiddle for it here or you can see it fullscreen for debugging here
Sorry I was being vague and general because I know my HTML is solid. Check the fiddle. The slider functions just fine it's Skrollr not being able to see the hidden slides at runtime that is the problem. I just need a better solution to solve this.
I'm guessing that you need to do a refresh since I notice it works if I resize the browser.
Try this code:
setTimeout(function () {
skrollr.get().refresh();
}, 0);
You can change the timeout to 1000 if necessary to ensure everything loads.
I have an image carousel built using knockout & jquery.
To animate the slides I really want to use CSS transitions and NOT jquery animate.
I have this nearly working but I have an issue.
In the code below, the 'slideRight' part doesn't work, however the else part works fine. What's happening is the transition to margin-left 0 is being skipped, even though the transition class has been added.
if (slideRight) {
$(requestedElement).insertBefore(currentElement);
slideContainer.css('margin-left', -$(self.carousel).width());
slideContainer.addClass('transition');
slideContainer.css('margin-left', 0);
} else {
$(requestedElement).insertAfter(currentElement);
slideContainer.addClass('transition');
slideContainer.css('margin-left', -$(self.carousel).width());
}
I've created a JSFiddle here: http://jsfiddle.net/vnw57nx0/2/
As you'll see in the fiddle, the carousel transitions nicely between slides going right to left.
But if you find this line in the javascript:
self.setIndex(self.currentIndex() + 1);
and change it to:
self.setIndex(self.currentIndex() - 1);
the slides should cycle in reverse.
They do, but they're not being animated.
Interestingly, if I debug the script and step through it works fine.
This made me think it was a timing issue and maybe I need to use a callback function but jquery .insertBefore, .css and .addClass are all synchronous.
Any ideas how I can fix this code that works if I debug but doesn't if I don't?
It seems that the browser doesn't make a transition when you revert a style value within the same context. You need to do it in a new context using something like setTimeout:
if (slideRight) {
$(requestedElement).insertBefore(currentElement);
slideContainer.css('margin-left', -$(self.carousel).width());
setTimeout(function() {
slideContainer.addClass('transition');
slideContainer.css('margin-left', 0);
});
} else {
http://jsfiddle.net/vnw57nx0/3/
I found this question because of the Knockout tag, and although you've got Knockout references in your question, the problem has nothing to do with Knockout. In fact, your code is very anti-Knockout since you're using jQuery selectors within your "view model" and using observables where none are needed or even useful.
This is certainly going to be an easy one but I can't get my head around what I am doing wrong...
I am trying to do a hover effect on a UL that affects a link within one of the UL LI's.
My current code looks like this:
$("ul.punchlines").hover(function () {
$(this).find("li a.light-grey-gradient").animate({'width' : '60%','top':'-65px'});
});
$("ul.punchlines").mouseleave(function () {
$(this).find("li a.light-grey-gradient").animate({'width' : '30%','top':'0px'});
});
This technically works as it gives the effect that the base of the element to be scaled remains in place and scales up from the bottom however it does it in two stages, I am trying to get this effect to happen all in one motion so it is a seamless scale and move.
I can do this easily with basic CSS3 transitions but as it is not supported in IE9 I am trying to use jQuery to allow for maximum browser support.
Can anyone offer a little support firstly about how I get the animation to happen in one motion (not staggered) and secondly if this is the right approach? I am new to jquery and only just getting my hands dirty with it :-)
Please see JQuery hover api:
http://api.jquery.com/hover/
also make sure that your "li" have absolute position.
$("ul.punchlines").hover(function () {
$(this).find("li a.light-grey-gradient").animate({'width' : '60%','top':'-65px'});
}, function () {
$(this).find("li a.light-grey-gradient").animate({'width' : '30%','top':'0px'});
});