Get static value from variable (scroll function) - javascript

I have a "follow scroll" function, but I want it to turn off when it returns to a certain point. My code is as follows:
scrollSidebar: function(scroll) {
var elemPos = $('#bestvideos-2').offset().top,
scroll2 = scroll;
if(scroll2 >= elemPos) {
$('#bestvideos-2').animate({
'margin-top':(scroll - 315)+'px'
},0);
} else {
$('#bestvideos-2').css('margin-top','0');
}
}
$(window).scroll(function() {
var scrollHeight = $(window).scrollTop();
Scroll.scrollSidebar(scrollHeight);
})
The problem is - every time I get up, it goes way up, not following scroll. What I'm thinking is storing a variable elemPos somewhere and keep it static (now it's changing each time I scroll).
What can I do with this?

Pass the value to the scrollSidebar function - make sure that the var elemPos = $('#bestvideos-2').offset().top is executed on dom ready
scrollSidebar: function (elemPos, scroll) {
var scroll2 = scroll;
if (scroll2 >= elemPos) {
$('#bestvideos-2').animate({
'margin-top': (scroll - 315) + 'px'
}, 0);
} else {
$('#bestvideos-2').css('margin-top', '0');
}
}
var elemPos = $('#bestvideos-2').offset().top
$(window).scroll(function () {
var scrollHeight = $(window).scrollTop();
Scroll.scrollSidebar(elemPos, scrollHeight);
})

Related

Make element stick to top when scrolling

I've written a function to make a div element stick to top when scrolling.
it works when it's written like this('#sticky-anchor-for-social' is to detect moving distance of the element, '#social-media' is the element sticks):
function sticky_socialmedia() {
var window_top = $(window).scrollTop();
var social_top = $('#sticky-anchor-for-social').offset().top - 88;
if (window_top >= social_top) {
$('#social-media').addClass('stick-social');
} else {
$('#social-media').removeClass('stick-social');
}
}
$(window).scroll(sticky_socialmedia);
sticky_socialmedia();
but it doesn't work when I write it like this:
function stickyWhenScroll(anchor, sticky) {
var window_top = $(window).scrollTop();
var filter_top = $(anchor).offset().top - 88;
if (window_top >= filter_top) {
$(sticky).addClass('stick-filter');
} else {
$(sticky).removeClass('stick-filter');
}
}
$(window).scroll(stickyWhenScroll);
stickyWhenScroll('#sticky-anchor-for-social','#social-media');
what could possibly go wrong?
many thanks!
You need to send your parameters to your function when adding the event, you can do that with bind:
$(window).bind('scroll', {
anchor: '#sticky-anchor-for-social',
sticky: '#social-media'
}, stickyWhenScroll).trigger('scroll');
By passing trigger('scroll') you can trigger the function straight away.
And in your function you can retrieve them by accesing the event.data:
function stickyWhenScroll(event) {
var data = event.data;
var anchor = data.anchor;
var sticky = data.sticky;
...
}
Fiddle
Because in your 2nd snippet the scroll event handler hasn't received any params. You could either pass params both times (load and scroll) or declare those as global variables and use them within the function.
(function stickyWhenScroll(anchor, sticky) {
var window_top = $(window).scrollTop();
var filter_top = $(anchor).offset().top - 88;
if (window_top >= filter_top) {
$(sticky).addClass('stick-filter');
} else {
$(sticky).removeClass('stick-filter');
}
}('#sticky-anchor-for-social', '#social-media'));
$(window).scroll(function() {
stickyWhenScroll('#sticky-anchor-for-social','#social-media');
});

Pop up text after scrolling certain distances is not working

I'm trying to get text to pop up at a fixed location at different y-scroll intervals however, I can't seem to chain the scripts correctly. It seems to skip the first action of displaying the first message.
Code: http://jsfiddle.net/k8bnd/
var startY = 1500;
var stopY = 2000;
$(window).scroll(function(){
checkY();
});
function checkY()
{
console.log($(window).scrollTop());
if($(window).scrollTop() > startY && $(window).scrollTop() <= stopY)
{
console.log("Show");
$('.titleTwo').show();
}
else
{
console.log("Hide");
$('.titleTwo').hide();
} }
checkY();
Your functions should have different names. Try
var startY1 = 900;
var stopY1 = 1800;
var startY2 = 1801;
var stopY2 = 2500;
$(window).scroll(function(){
checkY();
});
function checkY()
{
console.log($(window).scrollTop());
if($(window).scrollTop() > startY1 && $(window).scrollTop() <= stopY1)
{
console.log("Show");
$('.foxedDiv').show();
}
else
{
console.log("Hide");
$('.foxedDiv').hide();
}
if($(window).scrollTop() > startY2 && $(window).scrollTop() <= stopY2)
{
console.log("Show");
$('.foxedDivved').show();
}
else
{
console.log("Hide");
$('.foxedDivved').hide();
}
}
checkY();
Fixed Fiddle:
http://jsfiddle.net/k8bnd/1/
This is happening because you have overwritten the previous values/functions. To make this more dynamic you can add data-* attributes to each message element specifying which positions they are valid for. And then in the scroll event check each element's position data, if the window is within that range show it, otherwise hide it.
HTML
<!-- Changed the classes both elements had to foxedDiv
so that we can select them as a group and loop over them -->
<div class="foxedDiv" data-position="900,1800">
MESSAGE 1
</div>
<div class="foxedDiv" data-position="1801,2500">
MESSAGE 2
</div>
JS
//Note you do not need to make an anonymous
//function just to do the call for checkY
//just pass the function
$(window).scroll(checkY);
function checkY(){
//save this value so we dont have to call the function everytime
var top = $(window).scrollTop();
console.log(top);
$(".foxedDiv").each(function(){
var positionData = $(this).data("position").split(",");
if(top > positionData[0] && top <= positionData[1]){
console.log("Show");
$(this).show();
} else {
console.log("Hide");
$(this).hide();
}
});
}
checkY();
JSFiddle Demo

Floating JQuery menu issues on slower connection

I'm trying to create a floating menu (#quickmenu in left hand sidebar of bottom link) that stops at #weather whilst also re-calculating the bottom = $(\'#weather\').offset().top; every 0.5 seconds...
Page to test: Bristol International Jazz & Blues Festival 2014 | Festival Archive
The recalculation is key as I use expandable content in the main body and because without recaculating on slower connections it doestn't work. I need only #weather.offset.top to be recalculated every 5 seconds, not the whole script otherwise it refreshes and flickers...
I've tried to do code it myself and it's not working, it's 99% not coded correctly but can't figure out what's going wrong? The logic seems to be correct though... if (y >= top && z <= bottom) { ....
<script type="text/javascript">
$(document).ready(function () {
top = $('#quickmenu').offset().top;
var didScroll = false;
$(window).scroll(function() {
didScroll = true;
});
setInterval(function() {
if ( didScroll ) {
didScroll = false;
bottom = $('#weather').offset().top;
y = $(this).scrollTop();
z = y + $('#quickmenu').height();
if (y >= top && z <= bottom) {
// if so, add the fixed class
$('#quickmenu').addClass('fixed');
} else if(z > bottom) {
// otherwise remove it
$('#quickmenu').removeClass('fixed').addClass('absolute');
} else {
// otherwise remove it
$('#quickmenu').removeClass('fixed');
}
}
}, 500);
});
</script>
Thanks for the input, and apologies for lack of clarity within the question. I have fixed my issue by taking another approach. I hope that this is less resource heavy?
<script type="text/javascript">
(function () {
var s = document.querySelector(\'#event-info\').style;
s.overflow = \'inherit\';
s.height = \'auto\';
})();
window.updateQuickMenuPos = function () {
var menu = document.querySelector(\'#quickmenuwrapper\');
var scroll_pos = document.body.scrollTop;
var menu_pos = menu.offsetTop + 10;
var weather = document.querySelector(\'#weather\');
var pos = (scroll_pos - menu_pos);
// min height
if (pos < 0) {
pos = 0;
}
// max height
if (menu_pos + menu.offsetHeight + pos > weather.offsetTop) {
pos = weather.offsetTop - menu.offsetHeight - menu_pos;
}
var s = menu.style;
s[\'webkitTransform\'] = s[\'mozTransform\'] = s[\'transform\'] = \'translateY(\' + pos + \'px)\';
};
jQuery(document).scroll(window.updateQuickMenuPos);
</script>

how to check if the scrollbar has reached at the end of div?

function yHandler () {
var show = document.getElementById('show');
var contentHeight = show.offsetHeight;
var yOffset = show.pageYOffset;
var y = yOffset + show.innerHeight;
if(y >= contentHeight) {
alert("ok")
}
}
show.onscroll = yHandler;
how to check if the scrollbar has reached the end of div?
Some code for you to work on:
var scroll = document.getElementById('scroll');
var content = document.getElementById('content');
scroll.onscroll = function(){
var total = scroll.scrollTop + scroll.clientHeight;
if(total == content.clientHeight)
alert('Reached bottom!');
}
http://jsfiddle.net/EY6qP/
Thor's method works perfectly well (+1), but you could also rely on scrollHeight.
(function(scroll){
scroll.onscroll = function(){
if (scroll.scrollTop + scroll.clientHeight == scroll.scrollHeight) {
console.log('hither!');
}
}
})(document.getElementById('scroll'));
Use scrollHeight, scrollTop and clientHeight attributes to detect the scroll bar reached bottom end or not.
function handleScroll() {
var div = document.getElementById("div-id");
if(Math.abs(Math.round(div.scrollHeight - div.scrollTop) - div.clientHeight) > 3) {
console.log("Scroll bar reached bottom end");
return true;
}
return false;
};

jQuery Scroll Current Position and Next-Prev Navigator

I need a bit of advice as I can't get my noob head around the following, please see this fiddle: http://jsfiddle.net/NtUpw/
The code works as intended, but when the current div offset goes > 41 and prev is hit, I'd like the page to return to the beginning of the current div, not to one before that. Any idea how can I add this condition?
I realise the current code isn't the cleanest (actually it's a combination of two fiddles), but I hope someone could take a look at it anyway. Thanks.
$('a.buttons').on('click', function (e) {
e.preventDefault();
var t = $(this).text(),
that = $(this);
if (t === 'next' && $('.current').next('div.post').length > 0 ) {
var $next = $('.current').next('.post');
var top = $next.offset().top;
$('body').animate({
scrollTop: $('.current').next('div.post').offset().top - 40
});
} else if (t === 'prev' && $('.current').prev('div.post').length > 0 ) {
var $prev = $('.current').prev('.post');
var top = $prev.offset().top;
$('body').animate({
scrollTop: $('.current').prev('div.post').offset().top - 40
});
}
$(window).bind('scroll', function () {
$('.post').each(function () {
var post = $(this);
var position = post.position().top - $(window).scrollTop();
if (position <= 40) {
post.addClass('current');
post.prev().removeClass("current");
} else {
post.removeClass('current');
}
});
});
The prev action works by moving always the div to the previous; the solution is to check the current position of the navigator respect to the current div:
var $prev;
var top;
var firstElem = true;
if ($('.current').prev('div.post').length > 0) {
$prev = $('.current').prev('.post');
top = $prev.offset().top;
firstElem = false
}
var currTop = $('.current').offset().top;
var navBottom = $('.navigation').offset().top + 40;
if (currTop == navBottom && !firstElem) {
$('body,html').animate({
scrollTop: $('.current').prev('div.post').offset().top - 40
});
with this the navigator jumps to the previous div only if is not at the top of the current; alternatively jumps to the previous.
The firefox issue depends on how Firefox places the overflow, it places it at the html level not at body like other browsers.
To let it work you must define the scrolling action with:
$('body,html').animate({
});
Working fiddle: http://jsfiddle.net/IrvinDominin/2QYgR/3/

Categories