How to reduce flicker when scrolling & using jquery offset - javascript

I've got the behavior I want: a target object that stays in the viewport when user scolls down the page (but always stays inside a parent container). The problem is it flickers a lot when scrolling with the mouse. Have a look:
http://jsfiddle.net/3ZQat/5/
Markup:
<div id='container'>
<div id='target'></div>
</div>
Javascript
(function($){
$(document).ready(function(){
// variables
var target = $('#target');
var targetRect = target[0].getBoundingClientRect();
var container = $('#container');
var contRect = container[0].getBoundingClientRect();
var viewportHeight = $(window).height();
// logic conditions
var topOffScreen = false;
var roomForTarget = false;
// scroll event
$(window).scroll(function(){
targetRect = target[0].getBoundingClientRect();
contRect = container[0].getBoundingClientRect();
winTop = $(window).scrollTop();
topOffScreen = (contRect.top < 0);
roomForTarget = (contRect.bottom > target.height());
// if container scrolls off top of viewport
if(topOffScreen && roomForTarget){
target.offset({top:winTop});
target.css('border', 'solid 3px green');
// if container fits in viewport entirely
} else if (roomForTarget) {
target.css('border', 'solid 3px green');
// more code here
// if container no longer fits in viewport
} else {
target.css('border', 'solid 3px red');
// more code here
}
});
});//end document.ready
})(jQuery);
How can I make this less jumpy?

"You can check it here.. jsfiddle.net/nqZu2/2 Might not be everything that you wanted.. but should give you some idea."
From the comments. Thanks

Related

How to Make a certain Div ID show at and after a different Div ID with jQuery

I am trying to make a jQuery code so that my Menu will be hidden on the top section of a page and appear when it is at or past a certain div ID. I have written what I best can to achieve this but is not working. Can anyone help me configure it properly? Thank you.
jQuery (function($){
var topHeader = $('#top-header');
var mainSlider = $('#pbf-main-slider');
if (topHeader >= mainSlider) {
topHeader.show();
} else {
topHeader.hide();
}
});
menu hidden area
menu show area
Final Outcome (I added another section of the menu that needed this function)
jQuery (function($){
var topHeader = $('#top-header');
var mainHeader = $('#main-header');
var mainSlider = $('#pbf-main-slider');
var mainSliderHeight = mainSlider.outerHeight(true);
$(window).scroll(function () {
var scrollTop = $(this).scrollTop(); //get the scroll position
if (scrollTop >= mainSliderHeight) {
topHeader.slideDown(1000);
mainHeader .slideDown(1000);
}
else {
topHeader.hide(500);
mainHeader .hide(500);
}
})
});
you should get the height of the main slider, like this:
var mainSlider = $('#pbf-main-slider');
var mainSliderHeight = mainSlider.outerHeight(true);
then make the top bar appear if the scroll is past the mainSlider's height, like this:
$(window).scroll(function () {
var scrollTop = $(this).scrollTop(); //get the scroll position
if (scrollTop >= mainSliderHeight) {
topHeader.show();
}
else {
topHeader.hide();
}
}

How do I code JQuery so that when I scroll to a certain element, Nav bar appears at top, when I scroll back up past that element, nav bar disappears

I have a div called #menu which I want to display when I scroll past the element #section3, if I scroll up past that element again, I want #menu to disappear
How would I code this?
Maybe something like this?
scrolled = "no"
$(window).scroll(function(){
scr = $("body").scrollTop();
if (scr > 100 && scrolled == "no"){
$("#menu").css({"display:block"})
displayed = "yes"
}
if (displayed == "yes" && scrolled = "yes"){
$("#menu").css({"display:none"})
}
});
The above assumes that #section3 is 100 pixels down the page. If you do not know where its going to be on the page then you could use the method outlined here:
Trigger event when user scroll to specific element - with jQuery
With jQuery you can get the scroll position with $("body").scrollTop();.
Expanding on what #Ned Hulton said, I recommend comparing the scroll position to the top of a "container element" (or 'row') in your page like this:
if ($('body').scrollTop() > $('#someRow').offset().top){
//do something
}
That way you can account for your container appearing at a variable distance down the page (which will come in handy for mobile browsing or cases where your text wraps to additional lines)
I just whipped this up in jsfiddle
https://jsfiddle.net/rb56j0yu/
it uses jQuery, and checks the scroll position against the target div. Css sets the menu as position: fixed, and defaults to hidden.
$(window).scroll(function(){
var yPos = $("body").scrollTop();
var yCheck = $("#c3").position().top;
if (yPos > yCheck && !$("#menu").is(":visible"))
{
$("#menu").show();
}
if (yPos <= yCheck && $("#menu").is(":visible"))
{
$("#menu").hide();
}
});
First, get your #section3 top offset and height. Which will be used as the threshold whether #section3 is actually on the window screen.
var top = $('#section3').offset().top;
var bot = topOffset + $('#section3').height();
Then, detect it on your scroll event.
$(window).on('scroll', function () {
var scrollTop = $(window).scrollTop();
if (scrollTop >= top && scrollTop <= bot) {
// #section3 is within the screen.
$('#menu').show();
}
else {
// #section3 is out of screen.
$('#menu').hide();
}
});
This is a common use case, I wrote following code:
// what does "Auto Header" mean, goto https://www.yahoo.com/
// scroll down and you will see the purple part auto fixed to top,
// while when scroll up, it restores and does not be fixed.
// 1. multiple auto header elements handled
// 2. dynamically create/remove elements issue handled
// 3. no unnecessary dom operation, high performance
// usage: just add 'class="auto-header"' to any element you want to auto header
// suggest set each auto-header element specific width and height
// do not guarantee it works when resize or scroll left/right
$(document).ready(function() {
var rawTops = [],
rawLefts = [],
rawStyles = [],
$locations = [], // record next sibling so that element easily find where to restore
fixed = []; // mark whether this element is fixed
$(".auto-header").each(function() {
var $this = $(this),
offset = $this.offset();
rawTops.push(offset.top);
rawLefts.push(offset.left);
rawStyles.push($this.attr("style"));
$locations.push($this.siblings().eq($this.index()));
fixed.push(false);
});
$(window).on("scroll", function() {
$(".auto-header").each(function(i, e) {
if(!fixed[i] && $(window).scrollTop() > rawTops[i]) {
var $te = $(this).clone(true);
$(this).remove();
$locations[i].before($te);
$te.css({
"position": "fixed",
"top": 0,
"left": rawLefts[i],
"z-index": 100
});
fixed[i] = true;
} else if(fixed[i] && $(window).scrollTop() < rawTops[i]) {
$(this).removeAttr("style").attr("style", rawStyles[i]);
fixed[i] = false;
}
});
});
});

Change styles when scrolling down (javascript)

I'm rebuilding my webpage, make it more elegant so I decided that I would modify the top bar when the user scrolls down, make it smaller and hide some elements it has. I have the function that triggers when you scroll down, but for some reason it does nothing.
My HTML:
<div class="maindiv">
<img src="media/cgaline.png" id="cgalinepic" class="cgalinepic">
<a id="right-panel-link" href="#right-panel"><img src="media/menu.png" id="open_menu_button" width="50px" height="50px"></a>
<h2 class="h1-3" id="h1-3">
We are not in danger, we ARE the danger.
</h2>
</div>
I don't know what's going wrong since I dedicate most of my time in php and I find javascript a little hard.
I also tried doing this:
$('#maindiv').style.height = "50px";
But doesn't work neither.
My final javascript code (thanks to Sagi and Ilya Sviridenko):
var div = $('.maindiv');
var pic = $('.cgalinepic');
var menu = $('.open_menu_button');
var text = $('.h1-3');
$(function(){
var div = $('.maindiv');
var pic = $('#cgalinepic');
var menu = $('#open_menu_button');
var text = $('#h1-3');
$(document).scroll(function() {
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
div.css("height", "50px");
pic.css({ width : "400px", height : "50px" });
text.hide();
menu.css("top", "0px");
} else {
div.css("height", "140px");
pic.css({ width : "800px", height : "100px" });
text.show();
menu.css("top", "47px");
}
lastScrollTop = st;
});
});
});
You may use jQuery only after DOM is ready. Wrap your JS code like this:
$(function(){
...
});
Final solution, with Sagi code:
$(function(){
var div = $('#maindiv');
var pic = $('#cgalinepic');
var menu = $('#open_menu_button');
var text = $('#h1-3');
$(document).scroll(function() {
div.css("height", "50px");
pic.css({ width : "400px", height : "50px" });
text.css("visibilty", "hidden");
menu.css("top", "0px");
});
});
you are using jQuery already.Just continue to use jQuery API
div.css("height", "50px");
pic.css({ width : "400px", height : "50px" });
text.css("visibilty", "hidden"); // did you mean to hide the text completly? If so use text.hide();
menu.css("top", "0px");

Need to trigger an event as footer comes into view

I have a deep page with a deep footer
I want to use some jQuery to trigger an event when the top of the footer comes into view
I have looked and tried using
var scrollTop = jQuery (window).scrollTop();
but it just gives the position when you load, and it doesn't change as you scroll
Any ideas please
You can use my script on this answer: Pause and play video when in viewport
Fiddle: http://jsfiddle.net/pwhjk232/
$(document).ready(function() {
var inner = $(".inner");
var elementPosTop = inner.position().top;
var viewportHeight = $(window).height();
$(window).on('scroll', function() {
var scrollPos = $(window).scrollTop();
var elementFromTop = elementPosTop - scrollPos;
if (elementFromTop > 0 && elementFromTop < elementPosTop + viewportHeight) {
inner.addClass("active");
} else {
inner.removeClass("active");
}
});
})

Menu that fit to the buttom/top of the screen

I saw a cool style/js function (I can tell what it is) that implemented on a side menu.
You know the situation when you have a long center page and one of / both of you sides ends and that leave a blank space? Well this site implemented this thing that just when the user scrool to the place where the side menu end - the menu get absolute postion and doesnt move.
How can I do this?
If you want to see an example you can look here (just scroll and look on the sides)
I believe you can achieve similar effect using this: http://www.wduffy.co.uk/blog/keep-element-in-view-while-scrolling-using-jquery/comment-page-1/ (just making it move with 0 as speed parameter instead of slow, as in the example) and adding conditions about whether the current position fits within the box it is displayed (you can take height of the box - menu being moved on page or box that contains the menu - by using .height() jQuery function).
EDIT:
The page you referenced uses the following JavaScript code to support what you try to accomplish:
<script type="text/javascript">
$(function(){
var seoHeight = $$('dvIndexSeoMaster').height();
seoHeight = (seoHeight > 0) ? seoHeight : 0;
var documentHeight = $(document.body).height() - 120 - seoHeight;
var fixedMode = false;
var hasFixedClass = false;
var leftColElm = $sc('dvFixed');
var leftColPos = leftColElm.offset().top;
var leftColHeight = leftColElm.height();
var rightColElm = $$('dvIndexMasterRightCol');
var rightColPos = rightColElm.offset().top;
var rightColHeight = rightColElm.height();
function scrollElm(elmPos,elmHeight,objElm, cssClass){
var fixedMode = false;
var hasFixedClass = false;
var windowTop = $(window).scrollTop();
(windowTop >= elmPos && (windowTop + elmHeight) < documentHeight) ? fixedMode = true : fixedMode = false;
if( fixedMode){
$(objElm).addClass(cssClass);
hasFixedClass = true;
}else if( (fixedMode == false)){
$(objElm).removeClass(cssClass);
hasFixedClass = false;
}
};
$(window).scroll(function(){
scrollElm(leftColPos,leftColHeight,leftColElm,'make-fixed');
scrollElm(rightColPos,rightColHeight,rightColElm, 'make-fixed');
});
});
</script>
And the make-fixed CSS class has the following definition:
.make-fixed {
position: fixed;
top: 0;
z-index: 200;
}
You can make an element stay in the same place, even as the user scrolls, with the CSS position:fixed property: http://www.w3.org/TR/CSS2/visuren.html#fixed-positioning

Categories