this is a script i got from a the internet, and it works perfectly, what it deos it scrolls automatically on the movement of the mouse, over a div in this case scroll, but i cnt seem to find where i can find the speed, or can make it slower!! im so confused!!
$("#scroll").mousemove(function(e){
/* The scrollable quote container */
if(!this.hideDiv)
{
/* These variables are initialised only the firts time the function is run: */
this.hideDiv = $(this);
this.scrollDiv = $('#scroll');
this.pos = this.hideDiv.offset();
this.pos.top+=20;
/* Adding a 20px offset, so that the scrolling begins 20px from the top */
this.slideHeight = this.scrollDiv.height();
this.height = this.hideDiv.height();
this.height-=20;
/* Adding a bottom offset */
this.totScroll = this.slideHeight-this.height;
}
this.scrollDiv.css({
/* Remember that this.scrollDiv is a jQuery object, as initilised above */
marginTop:'-'+this.totScroll*(Math.max(e.pageY-this.pos.top,0)/this.height)+'px'
/* Assigning a negative top margin according to the position of the mouse cursor, passed
with e.pageY; It is relative to the page, so we substract the position of the scroll container */
});
});
The code seems to be just setting the margin directly:
marginTop:'-'+this.totScroll*(Math.max(e.pageY-this.pos.top,0)/this.height)+'px'
That is, it doesn't call any scroll jquery function that could easily be animated. To achieve that you would have to do some rewriting of that code, probably using jquery animate() function with the marginTop css.
The only problem is that the code is called on mousemove, which means that it could easily be called again while the animation is still active. So you will have to come up with some workaround there, like maybe checking first if there is an animation present and aborting it in that case.
Related
I have explored few approaches to this, but none really seems to work exactly like I would like:
I would like that when scrolling down, navbar is moving up at the speed the user is scrolling down, like that is static at that point.
When it disappears, I would like that the bottom of it is still visible, because this is where I have a progress bar (but maybe progress bar should detach at that point and be on top of the viewport).
When you scroll up, I would like that navbar appears again, again at the speed of scrolling, like it is static, until you see the whole navbar, when it should stick to the top of the viewport.
Here is an example of behavior I would like, but not performance/experience (because behavior is implemented using scroll event, it is not smooth).
I have also attempted to use CSS transform, which would on scroll down add a class to hide the navbar, and scroll up remove the class, animating the navbar hiding/showing, but the issue with that is that animation speed is disconnected with scrolling speed.
I tried CSS sticky position as well, but it looks like I need the opposite of what it provides.
Is there some other way to make this work well?
I've looked at your problem and I think i found a simple approach.
with this simple function you can get the amount of pixels user has scrolled.
window.onscroll = function (e) {
console.log(window.scrollY); // Value of scroll Y in px
};
after user scrolls the desired amount of pixels, make the progress bar fixed top ( or position:fixed;top:0)
Checking the link you provided, it seems to work as expected (you want it to be linked to the scroll event since you want it to move as "static"). If, though, it staggers on some system due to inconsistent scroll events, you could try adding a transition property with a small enough duration. Keep in mind the this should only be enabled while the position property remains the same, otherwise when changing from "absolute" to "fixed" it would mess things up, since the coordinate origin changes.
So you can add another variable let changedPosition = false; and whenever you change the position property you can do
if (position !== "absolute") {
changedPosition = true;
} else {
changedPosition = false;
}
position = "absolute";
or
if (position !== "fixed") {
changedPosition = true;
} else {
changedPosition = false;
}
position = "fixed";
and when you apply the style do
navbar.style = `position: ${position}; top: ${navbarTop}px; transitiona: ${
changedPosition ? "none" : "100ms linear"
}`;
like https://codepen.io/gpetrioli/pen/XWVKxNG?editors=0010
You should play around a bit with the transition properties you provide, i just put some sample values there.
I would like to move my image down the screen from the top left to the bottom left. I call two functions when the body loads:
window.onload = function() {
MoveRight();
MoveDown();
};
I then retreive the width and height of the clients browser window (to ensure the animation stops when it reaches the sides of the window):
document.body.style.height = height;
document.body.style.width = width;
The function "MoveDown()" is this:
function MoveDown(){
for(var i = 0; i < ; i++)
{
document.getElementById("Amanda").style.top=+i;
}
}
For some reason when I load the webpage, the image just sits in the top left. I had hoped the for loop would increment the "top" value by 1px every time, until such time that it was touching the bottom of the window when it would stop.
If it helps, the image position is set to relative with left and top both set to 0px.
If anyone could help it would be great.
*I collect the width as I want the image to move diagonally but figured that if I got moving down figured out I could easily change the code to make it go sideways at the same time.
The reason it's not moving is most likely (depending on browser) because you're not setting the units. Try
document.getElementById("Amanda").style.top=i+"px";
However, you'll find that it jumps straight down rather than animating. The reason is your loop executes all in one go without giving the browser a chance to redraw. There are a number of ways of getting around this, but one simple one would be like this
function MoveDown() {
var i=0;
function step() {
document.getElementById("Amanda").style.top=i+"px";
i++;
if (i<=100) setTimeout(step,10);
}
step();
}
Do you have position: absolute or position: relative (or position: fixed) as styling for your image?
Asking this because top applies only to positioned elements (and by default elements have position: static which is they are not explicitly positioned).
See https://developer.mozilla.org/en-US/docs/Web/CSS/top and https://developer.mozilla.org/en-US/docs/Web/CSS/position
On rereading your question, this loop of yours looks like an endless loop. Consider adding a stop rule for it, or as suggested in the comments - if you do not need some kind of sliding animation, just put css rule for bottom: 0
You'll want to use setTimeout or setInterval (I can never remember) with some interval and a function that increments the top value every time it runs. Then cancel the timeout/interval when the image reaches it's destination!
I want to call some actions, when the user is scrolling in iScroll4. Also depending on the position and speed on the scrolling.
Where and how to hook in best to achive this?
With addListener I had no luck, because it reacts on on-time events, eg. Touchmove, touchstart. What i need is to know when the div is scrolling..
Any ideas?
There are lot of callback functions iScroll. You can use those for your purposes.
A small explanation about those.
scroller = new iScroll('ID', {
onRefresh : function(){
/* iScroll provided feature to refresh the scroller. This will help to refresh the scroller container when you dynamically add contents. */
},
onBeforeScrollStart : function(e){
/* this is nothing but just when your mousedown event (This will be triggered each and every mousedown event). This is very useful when your parent container have scroller and your child container also have scroller. Assume this is your child scroller. What you can do is just get your parent scroller object (parentScroller) and disable it "parentScroller.disable()" */
},
onScrollStart : function(){
/* now you start to move your mouse while holding mouse left button */
},
onBeforeScrollMove : function(){
/* this where your scroller is start to move actually */
},
onScrollMove : function(){
/* now your scroller is moving. If you need to do something, when your scroller is moving you can do those here */
},
onBeforeScrollEnd : function(){
/* your scroller movement is about to stop */
},
onScrollEnd : function(){
/* your scorller movement stoped. Will say you have disable your parent scroller. Now this is the good place to enable your parent scroller "parentScroller.enable()"*/
},
onDestroy : function(){
/* you destroy your scroller. iScroll is provide a feature to remove the attached sctoller. */
}
});
I just gave you a small explanation about the some of callback functions. But there are some more exists such as onTouchEnd, onZoomStart, onZoom, onZoomEnd. You can experiment those if you need.
I hope this might help you to sort out issue.
Latest Update to get the position and speed of the scroller.
scroller = new iScroll('ID', {
onScrollMove : function(e){
/* this function return an object in which it has almost all the required stuffs. */
}
});
For your reference console.log(e) and analyze the value e has. It return lot of x & y positions. From those you can get the scroller position directly. But to get the speed of the scroller you have to use physics ;). It returns timestamp, scroller position. I think you might to able to get the speed using these values. I am sorry at the moment I could not analyze these values to exactly say how you can get the speed. But I think you can calculate speed using the values available.
The scroll event is available on iScroll probe edition only (iscroll-probe.js). The probe behavior can be altered through the probeType option.
you can include "iscroll-probe.js" in your html and :
var myScroll = new IScroll('#container', { probeType: 3, mouseWheel: true });
myScroll.on('scroll',function(){
var top = parseInt(-this.y);// scrolltop value
//do something with top
})
This may come as a huge surprise to some people but I am having an issue with the IE browser when I am using the $(window).scroll method.
My goal:
I would like to have the menu located on the left retain it's position until the scroll reaches > y value. It will then fix itself to the top of the page until the scroll returns to a < y value.
My error:
Everything seems just fine in Chrome and Firefox but when I go to Internet Explorer it would seem the browser is moving #scroller every time the scroll value changes, this is causing a moving/flickering event.
If someone could point me to a resource or give me a workaround for this I would be very grateful!
Here is a fiddle:
http://jsfiddle.net/CampbeII/nLK7j/
Here is a link to the site in dev:
http://squ4reone.com/domains/ottawakaraoke/Squ4reone/responsive/index.php
My script:
$(window).scroll(function () {
var navigation = $(window).scrollTop();
if (navigation > 400) {
$('#scroller').css('top',navigation - 220);
} else {
$('#scroller').css('top',183);
$('#scroller').css('position','relative');
}
});
You might want to take a look at the jQuery Waypoints plugin, it lets you do sticky elements like this and a lot more.
If you want to stick with your current method, like the other answers have indicated you should toggle fixed positioning instead of updating the .top attribute in every scroll event. However, I would also introduce a flag to track whether or not it is currently stuck, this way you are only updating the position and top attributes when it actually make the transition instead of every scroll event. Interacting with the DOM is computationally expensive, this will take a lot of load off of the layout engine and should make things even smoother.
http://jsfiddle.net/WYNcj/6/
$(function () {
var stuck = false,
stickAt = $('#scroller').offset().top;
$(window).scroll(function () {
var scrollTop = $(window).scrollTop();
if (!stuck && scrollTop > stickAt) {
$('#scroller').css('top', 0);
$('#scroller').css('position','fixed');
stuck = true;
} else if (stuck && scrollTop < stickAt) {
$('#scroller').css('top', stickAt);
$('#scroller').css('position','absolute');
stuck = false;
}
});
});
Update
Switching the #scroller from relative to fixed removes it from the normal flow of the page, this can have unintended consequences for the layout as it re-flows without the missing block. If you change #scroller to use an absolute position it will be removed from the normal flow and will no longer cause these side-effects. I've updated the above example and the linked jsfiddle to reflect the changes to the JS/CSS.
I also changed the way that stickAt is calculated as well, it uses .offset() to find the exact position of the top of #scoller instead of relying on the CSS top value.
Instead of setting the top distance at each scroll event, please consider only switching between a fixed position and an absolute or relative position.All browsers will appreciate and Especially IE.
So you still listen to scroll but you now keep a state flag out of the scroll handler and simply evaluate if it has to switch between display types.
That is so much more optimized and IE likes it.
I can get flickers in Chrome as well if I scroll very quickly. Instead of updating the top position on scroll, instead used the fixed position for your element once the page has scrolled below the threshold. Take a look at the updated fiddle: http://jsfiddle.net/nLK7j/2/
Simple, I just would like to have it so when a user is dragging an item and they reach the very bottom or top of the viewport (10px or so), the page (about 3000px long) gently scrolls down or up, until they move their cursor (and thus the item being dragged) out of the region.
An item is an li tag which uses jquery to make the list items draggable. To be specific:
../jquery-ui-1.8.14.custom.min.js
http://code.jquery.com/jquery-1.6.2.min.js
I currently use window.scrollBy(x=0,y=3) to scroll the page and have the variables of:
e.pageY ... provides absolute Y-coordinates of cursor on page (not relative to screen)
$.scrollTop() ... provides offset from top of page (when scroll bar is all the way up, it is 0)
$.height()... provides the height of viewable area in the user's browser/viewport
body.offsetHeight ... height of the entire page
How can I achieve this and which event best accommodates this (currently its in mouseover)?
My ideas:
use a an if/else to check if it is in top region or bottom, scroll up if e.pageY is showing it is in the top, down if e.page& is in bottom, and then calling the $('li').mouseover() event to iterate through...
Use a do while loop... this has worked moderately well actually, but is hard to stop from scrolling to far. But I am not sure how to control the iterations....
My latest attempt:
('li').mouseover(function(e) {
totalHeight = document.body.offsetHeight;
cursor.y = e.pageY;
var papaWindow = window;
var $pxFromTop = $(papaWindow).scrollTop();
var $userScreenHeight = $(papaWindow).height();
var iterate = 0;
do {
papaWindow.scrollBy(0, 2);
iterate++;
console.log(cursor.y, $pxFromTop, $userScreenHeight);
}
while (iterate < 20);
});
Works pretty well now, user just needs to "jiggle" the mouse when dragging items sometimes to keep scrolling, but for scrolling just with mouse position its pretty solid. Here is what I finally ended up using:
$("li").mouseover(function(e) {
e = e || window.event; var cursor = { y: 0 }; cursor.y = e.pageY; //Cursor YPos
var papaWindow = parent.window;
var $pxFromTop = $(papaWindow).scrollTop();
var $userScreenHeight = $(papaWindow).height();
if (cursor.y > (($userScreenHeight + $pxFromTop) / 1.25)) {
if ($pxFromTop < ($userScreenHeight * 3.2)) {
papaWindow.scrollBy(0, ($userScreenHeight / 30));
}
}
else if (cursor.y < (($userScreenHeight + $pxFromTop) * .75)) {
papaWindow.scrollBy(0, -($userScreenHeight / 30));
}
}); //End mouseover()
This won't work as the event only fires while you're mouse is over the li.
('li').mouseover(function(e) { });
You need to be able to tell the position of the mouse relative to the viewport when an item is being dragged. When the users starts to drag an item attach an 'mousemove' event to the body and then in that check the mouse position and scroll when necessary.
$("body").on("mousemove", function(event) {
// Check mouse position - scroll if near bottom or top
});
Dont forget to remove your event when the user stops dragging.
$("body").off("mousemove", function(event) {
// Check mouse position - scroll if near bottom or top
});
This may not be exactly what you want, but it might help. It will auto-scroll when the mouse is over the 'border of the screen' (a user defined region). Say you have a 40px wide bar on the right of the screen, if the mouse reaches the first 1px, it will start scrolling. Each px you move into it, the speed will increase. It even has a nice easing animation.
http://www.smoothdivscroll.com/v1-2.htm
I get a weekly newsletter (email) from CodeProject, and it had some stuff that certainly looks like it will solve my problem... hopefully this can help others:
http://johnpolacek.github.com/scrollorama/ -- JQuery based and animates the scroll
https://github.com/IanLunn/jQuery-Parallax -- JQuery based, similar to above
http:// remysharp. com/2009/01/26/element-in-view-event-plugin/ -- JQuery, detects whether an element is currently in view of the user (super helpful for this issue!)
Also the site in #2 had some interesting code:
var windowHeight = $window.height();
var navHeight = $('#nav').height() / 2;
var windowCenter = (windowHeight / 2);
var newtop = windowCenter - navHeight;
//ToDo: Find a way to use these vars and my original ones to determine scroll regions