views:

681

answers:

3

example page

I have a floating menu that i've built to the left side (green), and i've made it start moving after 200 pixels. and now i need to to stop and not go over the footer (blue) area. any ideas how to make my JS better?

this thing is, I cannot check this on the scroll event, because of the animation going on after i scroll, so it needs to be done someway else.

so how to make the animation stop at the end just before the footer?

A: 

In the $(window).scroll function have you checked whether the bottom position of the floating div is less than or equal to the top position of the footer element.

rahul
can't do that. when i scroll and the $(window).scroll is triggered, the animation kicks in. and i don't know where it gonna take the menu to after it starts.
vsync
+2  A: 
$.fn.menuFloater = function(options) {
 var opts = $.extend({ startFrom: 0, offsetY: 0, attach: '', duration: 50 }, options);
 // opts.offsetY
 var $obj = this;
 $obj.css({ position: 'absolute' /*, opacity: opts.opacity */ });


 /* get the bottom position of the parent element */
 var parentBottomPoint = $obj.parent().offset().top + $obj.parent().height() ; 
 var topMax = $obj.parent().height() - $obj.innerHeight() + parseInt($obj.parent().css('padding-top')); //get the maximum scrollTop value
 if ( topMax < 0 ) {
  topMax = 0;
 }

 console.log(topMax);

 $(window).scroll(function () { 
  $obj.stop(); // stop all calculations on scroll event
  // console.log($(document).scrollTop() + " : " + $obj.offset().top);

  /* get to bottom position of the floating element */
  var isAnimated = true;
  var objTop= $obj.offset().top;
  var objBottomPoint = objTop + $obj.outerHeight();

  if ( ( $(document).scrollTop() > opts.startFrom || (objTop - $(document).scrollTop()) > opts.startFrom ) && ( $obj.outerHeight() < $(window).height() ) ){
   var adjust;
   ( $(document).scrollTop() < opts.startFrom ) ? adjust = opts.offsetY : adjust = -opts.startFrom + opts.offsetY;
   // and changed here to take acount the maximum scroll top value
   var newpos = ($(document).scrollTop() + adjust );
   if ( newpos > topMax ) {
    newpos = topMax;
   }
   $obj.animate({ top: newpos }, opts.duration, function(){ isAnimated = false } );
  }
  else {
   $obj.stop();
  }
 });

};
Ramuns Usovs
+1 confirmed that this works. There are some superfluous things in there though. For instance, the 'isAnimated' value is irrelevant as the animation is being stopped regardless.
KyleFarris
Well all I did was add the things that were needed to prevent the menu going lower that it had to, I didn't remove any of the original code, leaving removal of the useless things as an exercise to the original author :)
Ramuns Usovs
yes, excellent! very good, thanks! I will clean the code now, i know there are irrelevant things in it.thank. why do you check - if( topMax < 0 ) ?anyway i don't think its necessary because i disabled animation ifthe window size is smaller than the menu, because the user must see it all.
vsync
Oh you know - just in case :)
Ramuns Usovs
+1  A: 

I've resolved the issue perfectly (hope so)
with the help of you guys, and released
a jQuery plugin for floating sticky boxes:


http://plugins.jquery.com/project/stickyfloat

vsync