Sticky div scrolls too far - javascript

I have a jquery code which makes an existing element follow the scroll of the user. I want it to stop when reaching a certain element #header-line, but it's not consistent. On some PDPs it scrolls and stops there, on others, it scrolls past the line.
Page: https://www.norli.no/to-pappaer
(Code is not activated here)
jQuery
require(['jquery'], function($){
$(document).ready(function() {
(function($) {
var element = $('.product-add-form'),
originalY = element.offset().top;
var hr = $('#header-line > hr');
topOfLine = hr.offset().top;
var topMargin = 250;
element.css('position', 'relative');
$(window).on('scroll', function(event) {
var scrollTop = $(window).scrollTop();
var nextPosition = scrollTop - originalY + topMargin;
var maxPositionAllowed = topOfLine - 1000;
element.stop(false, false).animate({
top: scrollTop + 250 < originalY ? 0 : Math.min(nextPosition, maxPositionAllowed )
}, 0);
});
})(jQuery);
});
});

You could definitely take advantage of using position: sticky if you are able to make sure all parent elements of the sticky element have overflow: visible
In that link you posted, if you wanted .product-add-form to be position: sticky you would have to make sure .off-canvas-wrapper has the overflow: hidden changed to overflow: visible.
I made an example fiddle of that page you shared so you could see how easy it would be to make that side form sticky.
https://jsfiddle.net/treckstar/d30phae8/8/

Related

Can I reset a jQuery sticky navbar function?

I'm new here and I'm facing a little problem with a jQuery script I'm using to change my CSS when my sticky navbar scrolls over a certain section.
First, I'm using one class called ".stickychange", which is the trigger for the jQuery function. On this section, I'm using a background-image (one picture I've taken personally), and I want my white navbar to become transparent black when it's over this said section. And it's working like a charm. But after this section, I have a white section and I want my navbar to take its default style, but it doesn't.
If I'm scrolling back to the top, it's taking its default settings, but if I'm scrolling past the .stickychange, it would stay with the tweaked CSS styles.
Do you know how to reset a function, or at least, stop it when it reaches a certain point?
Here's the code, it's a basic code if you wanna change styles on elements while scrolling :
var scroll_start = 0;
var startchange = $(".stickychange");
var offset = startchange.offset();
if (startchange) {
$(document).scroll(function () {
scroll_start = $(this).scrollTop();
if (scroll_start > offset.top) {
$("#menu_top").css('background-color', 'rgba(0,0,0,0.5)');
$("#menu_top").css('transition', 'all 0.2s ease-in');
$("#menu_top a").addClass("stickyspecial");
$("#menu_top h2").addClass("stickyname");
} else {
$('#menu_top').css('background-color', '#fff');
$('#menu_top a').removeClass("stickyspecial");
$('#menu_top h2').removeClass("stickyname");
}
});
}
Thanks, guys in advance! :)
Get the height of the div and add this to your if.
var scroll_start = 0;
var startchange = $(".stickychange");
var offset = startchange.offset();
// Get the height with padding and border
// You could use .height() if you just want the height of the div.
var endchange = startchange.outerHeight();
if (startchange) {
$(document).scroll(function () {
scroll_start = $(this).scrollTop();
if (scroll_start > offset.top && scroll_start < offset.top + endchange) { //<- Add it here
$("#menu_top").css('background-color', 'rgba(0,0,0,0.5)');
$("#menu_top").css('transition', 'all 0.2s ease-in');
$("#menu_top a").addClass("stickyspecial");
$("#menu_top h2").addClass("stickyname");
} else {
$('#menu_top').css('background-color', '#fff');
$('#menu_top a').removeClass("stickyspecial");
$('#menu_top h2').removeClass("stickyname");
}
});
}
If you're using margin on the div and want it to be applied, use .outerHeight(true).

Animate div detect top or bottom of it

I want my div to animate when that div is almost half while scrolling.
How can I do it? It's not on a fixed div but its like sticky sidebar
Just like on this website sample
this is my code
$(function(){ // document ready
if ($('.filter-container').length) { // make sure ".filter-container" element exists
var el = $('.filter-container');
var stickyTop = $('.filter-container').offset().top; // returns number
var stickyHeight = $('.filter-container').height();
$(window).scroll(function(){ // scroll event
var limit = $('#footer').offset().top - stickyHeight - 100;
var windowTop = $(window).scrollTop(); // returns number
if (stickyTop < windowTop){
el.css({ position: 'fixed', top: 0, width: 280 });
}
else {
el.css({ position: 'static', width: 280 });
}
if (limit < windowTop) {
var diff = limit - windowTop;
el.css({top: diff});
}
});
}
});
You could write a jQuery function using Waypoints.
Or more easily (in my opinion) but with higher payload cost use Bootstrap affix. In this case you keep your current css but then add some Bootstrap properties to the div, in your case:
<div class="filter-container" data-spy="affix" data-offset-top="60" data-offset-bottom="200">
This will add the classes .affix-top to the div UNTIL the user scrolls past 60px. Then if will change to .affix when the user gets 200px from the bottom it will change to .affix-bottom to the class.
This jsfiddle shows it quite well:
http://jsfiddle.net/skelly/df8tb/
This shows the appropriate css to get the sticky effect.

A cleaner way for a fixed div at bottom of the window but stays above the footer and triggers on page width

I've created a sticky bar to stay at the bottom of the window. As the user scrolls down to the bottom of the page the same bar will stay fixed until the footer shows, then removes its fixed position, temporarily, to stay above the footer until the user scrolls back up and it remains fixed again.
I only want to happen when the page is wider than 680px. Anything under that will keep the sticky bar in a default position (CSS: position:inherit).
This is the website: http://ttd.firefly-digital.co.uk
It works as expected. However, when I test on Chrome in Mac it triggers my CPU fan which suggests this not very efficient and with my limited JavaScript skills, wondered if there is a cleaner way to achieve this is?
This is the current js code:
$(window).scroll(function(event) {
var scroll = $(this).scrollTop();
var docHeight = $(document).height();
var windowHeight = $(window).height();
var footerHeight = $('.footer').height();
if(docHeight - (windowHeight + scroll) < footerHeight) {
$('.contact-bar').css({
bottom: footerHeight - (docHeight - (windowHeight + scroll))
});
} else {
$('.contact-bar').css({
bottom: 0
});
}
});
var windowWidth = $(window).width();
$(window).resize(function() {
windowWidth = $(window).width();
if(windowWidth > 680) {
$('.contact-bar').css({
position: "fixed"
});
} else {
$('.contact-bar').css({
position: "inherit"
});
}
});
CSS code
.contact-bar {
background: $contact-bar;
width: 100%;
height: 40px;
text-align: center;
position: fixed;
bottom: 0;
z-index: 10;
}
You can do it in reverse. Make it so that the bar, without position fixed, is above the footer without any JavaScript (incl. media queries). Than add a fixed class with position:fixed and bottom:0 that will be added accordingly. Like so:
.contact-bar.fixed { position:fixed; bottom:0; }
The jquery code that will trigger this, is as follows:
$(window).scroll(function (event) {
var windowTop = $(this).scrollTop();
if (windowTop >= $(".footer").offset().top) {
$(".contact-bar").addClass("fixed");
} else {
$(".contact-bar").removeClass("fixed");
}
});
Then add a few lines that the above code will only fire if the window width is > 680, either with jquery or pure javascript. For example with:
if ($(window).width() < 960) { // above function }
Do note I have not tested this, so please comment if it doesn't work. Credit: Preventing element from displaying on top of footer when using position:fixed
You better use classes to target your elements, at least to prevent jQuery from traversing the whole DOM using selectors appropriately which is good in performance.

Make html element stay in place when scrolled past

How does one make an html element not become fixed until it has been scrolled to? So while the user is scrolling it will be in normal position, but it won't go out of the screen after the user has scrolled past it?
Attach a listener to the onscroll event, and if the scrollTop is greater than the element's Y position, set it to position: fixed.
I've used this code before:
http://www.webdeveloperjuice.com/2011/08/07/how-to-fix-element-position-after-some-scroll-using-jquery/
(function($){
$.fn.scrollFixed = function(params){
params = $.extend( {appearAfterDiv: 0, hideBeforeDiv: 0}, params);
var element = $(this);
if(params.appearAfterDiv)
var distanceTop = element.offset().top + $(params.appearAfterDiv).outerHeight(true) + element.outerHeight(true);
else
var distanceTop = element.offset().top;
if(params.hideBeforeDiv)
var bottom = $(params.hideBeforeDiv).offset().top - element.outerHeight(true) - 10;
else
var bottom = 200000;
$(window).scroll(function(){
if( $(window).scrollTop() > distanceTop && $(window).scrollTop() < bottom )
element.css({'position':'fixed', 'top':'5px'});
else
element.css({'position':'static'});
});
};
})(jQuery);
Then just call the elements:
$(document).ready( function(){
$("#scrollingDiv").scrollFixed({appearAfterDiv:'.sidebar p', hideBeforeDiv:'.footer'});
$("#scrollingDiv1").scrollFixed({hideBeforeDiv:'.footer'});
});
Have a look at the jQuery Scrollfollow plugin. I have used this to achieve that effect conveniently.
You simply call it on the element that you want to stay in view:
<script type="text/javascript">
$( '#example' ).scrollFollow();
</script>
Easing, position and other parameters can be configured.

Javascript: have div always remain at the top when it reaches the top edge of browser with jquery

how to have a div that always stay on the screen? Lets say i have a div at the left hand site. When the browser is scroll to the bottom, the div will remain there ONLY when its' top reaches the top edge of browser screen so that it will not be hidden. I am using jquery too.
Thank you.
here is a Good ScreenCast By RemySharp Regarding this Issue
http://jqueryfordesigners.com/fixed-floating-elements/
Demo Page :
http://static.jqueryfordesigners.com/demo/fixedfloat.html
You need to invoke .scrollTop() on the window and compare that with the offset top value from that DIV.
$(window).bind('scroll', function(e){
var $div = $('.top').
sTop = $(window).scrollTop();
if($div.offset().top <= sTop)
$div.css('top', sTop);
else
$div.css('top', '100px');
});
Whereas in this example, .top is the element which should stay at top.
Example: http://www.jsfiddle.net/2C6fB/8/
If you want it to always stay in thesame place, you can use the css property position: fixed; else you can use a combination of $(window).scroll() and .scrollTop(); to detect where your div is in relation to the screen and apply the right positioning.
/* PlugTrade.com - Sticky Top jQuery Plugin */
jQuery.fn.sticky_top = function () {
/* check for our hidden div.. create it if it doesn't exist */
if (!this.find("#sticky_top").length > 0)
this.append("<div id='sticky_top' style='display:none'>"+this.css('top')+"</div>");
var thisdiv = this;
$(window).bind('scroll', function(e){
var initval = thisdiv.find("#sticky_top").text();
var wintop = $(window).scrollTop();
var boxtop = initval.replace(/px/i, "");
if(wintop >= boxtop)
{
if ( $.browser.msie )
{
thisdiv.css('top', wintop+'px');
} else {
thisdiv.css('position', 'fixed');
thisdiv.css('top', '0');
}
// console.log(boxtop+':'+wintop);
/* thisdiv.css('top', wintop+'px'); */
}
else
{
thisdiv.css('position', 'absolute');
thisdiv.css('top', initval);
}
});
}
You can use like this:
$('#div1').sticky_top();
Keep your div position: fixed;

Categories

Resources