Mouse scroll - snap to divs - javascript

I currently have a page in the form of
<div id="content">
<div id="content-page-1">
<!--content-->
</div>
<div id="content-page-2">
<!--content-->
</div>
</div>
Is there any way to make scrolling either
Stick/snap to divs (these are 100% height and 100% width of the display area)
Auto-scroll to next div when scrolling detected
with jquery?

If you listen for the scroll event on your node, you could easily use a plugin like scrollTo to smooth scroll to the "next div" or previous div (however you define that).
var prevScrollTop = 0;
var $scrollDiv = $('div#content');
var $currentDiv = $scrollDiv.children('div:first-child');
$scrollDiv.scroll(function(eventObj)
{
var curScrollTop = $scrollDiv.scrollTop();
if (prevScrollTop < curScrollTop)
{
// Scrolling down:
$currentDiv = $currentDiv.next().scrollTo();
}
else if (prevScrollTop > curScrollTop)
{
// Scrolling up:
$currentDiv = $currentDiv.prev().scrollTo();
}
prevScrollTop = curScrollTop;
});

I tried different plugins but they all had problem with multiple event firing in mvc, so i came up with this solution using underscore.js
<script type="text/javascript">
$(document).ready(function () {
var isc = _.throttle(function (event) {
if ($(window).scrollTop() + $(window).height() > $(document).height() - 200) {
if (event.handled !== true) {
$.post('#path', function (html) {
$('#user-feed').append(html);
});
}
}
}, 300);
$(window).scroll(isc);
});
</script>

Related

Detect when touch scroll animation finishes (within a DIV). There is no scrollanimation-end event?

I am scrolling several DIV children .scroll-item within a parent DIV .pathscroll.
I check the scroll position and then reposition the child DIV accordingly. Also a column is shown below, according to the child in the viewport.
HTML code:
<div class="pathscroll">
<div class="scroll-item" id="1">Montag</div>
<div class="scroll-item" id="2">Dienstag</div>
<div class="scroll-item" id="3">Mittwoch</div>
<div class="scroll-item" id="4">Donnerstag</div>
<div class="scroll-item" id="5">Freitag</div>
</div>
JS code:
$('body').on('touchend', '.scroll-item', function()
{
var scrollitem = $(this);
// determine most visible scrollitem
$('.scroll-item').each( function()
{
let scrollpos_left = ($(this).offset().left + 100);
if (scrollpos_left>0 && scrollpos_left<320)
{
scrollitem = $(this);
}
});
$('.pathscroll').animate({
// get scroll position and position of element to the left, then scroll the distance
scrollLeft: $('.pathscroll').scrollLeft() + scrollitem.offset().left - $('.pathscroll').offset().left - 2,
}, 200);
// show the column accordingly
var pathid = scrollitem.attr('id');
if ( $('#"'+pathid+'"]:visible').length == 0)
{
$('.path-column').hide(150);
$('#'+pathid).show(150);
}
});
You can see the problem in the GIF recording: When the user scrolls with a "swing" the DIV still gets scrolled, but the touchend gets triggered too early, resulting in some weird behavior.
How can I check if the DIV is still scrolling, and only then trigger the touchend event or skip the event and just check for an "end of scrolling" event?
Update:
I found out how to detect the scrolling of the parent DIV by:
var scrollpos_last = 0;
var scrolling_left = false;
$('.pathscroll').scroll( function()
{
let scrollpos_now = $(this).scrollLeft();
scrolling_left = (scrollpos_now < scrollpos_last);
scrollpos_last = scrollpos_now;
});
Maybe I can trigger the touchend event after the end of the scroll?! But there is no "scrollend" event as it seems.
Solution, thanks #Kosh.
JS Code:
// Jquery extension (event debouncing), https://stackoverflow.com/a/3701328/1066234
$.fn.scrollEnd = function(callback, timeout)
{
$(this).on('scroll', function()
{
var $this = $(this);
if ($this.data('scrollTimeout'))
{
clearTimeout($this.data('scrollTimeout'));
}
$this.data('scrollTimeout', setTimeout(callback, timeout));
});
};
$('.pathscroll').scrollEnd(function()
{
set_path_scroll_item();
}, 100);
And set_path_scroll_item(); contains the code above in the question.

Is there a way for changing different images at different scrolling point?

I'm trying to change one image at a time when I'm scrolling through the page.
This code actually changes all images classes when we get to that point of the scroll.
Is there any other way we can change images individually when scrolling?
Thank you.
jQuery(function($) {
var show = $(".show");
var hide = $(".hide");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if($(window).scrollTop() >= 500){
show.removeClass('show').addClass("hide");
hide.removeClass('hide').addClass("show");
} else {
show.removeClass("hide").addClass('show');
hide.removeClass('show').addClass("hide");
}
});
});
Since you're checking the scroll position of window and hiding/showing, this will hide/show all elements with the specified class name.
To achieve your purpose, add css position: relative to all images (if no position is specified already),
Then, iterate through each image as follows...
jQuery(function($) {
//var show = $(".show");
//var hide = $(".hide");
$(window).scroll(function() {
/*var scroll = $(window).scrollTop();
if($(window).scrollTop() >= 500){
show.removeClass('show').addClass("hide");
hide.removeClass('hide').addClass("show");
} else {
show.removeClass("hide").addClass('show');
hide.removeClass('show').addClass("hide");
}*/
var images = $('img');//or any other selector
$.each(images, function () {
if($(this).offset().top <= -500) {
$(this).hide();
}
else {
$(this).show();
}
});
});
});

Text effect not working properly if i add more div on page scroll

I have taken a reference of the below site and i want to add text effects ie opacity gets fade on page scroll. The above code is working properly if i use the below reference as it is but if i add many div then it gets faded early not reaching the required div
http://jsfiddle.net/HsRpT/134/
Here is what i have done and the text fade effects goes early without reaching the actual div. Is there any other way of solving this problem?
<div>
fsdfdfsdfffffffffff<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>><br><br><br>
</div>
<div class="block">
<h2>Fade this in / out as scroll down</h2>
</div>
<div class="content">
<div class="headerbar">
</div>
</div>
Try
$(window).scroll(function() {
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
if (scrollTop > 200) {
$('.block').stop(true, true).fadeOut();
}
else {
$('.block').stop(true, true).fadeIn('fast');
}
});
Fiddle
current_div="div1";
$(window).scroll(function() {
current_div = scroll_content();
console.log(current_div);
if(current_div=="last"){
don't fade out
}
});
function scroll_content(){
var winTop = $(this).scrollTop();
var $divs = $('section');
var top = $.grep($divs, function(item) {
return $(item).position().top <= winTop;
});
var cur=top[top.length - 1];
return $(cur).attr('id');
}
You can get the the id of the div which is going out of screen while scrolling. So you can do what ever you want to do with the divs after getting the id .
It worked for me.
Let me know if you any other query.

image related info showing while image centered when scrolling

I have the following problem:
I want image related captions in a div to show up while scrolling through my tumblr blog. So far I embedded the following code and managed to get it work:
script I used:
Fiddle
$(window).load(function () {
$(window).on("scroll resize", function () {
var pos = $('#captionposition').offset();
$('.post').each(function () {
if (pos.top >= $(this).offset().top && pos.top <= $(this).next().offset().top) {
$('#captionposition').html($(this).find('.tags').text()); //or any other way you want to get the date
return; //break the loop
}
});
});
$(document).ready(function () {
$(window).trigger('scroll'); // init the value
});
})
My blog
I am not sure how exactly "top" is defined, but it turned out being quite confusing for the viewer as there's no "pause" inbetween the captions and the div seems to pop up eventhough the image is not even fully visible in the window. Plus if two or even more images show up at the same time it's uncertain to which the info belongs.
What would I aim for?
I would love to have the div with the informations only visible for the image fully centered. center +/- 10% would be enough I guess (but would like to play around with this if possible). And a rather smooth fade in/out animation would be great as well.
I am super thankful in advance if anybody can help me!
original code:
{block:Photo}
<li class="post photo">
<ul class="post-data">
{block:IfPhotoIconImage}<li class="icon"></li>{/block:IfPhotoIconImage}
<li class="info"></li>
</ul>
<div class="post-content">
<div class="content-img-wrapper">{LinkOpenTag}<img src="{PhotoURL-1280}" alt="{PhotoAlt}"/>{LinkCloseTag}</div>
{block:Caption}<div class="caption">{Caption}</div>{/block:Caption}
</div>
{block:HasTags}
<ul class="tags" style="display: none;">
{block:Tags}
<li>{Tag} </li>
{/block:Tags}
</ul>
{/block:HasTags}
</li>
{/block:Photo}
<div id='captionposition'></div>
okay, so this is what worked well for me (check iris post for further explanations):
$(window).load(function () {
var window_center = $(window).height()/2;
var threshold = 0;
$(window).on("scroll resize", function () {
scroll = $(window).scrollTop();
//var pos = $('#captionposition').offset();
$('.post').each(function () {
var post_center = $(this).height()/2 + $(this).offset().top;
if (post_center + threshold < window_center + scroll ||
post_center - threshold < window_center + scroll) {
if (!$(this).hasClass('active')){
$('.post').removeClass('active');
$(this).addClass('active');
$( "#captionposition" ).hide();
$( "#captionposition").html($(this).find('.caption').text());
$( "#captionposition" ).fadeIn('slow');
}
return; //break the loop
}
});
});
$(document).ready(function () {
$(window).trigger('scroll'); // init the value
});
})
</script>
Ok I made a Demo that could help you.
$(window).load(function () {
var window_center = $(window).height()/2;
var threshold = 0;
$(window).on("scroll resize", function () {
scroll = $(window).scrollTop();
$('.post').each(function () {
var post_center = $(this).height()/2 + $(this).offset().top;
if (post_center + threshold < window_center + scroll ||
post_center - threshold < window_center + scroll){
if (!$(this).hasClass('active')){
$('.post').removeClass('active');
$(this).addClass('active');
$('#captionposition').hide();
var newDescr = $(this).find('.tags');
$('#captionposition').html(newDescr.html());
$('#captionposition').fadeIn('slow');
}
}
});
});
$(document).ready(function () {
$(window).trigger('scroll'); // init the value
});
});
Things to know:
I used $(window).scrollTop() as reference, so we know how much it's scrolled.
Added a Threshold variable, to set the +/- percent you wanted.
The scripts calculates the center of window and center of each .post.

How to stop position fixed before footer?

I have a floating box and I'd like to know how I can stop it from overlapping the footer div by stopping it on the main div where it is only allowed to go.
window.onload = function ()
{
var scrolledElement = document.getElementById('scrolling_box');
var top = scrolledElement.offsetTop;
var listener = function ()
{
var y = scrolledElement.scrollTop || scrolledElement.scrollTop || window.pageYOffset;
if (y >= top-25)
{
scrolledElement.classList.add('fixed');
} else {
scrolledElement.classList.remove('fixed');
}
};
window.addEventListener('scroll', listener, false);
}
I'd like for it to stop at the main div, that is as followed:
<div class="outer">
<div class="main">
<div class="left">
</div>
<div class="right">
<div class="scrolling_box">
the box that is scrolled goes right here
</div>
</div>
</div>
<div id="footer">
Footer goes here
</div>
</div>
I'd like it to be stopped at the main class, I have looked a lot of other tutorials and none that I could port it to plain javascript. I tried including the .stop() but it wound up being only for jQuery sadly. I could not replicated the issue in jsfiddle, sadly.
I tried using float:both, left and right but neither seemed to have worked at all.
Almost Solved Check for Demo
$(window).scroll(function(){
var pos = $('#footer').offset();
var top = pos.top;
var pos1 = $('#scrolling_boxI').offset();
var top1 = pos1.top
//alert(top);
if( $(window).scrollTop()<top-150-top1)
{
$("#scrolling_boxI").stop().animate({"marginTop": ($(window).scrollTop()) + "px", "marginLeft":($(window).scrollLeft()) + "px"}, "slow" );
}
});

Categories

Resources