Jquery Scroll to bottom in Firefox AND Chrome - javascript

function run_battle() {
if(battlenow.length>0) {
var div = document.getElementById('show_battle');
$("#show_battle").animate({ scrollTop: $("#show_battle").prop("scrollHeight") - $('#show_battle').height() }, 100);
var attempt = battlenow.shift();
div.innerHTML += attempt;
$("#show_battle").animate({ scrollTop: $("#show_battle").prop("scrollHeight") - $('#show_battle').height() }, 100);
setTimeout("run_battle()",800);
}
}
This is what I have so far. It works great in firefox. Yet in Chrome, it doesn't work at all. I'm using Jquery 1.7.1, So that's why I'm using .prop instead of .attr.
The battlenow array is like this.
battlenow.push('Alan hit Joe<br><br>');
battlenow.push('Joe fainted<br><br>Battle Over');
If that helps any.
Thank you.

Here's the code that I use that works in all browsers to scroll to a particular element. This code scrolls the minimal amount to get the element on screen, you might want something different. Note the check for webkit browsers:
(function($) {
$.fn.scrollMinimal = function() {
var cTop = this.offset().top;
var cHeight = this.outerHeight(true);
var windowTop = $(window).scrollTop();
var visibleHeight = $(window).height();
if (cTop < windowTop) {
$(jQuery.browser.webkit ? "body": "html")
.animate({'scrollTop': cTop}, 'slow', 'swing');
} else if (cTop + cHeight > windowTop + visibleHeight) {
$(jQuery.browser.webkit ? "body": "html")
.animate({'scrollTop': cTop - visibleHeight + cHeight}, 'slow', 'swing');
}
};
}(jQuery));
Called like:
$('#actions').scrollMinimal();

Related

How to control the speed of js nav scrolling

Hey Guys I found this really useful java script sticky side nav, and it works great! I don't much about js, i was just wondering if there was away to slow down the scrolling?
function redrawDotNav(){
var topNavHeight = 50;
var numDivs = $('section').length;
$('#dotNav li a').removeClass('active').parent('li').removeClass('active');
$('section').each(function(i,item){
var ele = $(item), nextTop;
console.log(ele.next().html());
if (typeof ele.next().offset() != "undefined") {
nextTop = ele.next().offset().top;
}
else {
nextTop = $(document).height();
}
if (ele.offset() !== null) {
thisTop = ele.offset().top - ((nextTop - ele.offset().top) / numDivs);
}
else {
thisTop = 0;
}
var docTop = $(document).scrollTop()+topNavHeight;
if(docTop >= thisTop && (docTop < nextTop)){
$('#dotNav li').eq(i).addClass('active');
}
});
}
$('#dotNav li').click(function(){
var id = $(this).find('a').attr("href"),
posi,
ele,
padding = $('.navbar-fixed-top').height();
ele = $(id);
posi = ($(ele).offset()||0).top - padding;
$('html, body').animate({scrollTop:posi}, 'slow');
return false;
});
demo
The line in your JavaScript code doing that is this:
$('html, body').animate({scrollTop:posi}, 'slow');
You can change the 'slow', to 'fast', and see the difference.
Learn more about the animate function here.
You can precisely control the speed on animate with duration. Here is the function signature:
animate(params, [duration], [easing], [callback])
The strings fast and slow can be supplied to indicate durations of 200ms and 600ms, respectively. The default speed is 400ms. You can adjust your speed by replacing nnn with the exact speed in milliseconds you want.
$('html, body').animate({scrollTop:posi}, nnn);

section snap to window (firefox issue)

I have written a simple custom section snapping script, works great in chrome and safari, but after nothing happens in firefox...
What it is does:
When scrolling stops it checks the direction and location of each secrion... if the top of a section is within a certain range either go to the top of the page or bottom. (scroll directions is also checked). Also, it accounts for the height of a fixed header. Like I said works in Chrome and Safari. Any ideas what's wrong?
$( document ).ready(function() {
var animating = false;
var mainHeader = $('#main-header');
var items = $("section");
var lastOffset = 0;
var scrollDir = 'none';
$(window).scroll(function() {
var windowHeight = $(this).height();
var currOffset = $(this).scrollTop();
var headerHeight = mainHeader.outerHeight();
if (currOffset > lastOffset) {
scrollDir = 'down';
} else {
scrollDir = 'up';
}
lastOffset = currOffset;
clearTimeout($.data(this, 'scrollTimer'));
if (!animating) {
$.data(this, 'scrollTimer', setTimeout(function() {
items.each(function(key, value) {
var currentItem = $(value);
var sectionOffset = currentItem.offset().top;
var sectionDist = sectionOffset - currOffset;
if ( scrollDir === 'up' && sectionDist > windowHeight*0.15 && sectionDist < windowHeight ) {
animating = true;
$('body').animate( { scrollTop: sectionOffset-windowHeight + 'px' }, 250);
setTimeout(function() { animating = false; }, 300);
return false;
}
else if ( scrollDir === 'down' && sectionDist < windowHeight*0.85 && sectionDist > 0 ) {
animating = true;
$('body').animate( { scrollTop: sectionOffset-headerHeight + 'px' }, 250);
setTimeout(function() { animating = false; }, 300);
return false;
}
});
}, 200));
}
});
});
Found the answer here...
Animate scrollTop not working in firefox
Firefox places the overflow at the html level, unless specifically styled to behave differently.
To get it to work in Firefox, use
$('body,html').animate( ... );

Firing an animation when aligned

I am creating a splitscrolling website and it's working great. But i have one problem, when the user stops scrolling it fires a function called alignWhenIdle and what this does is align the columns so they become "one".
Now that is working nicely but i can't seem to target a specific part of the column that aligns. let's say when the number 2 column aligns ( see image ) i want to be able to fire an animation. I tried using a callback but that fires a function every time the columns are aligned.
This is my JS:
(function ($) {
var top = 0;
var contentHeight, contents, totalHeight;
var locked = false;
var timeout;
var align = function () {
var pos = (top + $(window).scrollTop());
var snapUp = 0 - (pos % contentHeight) < (contentHeight / 2);
var multiplier = snapUp
? Math.ceil(pos / contentHeight)
: Math.floor(pos / contentHeight);
var newTop = contentHeight * multiplier;
$('html, body').animate({ scrollTop: newTop + totalHeight }, 200);
locked = false;
};
var reset = function () {
contentHeight = $('.right').height();
contents = $('.right > .content').length;
totalHeight = contentHeight * (contents - 1);
top = (0 - totalHeight);
};
var scrollRight = function () {
$('.right').css('top', (top + $(window).scrollTop()) + 'px');
};
var alignWhenIdle = function (delay) {
clearTimeout(timeout);
timeout = setTimeout(align, delay);
};
$(document).on('ready', function () {
reset();
scrollRight();
});
$(window).on('scroll', function () {
locked = true;
scrollRight();
});
$(window).on('mouseup', function (e) {
if (locked) {
align();
}
});
$(window).resize(function () {
locked = true;
reset();
scrollRight();
alignWhenIdle(300);
});
$(window).on('mousewheel', function (e) {
alignWhenIdle(300);
});
$(window).on("keyup", function (e) {
alignWhenIdle(300);
});
})(jQuery);
http://jsfiddle.net/ev3B8/
Any help is much appreciated,
Cheers
See http://jsfiddle.net/5T9Y8/
Scroll till the column 2 and see result...
In the method align I've added a callback:
$('html, body').animate({ scrollTop: newTop + totalHeight }, 200, function(){
$(".animate").animate({ marginLeft: "200px" },300);
});
Works well, did you need exactly that?
EDIT
You should just check for some condition.
E.g. based on this solution Check if element is visible after scrolling you can build this:
$('html, body').animate({ scrollTop: newTop + totalHeight }, 200, function(){
if (isScrolledIntoView(".animate")) $(".animate").animate({ marginLeft: "200px" },300);
});
See updated solution here http://jsfiddle.net/5T9Y8/1/
This is only one way, I'm really sure there is a way to do it even better. E.g. you can calculate the current elements which are shown and then just find the things only inside of them.
I tried using a callback but that fires a function every time the columns are aligned.
Use one method for functioning only once instead of on.

How to make the scrolling script efficiently?

I have div element inside that I have a list of(ol) elements. I use drag and drop using jquery nestable. Please look at the issue here (How to scroll the window automatically when mouse moves bottom of the page using jquery).
I used to get the visible <li> in current view, using view-port(plugin - http://www.appelsiini.net/projects/viewport).
I used the below script. I couldn't scroll the page more efficient and
script doesn't work in FF (scrolling does not work).
if ($('.dd-dragel').length > 0) {
var totalVisibleLi = $('#ol_id li:visible').length;
var liInViewPort = $('#ol_id li:in-viewport').length;
var closestLi = $(this.placeEl).prev('li');
var items = $('#ol_id li:in-viewport');
var indexOfClosestLi = items.index(closestLi);
if (indexOfClosestLi >= (liInViewPort - 3) && (e.pageY < $('#div_id').height())) {
$('body').animate({
scrollTop: $(window).scrollTop() + 200
}, 1);
}
if (indexOfClosestLi <= 3) {
$('body').animate({
scrollTop: $(window).scrollTop() - 200
}, 1);
}
}
What am I missing here?
Edited your code. Now scroll also work in FF
if ($('.dd-dragel').length > 0) {
var totalVisibleLi = $('#ol_id li:visible').length;
var liInViewPort = $('#ol_id li:in-viewport').length;
var closestLi = $(this.placeEl).prev('li');
var items = $('#ol_id li:in-viewport');
var indexOfClosestLi = items.index(closestLi);
if (indexOfClosestLi >= (liInViewPort - 3) && (e.pageY < $('#div_id').height())) {
$('html,body').animate({
scrollTop: $(window).scrollTop() + 200
}, 400);
}
if (indexOfClosestLi <= 3) {
$('html,body').animate({
scrollTop: $(window).scrollTop() - 200
}, 400);
}
}

jQuery breaking in Firefox but no other browser

I have the following code which works fine in all browsers including Firefox:
var top;
var imageHeight;
function upFunction() {
top = parseInt($(".feature img").css("top"));
imageHeight = $(".feature img").height();
if (top > (imageHeight - 335) * -1) {
$(".feature img").css("top", top - 1 + "px");
$("#topPos").val(top - 1);
}
};
$(document).ready(function() {
$("a#up").mousedown( function(e) {
e.preventDefault();
upFunction();
timeoutId = setInterval( upFunction, 100 );
}).bind('mouseup mouseleave', function() {
clearInterval(timeoutId);
});
});
However there's obviously something else in my page which is causing this not to work in firefox and I can't work it out.
Is there any way I can fond out what's causing it to break without removing everything from the page to find out what it is?
EDIT:
OK, with the help of Jai's answer, it appears that a small tweak to my code makes it work in Firefox. Here's what I did:
function upFunction() {
var top = parseInt($(".feature img").css("top"));
var imageHeight = $(".feature img").height();
if (top > (imageHeight - 335) * -1) {
$(".feature img").css("top", top - 1 + "px");
$("#topPos").val(top - 1);
}
};
and remove the 2 variables from the global scope. Not sure why it made a different but it did.
Try these fixed variable declarations:
function upFunction() {
var img = $(".feature img"),
top = parseInt(img.css("top"));
if (top > (335 - img.height())) {
img.css("top", top - 1 + "px");
$("#topPos").val(top - 1);
}
};
$(document).ready(function() {
var timeoutId;
$("a#up").mousedown( function(e) {
e.preventDefault();
upFunction();
timeoutId = setInterval( upFunction, 100 );
}).bind('mouseup mouseleave', function() {
clearInterval(timeoutId);
});
});
On your actual question: Debug your script via inspecting it in the developer tools (Firebug).
You should try this one:
function upFunction(top, imageHeight) {
if (top > (imageHeight - 335) * -1) {
$(".feature img").css("top", top - 1 + "px");
$("#topPos").val(top - 1);
}
}
$(document).ready(function() {
var top = parseInt($(".feature img").css("top"));
var imageHeight = $(".feature img").height();
$("a#up").mousedown( function(e) {
e.preventDefault();
upFunction(top, imageHeight);
timeoutId = setInterval(function(){
upFunction(top, imageHeight);
}, 100);
}).bind('mouseup mouseleave', function() {
clearInterval(timeoutId);
});
});
Don't use top as a var name in global scope, it's already used.
Try typing console.log(top) or alert(window.top) into your browser's console for reference.

Categories