JAVASCRIPT ONLY (no jquery) animated scrollTop in div - javascript

I am trying to animate a "scroll-to-top" button for a div with overflow set to auto (scrollbars are displayed as overflow exceeds div limits, so this is not an issue). On clicking the button i call a for loop in a javascript (not jquery) function. Each descending increment of the for loop (starting at the current element.scrollTop position) is to gradually back the scrolling down until element.scrollTop is 0. Very simple and straightforward in theory. Works like a dream in IE (very atypical!) but DOES NOT WORK in Firefox or Chrome!!!! All it does is JUMPS to the top...no smooth gradual scrolling upward which is what i want! Please help!
javascript:
function scrollUp(d){
var s=document.getElementById(d).scrollTop;
for (x=s; x>0; x=x-1){document.getElementById(d).scrollTop=x;}
}
html:
<div id="this_div" class="container">
<div id="top" class="topbutton" onClick="scrollUp('this_div');">Top</div>
</div>

you can use timer for animating that
window.onload = function() {
document.getElementById('top').onclick = function() {
scrollUp('this_div');
};
};
function scrollUp(d){
var s = document.getElementById(d).scrollTop;
var scrollDistance = 10;
var scrollSpeed = 200; // 1000 = 1 seconds
var scrollAnimate = setInterval(function() {
if (s > 0) {
s -= scrollDistance;
document.getElementById(d).scrollTop = s;
} else {
clearInterval(scrollAnimate);
}
},scrollSpeed);
}
you can now manipulate the speed and the distance of scrolling by just changing the value of scrollDistance and scrollSpeed.

Related

Infinite auto scroll top-to-bottom and back, how to control/configure speed, time of pause at end?

I'm trying to make a long page of images scroll up and down infinitely (for an exhibition).
This is what I've been working with (code I found here, so helpful!):
https://jsfiddle.net/p7r73tke/
It's mostly working ok for what I want, but I need more control over speed and pause.
How can I make the pause at the top longer?
is there a way to make it pause randomly for ~1 second ?
does anyone know of an easier way to do what I'm thinking of? maybe as samuel-liew suggests, javascript is not the best solution for the problem
thank u thank u!
function scrollpage() {
function f() {
window.scrollTo(0, i); //idk
if (status == 0) {
i = i + 50; //scroll speed top to bottom?
if (i >= Height) {
status = 30; //idk?
}
} else {
i = i - 10; //scroll speed bottom to top?
if (i <= 1) { // if you don't want continue scroll then remove this if condition
status = 0; //idk
}
}
setTimeout(f, 0.01); //idk
}
f();
}
var Height = 15000; //doc height input manually
var i = 1, //idk
j = Height,
status = 0; //idk
scrollpage();
(I'm new and tender to JavaScript, as you can see in the comments)
Thanks for any help!
jQuery solution:
var speed = 10000; // 10000 = 10 seconds
var doScroll = function() {
var direction = $(window).scrollTop() != 0 ? 0 : $(document).height() - $(window).height();
$('html, body').animate({ scrollTop: direction }, speed, 'linear');
}
doScroll(); // once on page load
setInterval(doScroll, speed + 10); // once every X ms
DEMO: http://jsfiddle.net/samliew/k35tbgau/
JavaScript:
Sorry, I do not recommend pure JavaScript for this as you have to take into account:
Cross-browser issues with getting window height, document height, and current scroll position
Recalculating the scroll speed based on content height every time the browser is resized
Programming an animation function
Keeping track of intervals and timeouts, and when you need to clear them
Direction/state of scroll
Taking into consideration if user manually scrolls the scrollbar
Probably lots more...

How can I stop Scrolling my <div> onmouseover?

Right now I have a div that I am automatically scrolling infinitely:
<script language="javascript">
i = 0
var speed = 1
function scroll() {
i = i + speed
var div = document.getElementById("content")
div.scrollTop = i
if (i > div.scrollHeight - 160) { i = 0 }
t1 = setTimeout("scroll()", 100)
}
</script>
The div that I need to scroll I want to stop scrolling onmouseover, so I have added this code to the div:
<div id="content" value="Pause" onmouseover="clearTimeout(t1)" onmouseout="scroll()">
Here is a link to a jfiddle. The preview there isn't doing what it should, but that's what I have that's working in my project right now.
So far this is working, but the problem is that I want to be able to manually scroll when I hover over this div. Now, the automatic scrolling is stopping, but I can't manually scroll with just the scrollwheel: It reacts the same when it is scrolling as when it is stopped with onmouseover.
Is there a way that I can basically cancel the whole scroll function onmouseover, or write something that just allows using the scrollwheel/scrollbar. as well? It would also be ok to have code to ALWAYS allow using the scrollwheel/scrollbar.
I'm not sure what would be the best way to do it.
Thanks!!
By setting it to scroll the overflow, assuming a fixed height, the scrollbar will pop up and you can scroll manually. Of course you will want to hide the scrollbar again when it resumes autoscrolling so you will need two functions to set the style.
<script language="javascript">
i = 0;
var speed = 1,t1=null;
function startScroll(){
document.getElementById("content").style.overflowY="hidden";
scroll();
}
function stopScroll(){
clearTimeout(t1);
document.getElementById("content").style.overflowY="scroll";
}
function scroll() {
i = i + speed;
var div = document.getElementById("content");
div.scrollTop = i;
if (i > div.scrollHeight - 160) { i = 0; }
t1 = setTimeout("scroll()", 100);
}
</script>
HTML change:
<div id="content" value="Pause" onmouseover="pauseScroll()" onmouseout="startScroll()">

How to get the real scroll height of div (say, inner text size)

I'm trying to make a auto-scrolling div that go to its top when it reaches the end. But it doesn't work...
function scrollPannel()
{
var pannel = document.getElementById('pannel');
if (typeof scrollPannel.count == 'undefined')
{
scrollPannel.count = 0;
}
else
{
scrollPannel.count += 2;
}
// trouble is here
if ((scrollPannel.count - pannel.scrollHeight) > pannel.clientHeight)
{
scrollPannel.count = 0;
}
pannel.scrollTop = scrollPannel.count;
setTimeout('scrollPannel()', 500);
}
HTML:
<div id='pannel' style="height:200px;overflow:auto" onmouseover="sleepScroll()">
<p>...</p><!-- long text -->
</div>
And after, I will need to find how to stop scrolling when "onmouseover" occures.
EDIT: I did not explained the problem clearly. In fact, I have tried something like:
if (scrollPannel.count > pannel.scrollHeight)
{
scrollPannel.count = 0;
}
The problem is that scrollHeight seems greater than div inner text. So it makes a lot of time to return to the top.
So I need an element property of which I could use the value to compare with my count variable. However I don't know Javascript a lot and I could not find anything. I hope it is as well simple as I think of it.
Try:
// calculate max scroll top position (go back to top once reached)
var maxScrollPosition = element.scrollHeight - element.clientHeight;
// example
element.scrollTop = maxScrollPosition;
That should do what you need.
You could try using the scrollHeight property.
https://developer.mozilla.org/en-US/docs/Web/API/element.scrollHeight
The solution I have involves jQuery, hope that's not a problem.
JavaScript:
var timeout;
function scrollPannel()
{
var divHeight = $("#pannel").height() / 2;
var scrollCount = $("#pannel").scrollTop();
var scrollHeight = $("#inside").height() - 20 - divHeight;
scrollCount += 2;
if ((scrollCount - scrollHeight) > 0)
{
scrollCount = 0;
}
$("#pannel").scrollTop(scrollCount);
timeout = window.setTimeout(scrollPannel(), 100);
}
function scrollStop() {
window.clearTimeout(timeout);
}
HTML:
<div id='pannel' onmouseover="scrollStop();" onmouseout="scrollPannel();">
<p id="inside"></p><!-- long text -->
</div>
Explanation:
jQuery's .height() of the inside element <p> gives us the actual height you're looking for, but it's not enough for reaching the bottom, since that happens before we reach the element's height. A little investigation shows that the "top" of scrollTop() is about half way inside the original div's height. You may need to play around with divHeight to get the exact results you're looking for.
Of course, I also included a method for stopping and continuing scrolling.
Good luck!
You should use scrollHeight property but to call it, you need to use an index like that:
$('#pannel')[0].scrollHeight;
If you set the scrollTop and scrollLeft to really high silly values they only ever get set as their maximum allowed values which I think is what you need? You can then use them to work out the scroll center if you wished.
See snippet example.
var mB = document.getElementById('myBox');
var mR = document.getElementById('myResult');
// Set the top and the left to silly values
mB.scrollTop = 99999999;
mB.scrollLeft = 99999999;
// They will only end up being set as their max
mR.innerHTML = "maxTop="+mB.scrollTop+"<br>maxLeft="+mB.scrollLeft;
// Now take the max values and divide by 2 to scroll back to middle.
mB.scrollTop = mB.scrollTop/2;
mB.scrollLeft = mB.scrollLeft/2;
#myBox{
overflow:auto;
}
#myContent{
border:1px solid black;
background-color:red;
}
<div id='myBox' style='width:300px;height:300px'>
<div id='myContent' style='width:500px;height:800px;line-height:800px;'><center>I am the center of the content</center></div>
</div>
<div id='myResult'></div>
I have got one solution....
function findMaxReach(){
let maxReach =0
document.querySelector('.YourElement').scrollLeft = 100000;
maxReach = document.querySelector('.YourElement').scrollLeft;
document.querySelector('.YourElement').scrollLeft = 0;
return maxReach
}

Stop scrolling page, scroll div

I'm creating this landing page: http://tag4share.com/landing/#
Where is located the two galaxy s3 (one white with "Organizador" label on it and a black with "Participante" label), I want to stop scrolling the page and automatically start scrolling the content inside the mobile (an iFrame, div, anything).
Is it possible?
Basically I want to "focus" the scrolling inside a div (and make it work even if the cursor isn't hovering it). Or animate while scrolling without scrolling the body.
Example: http://www.google.com/nexus/5/
On the "Everything you need to capture the moments that matter." part.
My attempt:
var lastScroll;
var currentScroll = $(window).scrollTop();
$(window).scroll(function() {
lastScroll = currentScroll;
currentScroll = $(window).scrollTop();
if($(window).scrollTop() >= 2024 && $(window).scrollTop() < 2500)
{
var difference = currentScroll - lastScroll;
$(".main").css({"margin-top":"-="+currentScroll});
}
});
I've tried to move the main div along with scrolling. It works but it looks really strange (keeps shaking).
Thanks!
I've just tidied up your code a tad, fixed indentation etc.
As for actually scrolling your div when you hit the position, use animate to actually mimic the scrolling effect, once you know you have reached the bottom, you can put another if statement within the scroll function to stop resetting the scroll position.
var lastScroll;
var scrollPosition = $(window).scrollTop();
var reachedBottom = false;
var phonePositionTop = $('#phoneContainerID').position().top;
var phonePositionBottom = phonePositionTop + $('#phoneContainerID').height();
$(window).scroll(function() {
if(scrollPosition >= phonePositionTop && scrollPosition < phonePositionBottom && reachedBottom == false){
var difference = currentScroll - lastScroll;
// Keep resetting scroll to the phoneContainerTop position
$(".main").css({"margin-top": phonePositionTop});
var scrollLimit = -100;
if ($('#phoneContainerID').position().top < scrollLimit) {
//Once the scroll limit is less than -100 (scrolled up 100 pixels)
// Disable our 'pause' effect, and continue
reachedBottom = true;
}
}
});
I haven't tested this, however I was just giving you an idea of where to go from here.
I hope I have helped a little!

Synchronized scrolling using jQuery?

I am trying to implement synchronized scrolling for two DIV with the following code.
DEMO
$(document).ready(function() {
$("#div1").scroll(function () {
$("#div2").scrollTop($("#div1").scrollTop());
});
$("#div2").scroll(function () {
$("#div1").scrollTop($("#div2").scrollTop());
});
});
#div1 and #div2 is having the very same content but different sizes, say
#div1 {
height : 800px;
width: 600px;
}
#div1 {
height : 400px;
width: 200px;
}
With this code, I am facing two issues.
1) Scrolling is not well synchronized, since the divs are of different sizes. I know, this is because, I am directly setting the scrollTop value. I need to find the percentage of scrolled content and calculate corresponding scrollTop value for the other div. I am not sure, how to find the actual height and current scroll position.
2) This issue is only found in firefox. In firefox, scrolling is not smooth as in other browsers. I think this because the above code is creating a infinite loop of scroll events.
I am not sure, why this is only happening with firefox. Is there any way to find the source of scroll event, so that I can resolve this issue.
Any help would be greatly appreciated.
You can use element.scrollTop / (element.scrollHeight - element.offsetHeight) to get the percentage (it'll be a value between 0 and 1). So you can multiply the other element's (.scrollHeight - .offsetHeight) by this value for proportional scrolling.
To avoid triggering the listeners in a loop you could temporarily unbind the listener, set the scrollTop and rebind again.
var $divs = $('#div1, #div2');
var sync = function(e){
var $other = $divs.not(this).off('scroll'), other = $other.get(0);
var percentage = this.scrollTop / (this.scrollHeight - this.offsetHeight);
other.scrollTop = percentage * (other.scrollHeight - other.offsetHeight);
// Firefox workaround. Rebinding without delay isn't enough.
setTimeout( function(){ $other.on('scroll', sync ); },10);
}
$divs.on( 'scroll', sync);
http://jsfiddle.net/b75KZ/5/
Runs like clockwork (see DEMO)
$(document).ready(function(){
var master = "div1"; // this is id div
var slave = "div2"; // this is other id div
var master_tmp;
var slave_tmp;
var timer;
var sync = function ()
{
if($(this).attr('id') == slave)
{
master_tmp = master;
slave_tmp = slave;
master = slave;
slave = master_tmp;
}
$("#" + slave).unbind("scroll");
var percentage = this.scrollTop / (this.scrollHeight - this.offsetHeight);
var x = percentage * ($("#" + slave).get(0).scrollHeight - $("#" + slave).get(0).offsetHeight);
$("#" + slave).scrollTop(x);
if(typeof(timer) !== 'undefind')
clearTimeout(timer);
timer = setTimeout(function(){ $("#" + slave).scroll(sync) }, 200)
}
$('#' + master + ', #' + slave).scroll(sync);
});
This is what I'm using. Just call the syncScroll(...) function with the two elements you want to synchronize. I found pawel's solution had issues with continuing to slowly scroll after the mouse or trackpad was actually done with the operation.
See working example here.
// Sync up our elements.
syncScroll($('.scroll-elem-1'), $('.scroll-elem-2'));
/***
* Synchronize Scroll
* Synchronizes the vertical scrolling of two elements.
* The elements can have different content heights.
*
* #param $el1 {Object}
* Native DOM element or jQuery selector.
* First element to sync.
* #param $el2 {Object}
* Native DOM element or jQuery selector.
* Second element to sync.
*/
function syncScroll(el1, el2) {
var $el1 = $(el1);
var $el2 = $(el2);
// Lets us know when a scroll is organic
// or forced from the synced element.
var forcedScroll = false;
// Catch our elements' scroll events and
// syncronize the related element.
$el1.scroll(function() { performScroll($el1, $el2); });
$el2.scroll(function() { performScroll($el2, $el1); });
// Perform the scroll of the synced element
// based on the scrolled element.
function performScroll($scrolled, $toScroll) {
if (forcedScroll) return (forcedScroll = false);
var percent = ($scrolled.scrollTop() /
($scrolled[0].scrollHeight - $scrolled.outerHeight())) * 100;
setScrollTopFromPercent($toScroll, percent);
}
// Scroll to a position in the given
// element based on a percent.
function setScrollTopFromPercent($el, percent) {
var scrollTopPos = (percent / 100) *
($el[0].scrollHeight - $el.outerHeight());
forcedScroll = true;
$el.scrollTop(scrollTopPos);
}
}
If the divs are of equal sizes then this code below is a simple way to scroll them synchronously:
scroll_all_blocks: function(e) {
var scrollLeft = $(e.target)[0].scrollLeft;
var len = $('.scroll_class').length;
for (var i = 0; i < len; i++)
{
$('.scroll_class')[i].scrollLeft = scrollLeft;
}
}
Here im using horizontal scroll, but you can use scrollTop here instead. This function is call on scroll event on the div, so the e will have access to the event object.
Secondly, you can simply have the ratio of corresponding sizes of the divs calculated to apply in this line $('.scroll_class')[i].scrollLeft = scrollLeft;
I solved the sync scrolling loop problem by setting the scroll percentage to fixed-point notation: percent.toFixed(0), with 0 as the parameter. This prevents mismatched fractional scrolling heights between the two synced elements, which are constantly trying to "catch up" with each other. This code will let them catch up after at most a single extra step (i.e., the second element may continue to scroll an extra pixel after the user stops scrolling). Not a perfect solution or the most sophisticated, but certainly the simplest I could find.
var left = document.getElementById('left');
var right = document.getElementById('right');
var el2;
var percentage = function(el) { return (el.scrollTop / (el.scrollHeight - el.offsetHeight)) };
function syncScroll(el1) {
el1.getAttribute('id') === 'left' ? el2 = right : el2 = left;
el2.scrollTo( 0, (percentage(el1) * (el2.scrollHeight - el2.offsetHeight)).toFixed(0) ); // toFixed(0) prevents scrolling feedback loop
}
document.getElementById('left').addEventListener('scroll',function() {
syncScroll(this);
});
document.getElementById('right').addEventListener('scroll',function() {
syncScroll(this);
});
I like pawel's clean solution but it lacks something I need and has a strange scrolling bug where it continues to scroll and my plugin will work on multiple containers not just two.
http://www.xtf.dk/2015/12/jquery-plugin-synchronize-scroll.html
Example & demo: http://trunk.xtf.dk/Project/ScrollSync/
Plugin: http://trunk.xtf.dk/Project/ScrollSync/jquery.scrollSync.js
$('.scrollable').scrollSync();
If you don't want proportional scrolling, but rather to scroll an equal amount of pixels on each field, you could add the value of change to the current value of the field you're binding the scroll-event to.
Let's say that #left is the small field, and #right is the bigger field.
var oldRst = 0;
$('#right').on('scroll', function () {
l = $('#left');
var lst = l.scrollTop();
var rst = $(this).scrollTop();
l.scrollTop(lst+(rst-oldRst)); // <-- like this
oldRst = rst;
});
https://jsfiddle.net/vuvgc0a8/1/
By adding the value of change, and not just setting it equal to #right's scrollTop(), you can scroll up or down in the small field, regardless of its scrollTop() being less than the bigger field. An example of this is a user page on Facebook.
This is what I needed when I came here, so I thought I'd share.
From the pawel solution (first answer).
For the horizzontal synchronized scrolling using jQuery this is the solution:
var $divs = $('#div1, #div2'); //only 2 divs
var sync = function(e){
var $other = $divs.not(this).off('scroll');
var other = $other.get(0);
var percentage = this.scrollLeft / (this.scrollWidth - this.offsetWidth);
other.scrollLeft = percentage * (other.scrollWidth - other.offsetWidth);
setTimeout( function(){ $other.on('scroll', sync ); },10);
}
$divs.on('scroll', sync);
JSFiddle
An other solution for multiple horizontally synchronized divs is this, but it works for divs with same width.
var $divs = $('#div1, #div2, #div3'); //multiple divs
var sync = function (e) {
var me = $(this);
var $other = $divs.not(me).off('scroll');
$divs.not(me).each(function (index) {
$(this).scrollLeft(me.scrollLeft());
});
setTimeout(function () {
$other.on('scroll', sync);
}, 10);
}
$divs.on('scroll', sync);
NB: Only for divs with same width
JSFiddle

Categories

Resources