Jquery - Choppy animations in IE scrolling - javascript

So I have a toolbar that is on the left side of my page that I have animating when the user scrolls to stay focused on the top of the page. It works perfectly in every browser except IE. In IE, it appears to almost do it twice. It bounces around and is very strange. This is my code.
$(window).scroll(function () {
var windowScrollPosition = $(window).scrollTop(),
toolbarLocation = toolbar.offset().top + toolbar.height(),
canvasSize = formCanvas.offset().top + formCanvas.height();
//Give toolbar a new position relative to container
if ((toolbarLocation + windowScrollPosition) < canvasSize + toolbarLocation) {
toolbar.animate({'margin-top': (windowScrollPosition - 95) <= 0 ? windowScrollPosition : (windowScrollPosition - 95) + 'px'}, 65);
}
});
any thoughts on how to fix this in IE? Thanks!

Unless you want it to animate, i would use position: fixed to keep it there instead of animating it. That would probably fix your problem at least.

Related

Parallax - help making vertical position start at 200px rather than 0px

I'm using a precoded Parallax JQuery as part of a Wordpress theme called Parallax by Studiopress. It works fairly well, but I end up missing the top half of the image when scrolling and I'd like the user to be able to see that as well when they scroll down. Currently, the background-position starts at "50% 0px" and the px goes into negative figures when you scroll the page. I figure if I set it to start at 200 or 300px the majority of the image can be viewed. However, I can't set the CSS as that gets overridden by JQuery.
I'm fairly new to JQuery so I'm wondering if there's any pointers or method that can be given to help me?
This is the code :
jQuery(function ($) {
// Enable parallax and fade effects on homepage sections
$(window).scroll(function () {
scrolltop = $(window).scrollTop()
scrollwindow = scrolltop + $(window).height();
$(".home-section-2").css("backgroundPosition", "50% " + -(scrolltop / 6) + "px");
if ($(".home-section-4").length) {
sectionthreeoffset = $(".home-section-4").offset().top;
if (scrollwindow > sectionthreeoffset) {
// Enable parallax effect
backgroundscroll = scrollwindow - sectionthreeoffset;
$(".home-section-4").css("backgroundPosition", "50% " + -(backgroundscroll / 6) + "px");
}
}
})
});
For the top image - change scrolltop to scrolltop = $(window).scrollTop() + -1000 The larger the number makes the starting px larger as well.
Every other image requires a duplicate of scrolltop called scrolltop2 which does not contain the number. This is referred to in scrollwindow.
scrolltop2 = $(window).scrollTop()
scrollwindow = scrolltop2 + $(window).height();
Then add the number to backgroundscroll
eg: backgroundscroll = scrollwindow - sectionthreeoffset + -1500;

DOM element position slow while scrolling + difference between scrollbar-scrolling and mouse/touchpad-scrolling

I'm having a little problem with Safari - When i want to update a DOM element's position on scroll event, Safari seems not to catch up with the changes (resulting in a jumpy lag effect).
I checked it on other browsers (Chrome, FF, IE8+) and this seems to be specific to Safari.
I made a jsfiddle to illustrate my problem:
$("#container").on("scroll", function() {
$("#slide").css({
left: $("#container").scrollLeft() + "px"
});
var leftPos = 0;
for(var i = 0; i < 2000 ; i++) {
leftPos = $("#slide").css("left");
}
$("#info").text(leftPos);
});
http://jsfiddle.net/a4b86et3/2/
As you can see, I added an additional loop of DOM reading on each scroll to simulate "more operations going on" on each event occurrence, as this mechanism is a part of a bigger project, which contains many other DOM operations. (Notice, that this example works smooth everywhere except Safari)
Also, i used jQuery just for the convenience, the actual project uses pure js.
I managed to partially fixed the issue
by changing the left = x property to transform = translate3d(x,0,0), so the browser would use the GPU.
$("#container").on("scroll", function() {
$("#slide").css({
'-webkit-transform': 'translate3d(' + $("#container").scrollLeft() + 'px, 0, 0)'
});
var leftPos = 0;
for(var i = 0; i < 1900 ; i++) {
leftPos = $("#slide").css("left");
}
$("#info").text(leftPos);
});
http://jsfiddle.net/a4b86et3/3/
However, sometimes I'm still experiencing a slight lag/glitching while scrolling.
But, what's more important, this fix doesn't affect the scrolling, when I'm using a mouse scroll or touchpad! While dragging the scrollbar works way better, using any of the above brings me back to my initial problem.
Any ideas why this happens and how to fix it?
tl;dr; - Safari is slow when changing element position on scroll; translate3d seems to not work properly when using mouse scroll/touchpad.
I had the exact same issue, and it took me some time to figure out the fix. Here is an updated jsfiddle showing you how to resolve the issue in Safari: http://jsfiddle.net/a4b86et3/4/
function handle_scroll() {
$("#slide").css({
'-webkit-transform': 'translate3d(' + $("#container").scrollLeft() + 'px, 0, 0)'
});
var leftPos = 0;
for(var i = 0; i < 1900 ; i++) {
leftPos = $("#slide").css("left");
}
$("#info").text(leftPos);
}
$("#container").on("scroll", handle_scroll);
$("#container").on('mousewheel', function(e) {
e.preventDefault()
var maxX = this.scrollWidth - this.offsetWidth
var maxY = this.scrollHeight - this.offsetHeight
this.scrollTop = Math.max(0, Math.min(maxY, this.scrollTop - e.originalEvent.wheelDeltaY))
this.scrollLeft = Math.max(0, Math.min(maxX, this.scrollLeft + e.originalEvent.wheelDeltaX))
handle_scroll(e)
})
In brief: if you handle the mousewheel event yourself, calculate the correct scroll values there, and then call your handler code, things start working.
I'm not sure why Safari makes you jump through this hoop, but luckily the fix isn't too involved.
Hope this helps.

iOS7 on "touchmove", prevent fixed element going negative?

I have a fixed row of indicators (slider-indicators) that when it reaches the bottom bound, it should sit on top of the footer. On the desktop everything works fine, and I know that on iOS the scrolling freezes the DOM manipulation.
So I tried using on('touchmove') event, which does a decent job, but when the user scrolls up the page on iOS, moving the website itself up (and revealing the blank/grey/ background), the fixed element moves with it also.
I'm try to disable this feature, and usually works with removing the touch event off('touch'), but how would I rebind it again, so that the DOM manipulation works as the user scrolls?
This is what code I have:
$(window).on('touchmove',moveIndicators);
$(window).scroll(moveIndicators);
function moveIndicators() {
var d = $(document).height(),
w = $(window).height(),
s = $(this).scrollTop(),
bottomBound = (navigator.userAgent.match(/(iPhone);.*CPU.*OS 7_\d/i)) ? 119 : 50;
$location = $('.location-nav');
if(d - (w + s) <= bottomBound) {
$location.css({ bottom: bottomBound - (d - (w + s)), 'margin-bottom': '0px' });
} else {
$location.css({ bottom: 0, 'margin-bottom': '0px' });
}
}

Strange JavaScript scroll in firefox

I have build a website just to try out some off my ideas and to learn. I found a problem when I tested it in firefox. I made a scroll function which scrolls the page when an image reach a specific position. the image moves by arrow keys. It works great in IE9 and Chrome, but in firefox the page scrolls when I enter an arrow key. I thought it was becuase of the the page up, page down, home and end navigation on the arrowKeys, but if I disable the navigation by arrowkeys in firefox, the problem still ocures.
The scroll function:
function scrollPage() {
if(xpos > scrollPosX[scrolledX + 1]) {
scrolledX++;
window.scroll(scrollPosX[scrolledX],scrollPosY[scrolledY]);
}
if(xpos < scrollPosX[scrolledX] - ufoWidth) {
scrolledX--;
window.scroll(scrollPosX[scrolledX],scrollPosY[scrolledY]);
}
if(ypos > scrollPosY[scrolledY + 1]) {
scrolledY++;
window.scroll(scrollPosX[scrolledX],scrollPosY[scrolledY]);
}
if(ypos < scrollPosY[scrolledY] - ufoHeight) {
scrolledY--;
window.scroll(scrollPosX[scrolledX],scrollPosY[scrolledY]);
}
info5.html('scrolledX: ' + scrolledX + '<br />scrolledY: ' + scrolledY + '<br />scrollPosX: ' + scrollPosX[scrolledX] + '<br />scrollPosY: ' + scrollPosY[scrolledY]);
scrollLoop = setTimeout(scrollPage, 100);
}
xpos and ypos are the left and top positions of the image.
scrollPosX and scrollPosY are arrays containing the positions to
scroll to.
scrolledX and scrolledY are for counting the scrolls.
Here is a demo I uploaded. for the full code please lookup the page source: http://www.mikeywebs.nl/
I hope someone can tell me how to solve this. Some commentary on my code is also welcome cause im still learning.
Thanx.
In your demo's code, there is nothing preventing the scroll event to fire. Try this near line 96 in the inline JS code:
$(document).keydown(function(e){
e.preventDefault(); // Add this
var code = e.keyCode;
switch (code) {
For further info here on SO about preventing scrolling:
How to disable scrolling.

Javascript dialog is programmed to move when the page scrolls, but it flickers. Can this be fixed?

I've written some jQuery code to display a box with data in the corner of the users' web browser. I'm using the .scroll event to make the box stay in the corner as the user scrolls up and down the page. Let me emphasize that I am not using jquery-ui dialog.
The only problem is that the box flickers as the page scrolls. I'm afraid that there will be no cross-browser solution to this problem as the different browsers seem to behave differently with scrolling. Barring a cross-browser solution, an IE solution would be nice (My web application is designed to be used by a specific group of about 100 users in my organization.)
Here are snippets of the relative code:
ExternalScroll: function () {
LittleBlackBook.setPosition();
}
setPosition: function () {
var scrollPosition = $(self).scrollTop();
var cssTop = LittleBlackBookStatic.determineCssTop(this.height, this.isTop, this.vOffset, scrollPosition);
var cssHeight = LittleBlackBookStatic.determineCssHeight(this.height);
var cssLeft = LittleBlackBookStatic.determineCssLeft(this.width, this.isLeft, this.hOffset);
var cssWidth = LittleBlackBookStatic.determineCssWidth(this.width);
this.jQueryObj.css('top', cssTop);
this.jQueryObj.css('height', cssHeight);
this.jQueryObj.css('left', cssLeft);
this.jQueryObj.css('width', cssWidth);
}
var LittleBlackBookStatic = {
determineCssTop: function (height, isTop, vOffset, vScroll) {
var windowHeight = $(self).height();
var scrollPosition = $(self).scrollTop();
var newModalTop = isTop ? vOffset + vScroll : windowHeight - height + vScroll - vOffset;
return newModalTop + 'px';
},
determineCssHeight: function (height) {
return height + 'px';
},
determineCssLeft: function (width, isLeft, hOffset) {
var windowWidth = $(self).width();
var newModalLeft = isLeft ? hOffset : windowWidth - width - hOffset;
return newModalLeft + 'px';
},
determineCssWidth: function (width) {
return width + 'px';
}
} // end LittleBlackBookStatic
I'm using jQuery to look up the scroll position as the page scrolls and change the CSS.
Is there a better way; a way that will make it scroll without flickering? If no, then why not?
You should use fixed positioning for that box instead instead of animating it to keep it in the corner.
You'll use less javascript and avoid flickering that comes with animation.

Categories