How use sidebar position when scoll up - javascript

I have a 2 column layout. The left column is way longer than the sidebar. I want the sidebar only to stick when its bottom reaches the bottom of the browser window. So the user can continue to scroll down the left column content while the right sidebar sticks.. how use jquery and javascipt
$(function() {
var $window = $(window);
var lastScrollTop = $window.scrollTop();
var wasScrollingDown = true;
var $sidebar = $("#sidebar");
if ($sidebar.length > 0) {
var initialSidebarTop = $sidebar.position().top;
$window.scroll(function(event) {
var windowHeight = $window.height();
var sidebarHeight = $sidebar.outerHeight();
var scrollTop = $window.scrollTop();
var scrollBottom = scrollTop + windowHeight;
var sidebarTop = $sidebar.position().top;
var sidebarBottom = sidebarTop + sidebarHeight;
var heightDelta = Math.abs(windowHeight - sidebarHeight);
var scrollDelta = lastScrollTop - scrollTop;
var isScrollingDown = (scrollTop > lastScrollTop);
var isWindowLarger = (windowHeight > sidebarHeight);
if ((isWindowLarger && scrollTop > initialSidebarTop) || (!isWindowLarger && scrollTop > initialSidebarTop + heightDelta)) {
$sidebar.addClass('fixed');
} else if (!isScrollingDown && scrollTop <= initialSidebarTop) {
$sidebar.removeClass('fixed');
}
var dragBottomDown = (sidebarBottom <= scrollBottom && isScrollingDown);
var dragTopUp = (sidebarTop >= scrollTop && !isScrollingDown);
if (dragBottomDown) {
if (isWindowLarger) {
$sidebar.css('top', 0);
} else {
$sidebar.css('top', -heightDelta);
}
} else if (dragTopUp) {
$sidebar.css('top', 0);
} else if ($sidebar.hasClass('fixed')) {
var currentTop = parseInt($sidebar.css('top'), 10);
var minTop = -heightDelta;
var scrolledTop = currentTop + scrollDelta;
var isPageAtBottom = (scrollTop + windowHeight >= $(document).height());
var newTop = (isPageAtBottom) ? minTop : scrolledTop;
$sidebar.css('top', newTop);
}
lastScrollTop = scrollTop;
wasScrollingDown = isScrollingDown;
});
}
});
SeeDemo
i have this error when scroll top
i wanted this style

Related

Slow scroll when detect image

I have the problem with the scenario.
We have a page with text which is scrollable
When image is detected, scrolling should be slower
When image is over, scrolling gets back to default speed.
I have detection of element and trying to do slowing scroll with using transform, but without luck. It is slower a little bit, but it does not look like properly.
function elementInViewport2(el) {
var top = el.offsetTop;
var left = el.offsetLeft;
var width = el.offsetWidth;
var height = el.offsetHeight;
while(el.offsetParent) {
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;
}
return (
top < (window.pageYOffset + window.innerHeight) &&
left < (window.pageXOffset + window.innerWidth) &&
(top + height) > window.pageYOffset &&
(left + width) > window.pageXOffset
);
}
/*window.addEventListener('scroll', function(e) {
var el = document.getElementById('slides');
console.log(elementInViewport2(el));
});*/
$.fn.moveIt = function(){
var $window = $(window);
var instances = [];
$(this).each(function(){
instances.push(new moveItItem($(this)));
});
window.addEventListener('scroll', function(){
var scrollTop = $window.scrollTop();
var el = document.getElementById('slides');
if (elementInViewport2(el)) {
instances.forEach(function(inst){
inst.update(scrollTop, -20);
});
}
}, {passive: true});
}
var moveItItem = function(el){
this.el = $(el);
console.log(el);
this.speed = parseInt(this.el.attr('data-scroll-speed'));
};
moveItItem.prototype.update = function(scrollTop, speed){
this.el.css('transform', 'translateY(' + -(scrollTop / speed) + 'px)');
};
// Initialization
$(function(){
$('[data-scroll-speed]').moveIt();
});
https://jsfiddle.net/pnrszyzn/

How can I write jquery plugin that works on multiple elements

I wrote following functon and I am trying to use that in different elements but it doesn't work.
$.fn.sticky = function() {
var
scrollTop = $(window).scrollTop();
replace_class = $(this),
sticky = "ceras_sticky_header",
elementOffset = replace_class.offset().top,
distance = (elementOffset - scrollTop),
leftPositionofImage = replace_class.offset().left,
windowWidth = $(window).width(),
elementWidth = replace_class.width(),
rightPosition = (windowWidth - leftPositionofImage - elementWidth - 12);
$(window).scroll(function() {
if( $(this).scrollTop() > distance) {
replace_class.addClass(sticky);
replace_class.css('right',rightPosition);
replace_class.draggable();
} else {
replace_class.removeClass(sticky);
}
});
};
I want to it to work like:
$( ".ancor_controls" ).sticky();
$( ".ancor_controls1" ).sticky();

Set top of page to 340px from top with jQuery

Currently I have a script which starts a progress bar the moment a user starts scrolling.
Is it possible to change this to when the user gets to 340px from the top of the page?
Here is a demo of my site: http://pixsols.com/test/wordpress/reading-progress/
Here is my current code:
(function ( $ ) {
$.fn.progressScroll = function(options) {
var settings = $.extend({
fontSize : 20,
color : '#009ACF',
height : '5px',
textArea : 'dark',
}, options);
// element state info
var docOffset = $(this).offset().top,
elmHeight = $(this).height(),
winHeight = $(window).height();
// listen for scroll changes
$(window).on('scroll', function() {
var docScroll = $(window).scrollTop(),
windowOffset = docOffset - docScroll,
viewedPortion = winHeight + docScroll - docOffset;
if($(window).scrollTop() > 0) {
if($('.scrollWrapper').hasClass('hidden')) {
$('.scrollWrapper').removeClass('hidden').hide();
$('.scrollWrapper').slideDown('slow');
}
} else {
$('.scrollWrapper').slideUp('slow');
$('.scrollWrapper').addClass('hidden');
}
if(viewedPortion < 0) { viewedPortion = 0; }
if(viewedPortion > elmHeight) { viewedPortion = elmHeight; }
// calculate viewed percentage
var viewedPercentage = viewedPortion / elmHeight;
// set percent in progress element
$('.scroll-bar').css('width', (viewedPercentage*100)+'%' );
});
var self = this;
$(window).on('resize', function() {
docOffset = $(self).offset().top;
elmHeight = $(self).height();
winHeight = $(window).height();
$(window).trigger('scroll');
});
$(window).trigger('scroll');
var $el = $('.scroll-bar').css(settings);
return $el;
};
}( jQuery ));
My guess would be to manipulate this:
windowOffset = docOffset - docScroll,
Probably you should add or subtract 320px from windowOffset. So for example"
windowOffset = docOffset - docScroll + 320,

Parallax H1 and H2

Can someone tell me how to adjust this .js? I want it to be able to apply on H1 and H2 with an ID in my html. Now it is only working on css background-image. Below is the .js I'm using. I'm a beginner with javascript;)
Hope you guys can help me out!
(function( $ ){
var $window = $(window);
var windowHeight = $window.height();
$window.resize(function () {
windowHeight = $window.height();
});
$.fn.parallax = function(xpos, speedFactor, outerHeight) {
var $this = $(this);
var getHeight;
var firstTop;
var paddingTop = 0;
//get the starting position of each element to have parallax applied to it
$this.each(function(){
firstTop = $this.offset().top;
});
if (outerHeight) {
getHeight = function(jqo) {
return jqo.outerHeight(true);
};
} else {
getHeight = function(jqo) {
return jqo.height();
};
}
// setup defaults if arguments aren't specified
if (arguments.length < 1 || xpos === null) xpos = "50%";
if (arguments.length < 2 || speedFactor === null) speedFactor = 0.1;
if (arguments.length < 3 || outerHeight === null) outerHeight = true;
// function to be called whenever the window is scrolled or resized
function update(){
var pos = $window.scrollTop();
$this.each(function(){
var $element = $(this);
var top = $element.offset().top;
var height = getHeight($element);
// Check if totally above or totally below viewport
if (top + height < pos || top > pos + windowHeight) {
return;
}
$this.css('backgroundPosition', xpos + " " + Math.round((firstTop - pos) * speedFactor) + "px");
});
}
$window.bind('scroll', update).resize(update);
update();
};
})(jQuery);
It should be background-position. Can you try changing?
$this.css('background-position', xpos + " " + Math.round((firstTop - pos) * speedFactor) + "px");

Add a class to the sections once they are visible in viewport

This is how I am trying but the condition would never fire..
$(window).scroll(function(e){
var scrollTop = $(window).scrollTop();
var viewportHeight = $(window).height();
$('section').each(function(){
var top = $(this).offset().top;
var bottom = top + $(this).height();
if(top <= scrollTop && bottom >= (scrollTop + vieportHeight) ){
$(this).addClass('visible');
console.log('Hola');
}else{
console.log(top,bottom,scrollTop,viewportHeight);
}
});
});
Fiddle: http://jsfiddle.net/rYeMC/
Any idea whyat i'm doing wrong?
In addition to the typo, you have a slight math error. The easiest way I've found to determine if an element is onscreen is to determine the top and bottom of the viewport and compare that with the top and bottom of the element:
$(document).ready(function () {
var viewport = $(window),
setVisible = function (e) {
var viewportTop = viewport.scrollTop(),
viewportBottom = viewport.scrollTop() + viewport.height();
$('section').each(function () {
var self = $(this),
top = self.offset().top,
bottom = top + self.height(),
topOnScreen = top >= viewportTop && top <= viewportBottom,
bottomOnScreen = bottom >= viewportTop && bottom <= viewportBottom,
elemVisible = topOnScreen || bottomOnScreen;
self.toggleClass('visible', elemVisible);
});
};
viewport.scroll(setVisible);
setVisible();
});
Working fiddle: http://jsfiddle.net/rYeMC/2/
Looks like what you want:
http://jsfiddle.net/rYeMC/1/
$(function () {
$(window).scroll(function (e) {
var scrollTop = $(window).scrollTop();
var viewportHeight = $(window).height();
$('section').each(function () {
var top = $(this).offset().top;
var bottom = top + $(this).height();
if (top <= scrollTop && bottom >= (scrollTop + viewportHeight)) {
$(this).addClass('visible');
} else {
console.log(top, bottom, scrollTop, viewportHeight);
$(this).removeClass('visible');
}
});
});
});
everything's fine with your code. just correct the typo (vieport) and be aware that the style attribute overrules your external css!
This is the condition
if(scrollTop + viewportHeight >= top ){
$(this).addClass('visible');
}

Categories