I'm building a horizontal scrolling div, something like a slider.
Something like this
The thing is, this thing is between other contents, so I had to use a custom javascript code that I found online to make this horizontal sliding div act like a vertical div.
`
(function () {
init();
var g_containerInViewport;
function init() {
setStickyContainersSize();
bindEvents();
}
function bindEvents() {
window.addEventListener("wheel", wheelHandler);
}
function setStickyContainersSize() {
document
.querySelectorAll(".sticky-container")
.forEach(function (container) {
const stikyContainerHeight =
container.querySelector(".container").scrollWidth;
container.setAttribute(
"style",
"height: " + stikyContainerHeight + "px"
);
});
}
function isElementInViewport(el) {
const rect = el.getBoundingClientRect();
return (
rect.top <= 0 && rect.bottom > document.documentElement.clientHeight
);
}
function wheelHandler(evt) {
const containerInViewPort = Array.from(
document.querySelectorAll(".sticky-container")
).filter(function (container) {
return isElementInViewport(container);
})[0];
if (!containerInViewPort) {
return;
}
var isPlaceHolderBelowTop =
containerInViewPort.offsetTop < document.documentElement.scrollTop;
var isPlaceHolderBelowBottom =
containerInViewPort.offsetTop + containerInViewPort.offsetHeight >
document.documentElement.scrollTop;
let g_canScrollHorizontally =
isPlaceHolderBelowTop && isPlaceHolderBelowBottom;
if (g_canScrollHorizontally) {
containerInViewPort.querySelector(
".projAnimContainer"
).scrollLeft += evt.deltaY;
}
}
})();
This code works.
It does stick the div when user comes to that div, and its not letting the user go down till he finishes scrolling that horizontal div.
So user scrolls down, comes to the slider div, slides(scrolls down) but it doesn't scroll down but scrolls to right. And after user finishes scrolling in that div and div ends, it leaves the user and user can continue the rest of the website as normal.
It works as I said but the problem is I dont want it to scroll ugly.
I want it to scroll smooth.
containerInViewPort.querySelector(
".container"
).scrollLeft += evt.deltaY;
This is the action that adds the scrolling horizontally to my div.
I've tried changing it with this
document.querySelector(".container").scrollBy({
top: 0,
left: +evt.deltaY,
behavior: "smooth",
});
and
$(".container").animate(
{ scrollLeft: "+=" + evt.deltaY + "" },
1000,
"easeOutSine"
);
this..
Both didn't work.
They try to work but they can't, I mean for example if I change the code with the jquery one (easeoutsine one), it scrolls 1 time with ease thats good but then jumps to the end of the div and scrolling more up or down doesn't work. it stuck.
And if I use the other document.query... one it tries to scroll with ease but the scrolling to right effect ends and it goes to the next content after this slider without finishing the slider completely. I think when I add ease, it adds more px than it should and It finishes the slider before it should.
I hope I managed to describe my question.
Thanks all.
I've tried jquery and normal ease animations.
Related
This code works well, but when I scroll up and down after 4-5 times it crashes and all the elements disappear. Why does this happen and how do I fix it?
$(window).on("load",function() {
$(window).scroll(function() {
var winheight = $(window).innerHeight();
$(".fade").each(function() {
/* Check the location of each desired element */
var objectBottom = $(this).offset().top + $(this).outerHeight();
var windowBottom = $(window).scrollTop() + $(window).innerHeight();
/* If the element is completely within bounds of the window, fade it in */
if ( windowBottom > (objectBottom - (winheight*0.65))) { //object comes into view (scrolling down)
if ($(this).css("opacity")==0) {$(this).fadeTo(500,1);}
} else { //object goes out of view (scrolling up)
if ($(this).css("opacity")==1) {$(this).fadeTo(500,0);}
}
});
}); $(window).scroll(); //invoke scroll-handler on page-load
});
Ok, I supposed that your html is something like this: https://jsfiddle.net/szdwwdac/
Sometimes, if you are scrolling fast up and down, when the element is fading out, your if doesn't work well.
if ( windowBottom >= (objectBottom - (winheight*0.65))) {
if ($(this).css("opacity")==0) {$(this).fadeTo(300,1);}
} else { //object goes out of view (scrolling up)
if ($(this).css("opacity")==1) {$(this).fadeTo(300,0);}
}
It's because of the 500ms of animation.
One of the solutions can be the eneble/disable for 500ms of the scroll page.
You can check this solution: How to disable scrolling temporarily?
EDIT
Another solution can be: add a class "fading" when you are inside your if. Then, in the if, eval if the element hasClass "fading". If not, you can go inside and make the animation.
I'm writing this after searching for mousewheel events in jQuery, but perhaps I'm not asking the right questions due to my lack of knowledge, and that's why I'm not finding any useful answers yet.
What I would like to achieve is a mousewheel effect that I can trigger only inside a certain div called #scroller. I'm using the jquery mousewheel plugin by Brandon Aaron and a script that updates the top value to the next or previous .js-slide whenever I delta scroll.
FIDDLE LINK:
I created this fiddle link. As you can see, it "jumps" from slide to slide, but then the content outside #scroller is not accesible anymore! I would like it to have a normal wheelmouse behaviour :S. I also have a working url where I would like to apply this effect, if you think that's of any use.
To better explain the structure and desired effect, here's an image:
I have already tried bounding my script only to $('#scroller').mouseover(function(){ my script }); but that didn't work. The mousewheel started out ok, it switched into jumping mode ok, but it never went back to normal after leaving the div #scroller and I don't find how to reset this behaviour.
My script right now is this:
jQuery(document).ready(function($) {
var slide = $('.js-slide');
var sectionHeight = $(window).height();
var slideHeight = $(slide).height();
var scrollingScreen = false;
$('#scroller').mouseover(function(){
$(slide).mousewheel(function(event, delta) {
if ( !scrollingScreen ) {
scrollingScreen = true; // prevent call
var top = $("body").scrollTop() || $("html").scrollTop();
// Chrome places overflow at body, Firefox places whacks at html...
// Finds slide headers above/below the current scroll top
var candidates = $(slide).filter(function() {
if ( delta < 0 )
return $(this).offset().top > top + (1);
else
return $(this).offset().top < top - (1);
});
// one or more slides found? Update top
if ( candidates.length > 0 ) {
if ( delta < 0 )
top = candidates.first().offset().top;
else if ( delta > 0 )
top = candidates.last().offset().top;
}
// Perform animated scroll to the right place
$("html,body").animate({ scrollTop:top }, "easeInOutQuint", function() {
scrollingScreen = false; // Release call
});
}
return false;
}); // closes mousewheel
}); // closes mouseover
});
Any help or insight on how to achieve this would be greatly appreciated.
Thank you!
Ok. Finally I found it!! I reviewed the web where the plugin author records different mousewheel events, including deactivating all of them and reseting a normal scrolling mouse. There's where I found the use of the function .unmousewheel(), just what I wanted!
But now, as the script is not able to find further slides past de last when scrolling down, and before the first when scrolling up, it became impossible to access content before and after #scroller with the scrolling wheel. That's why I had to change a bit the script and force a jump while on the first slide or the last.
Anyway, here's the script:
jQuery(document).ready(function($) {
var slide = $('#scroller .sectioncontainer');
var sectionHeight = $(window).height();
var slideHeight = slide.height();
var scrollingScreen = false;
slide.mousewheel(function(event, delta) {
if ( !scrollingScreen ) {
scrollingScreen = true; // prevent call
var top = $("body").scrollTop() || $("html").scrollTop();
// Chrome places overflow at body, Firefox places whacks at html...
// Finds slide headers above/below the current scroll top
var candidates = slide.filter(function() {
if ( delta < 0 )
return $(this).offset().top > top + (1/120);
else
return $(this).offset().top < top - (1/120);
});
// one or more slides found? Update top
if ( candidates.length > 0 ) {
if ( delta < 0 )
top = candidates.first().offset().top;
else if ( delta > 0 )
top = candidates.last().offset().top;
} else{ // no more slides found
if ( delta < 0 )
top = $("#contact").offset().top;
else if ( delta > 0 )
top = $("#about").offset().top;
}
// Perform animated scroll to the right place
$("html,body").animate({ scrollTop:top }, "easeInOutQuint", function() {
scrollingScreen = false; // Release call
});
}
return false;
});
$("#contact").unmousewheel();
$("#about").unmousewheel();
$("#div1").unmousewheel();
$("#div2").unmousewheel();
$("#div3").unmousewheel();
$("#div4").unmousewheel();
$("#div5").unmousewheel();
// . . .
//and all other divs and sections that don't use the mousewheel
});
And here's the result.
Im trying to remove the scrollbars and replace them with up/down buttons.
Im nearly there, everything works, I just want to remove the 'up' button when you are scrolled right to the top of the container. right now Ive just hidden it as a default and an onscroll event on the container, and then just do this to make the scroll button appear:
function OnScrollDiv (div) {
$(".up").show();
}
But if you scroll back up, the up button stays, of course.
Now I dont understand why my alternative wont work! What I want to do is just check at the scroll event whether the scrollTop() value is 0, if it is, dont show it. I dont know javascript, but I would imagine it would look like:
function OnScrollDiv (div) {
var n = $("#prodcont").scrollTop();
if (n = 0) {
//nothing
}
else {
$(".up").show();
}
But alas, this does not work. At all. Any suggestions?!
You can make use of onscroll event provided by window. Ref
window.onscroll = scroll;
function scroll () {
console.log("scroll event detected! " + window.pageXOffset + " " + window.pageYOffset);
if(window.pageXOffset == 0 && window.pageYOffset == 0)
console.log('hide buttons');
}
I've been working on a scroll to top function for my website, and that part of it works fine. My problem is however that I have a fixed div that is overlapping my footer when it hits the bottom of the page.
Here is the function that I have working.
$(document).scroll(function (e) {
if (document.body.scrollTop >= 800) {
$('#beamUp').show(1000);
} else {
$('#beamUp').hide(1000);
return false;
}
});
Is there somehow I could detect when I hit that part of the page and stop the div from moving past that.Help is much appreciated!
jsFiddle: http://jsfiddle.net/zazvorniki/RTDpw/
Just get the height of the page, minus the height of the div in question, as well as the footer... make sure the top is never greater than that value... you'll also need an onresize event handler re-evaluate that value.
looking at your jsfiddle... here are my edits
In your scroll listener, I am checking for the position of the page, and adjusting the bottom position of the floater appropriately. I also set the initial display:none, so you don't need to call .hide() in your initial script. In addition, resizing the window has the effect of scrolling for your use, so I changed the listener for both events.
$(document).on('scroll resize', function (e) {
var viewHeight = $(window).height();
var viewTop = $(window).scrollTop();
var footerTop = $("footer").offset().top;
var baseline = (viewHeight + viewTop) - footerTop;
var bu = $("#beamUp").css({bottom: (baseline < 0 ? 0 : baseline) + 'px'});
if (viewTop >= 50) {
bu.show(1000);
} else {
bu.hide(1000);
}
});
This is a follow-up post to a previous question: jQuery - scroll down every x seconds, then scroll to the top
I have refined the scrip a little further, but am having a little trouble with the last step.
I have a div that automatically 50px at a time until it reaches the bottom, at which point it scrolls to the top and starts again. I have this working perfectly thanks to the above question and with a little add work.
I need to make all scrolling stop when the div is hovered. I have done part of this already (there is no incremental scrolling down on hover) but I cannot get the full picture. The div will still scroll to the top even when hovered.
Here is my jQuery and a fiddle to go along with it: http://jsfiddle.net/wR5FY/1/
var scrollingUp = 0;
var dontScroll = 0;
window.setInterval(scrollit, 3000);
function scrollit() {
if(scrollingUp == 0 && dontScroll == 0) {
$('#scroller').animate({ scrollTop: $("#scroller").scrollTop() + 50 }, 'slow');
}
}
$('#scroller').bind('scroll', function () {
if (dontScroll == 0) {
if ($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight) {
scrollingUp = 1;
$('#scroller').delay(2000).animate({ scrollTop: 0 }, 1000, function() {
scrollingUp = 0;
});
}
}
});
$('#scroller').bind('mouseenter', function() {
dontScroll = 1;
});
$('#scroller').bind('mouseleave', function() {
dontScroll = 0;
});
In the fiddle, try hovering the scroller div when the yellow square is visible. You will see that it scrolls to the top.
A couple of notes:
You will notice I have used mouseenter and mouseleave rather than hover and mouseout. This was the best way I could find to ensure all child elements within the div didn't have an adverse affect.
A potential problem area is the fact that I have binded to the scroll event for my function that scrolls to the top. I think this might cause some additional problems when a user is manually scrolling through the items, with my jQuery trying to scroll against the user.
I did a little experimenting with killing setInterval, but I didn't find this to be very helpful as the function that triggers isn't the problem area.
My overall goal here is to lock down all automatic scrolling when a user is hovering or manually scrolling through the list. This is 90% there. If they happen to scroll to the bottom, NOTHING should happen until they move the mouse elsewhere - this is the problem.
Keep it easier ;)
The problem was that you first evaluate wheter dontScroll is zero, then start the timer.
When the timer has ended, it doesnt evaluate anymore, whether dontScroll STILL is zero.
Just pulled that into your scrollIt function:
var scrollingUp = 0;
var dontScroll = 0;
window.setInterval(scrollit, 2000);
function scrollit() {
if(dontScroll == 0){
if ($('#scroller').scrollTop() + $('#scroller').innerHeight() >= $('#scroller')[0].scrollHeight) {
scrollingUp = 1;
$('#scroller').animate({ scrollTop: 0 }, 1000, function() {
scrollingUp = 0;
});
} else if(scrollingUp == 0) {
$('#scroller').animate({ scrollTop: $("#scroller").scrollTop() + 50 }, 'slow');
}
}
}
$('#scroller').bind('mouseenter', function() {
dontScroll = 1;
});
$('#scroller').bind('mouseleave', function() {
dontScroll = 0;
});