CSS or Browser issue with a position: fixed while jquery script

326
November 26, 2016, at 11:43 AM

Here is codepen example. Scroll down to tab block. If you scroll top it adds class 'sticked' and if it reaches bottom of parrent element it gets 'sticked2' class. The issue is: when you set top: 0 it works perfect. But when you set the 'sticked' class with top: 1px or more, it bugges (?) and script stops working. Why is it so? UPD Added link to codepen to understand the issue.

var $window = $(window); 
 
$window.scroll(function() { 
  var labels = $('.forlabels'), 
    labelsSec = $('.forlabels-section'), 
    bottomOfLabels = labels.outerHeight() + labels.offset().top, 
    bottomOfLabelsSec = labelsSec.outerHeight() + labelsSec.offset().top, 
    topOfLabels = labels.offset().top, 
    topOfLabelsSec = labelsSec.offset().top, 
    isAboveTopSec = $window.scrollTop() < topOfLabelsSec, 
    isAboveTop = $window.scrollTop() < topOfLabels, 
    isBelowTop = $window.scrollTop() >= topOfLabels, 
    isBelowBottom = bottomOfLabelsSec <= bottomOfLabels; 
 
 
  if (!isAboveTopSec && ((isBelowTop && !isBelowBottom) || isAboveTop)) { 
 
    $('.forlabels') 
      .addClass('sticked') 
      .removeClass("sticked2") 
      .text("Sticked"); 
  } else if (isBelowBottom) { 
 
    $('.forlabels') 
      .addClass('sticked2') 
      .removeClass('sticked') 
      .text("Scrolled Below Bottom"); 
  } else { 
 
    $('.forlabels') 
      .removeClass('sticked sticked2') 
      .text("Not sticked "); 
  } 
 
 
});
* { 
  box-sizing: border-box; 
} 
.one-half { 
  position: relative; 
  padding: 0 10px; 
} 
.one-half { 
  -webkit-box-flex: 1; 
  -ms-flex: 1 45%; 
  flex: 1 45%; 
  -webkit-flex: 1 45%; 
  min-width: 300px; 
  border: 1px solid red; 
  height: 100%; 
} 
.fbox { 
  height: 1800px; 
  margin-top: 100px; 
  border: 1px solid #000; 
  display: flex; 
  align-items: flex-start; 
} 
.forlabels-section { 
  height: 500px; 
  background: green; 
  position: relative; 
} 
.forlabels { 
  height: 100px; 
  background: #777; 
} 
.forlabels, 
.forlabels-section { 
  width: 200px; 
} 
.sticked { 
  position: fixed; 
  top: 0; 
  bottom: inherit; 
} 
.sticked2 { 
  bottom: 0px; 
  position: absolute; 
  top: inherit; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<div class="fbox"> 
 
  <div class="forlabels-section"> 
    <div class="forlabels">Untouched Column</div> 
  </div> 
 
  <div class="one-half columned"> 
  </div> 
 
</div>

Answer 1

The issue is that by adding the top on the element , you also need to recalculate the value of $(window).scrollTop() based on the top edge added for comparison between with the other calculated variables.

CSS :

.sticked{
  position: fixed;
  top: 1px;
  bottom: inherit;
}

JS :

var $window = $(window);
$window.scroll(function() {
  var windowScrollTop = $window.scrollTop(); // created a variable for $window.scrollTop() value.
  if($('.forlabels').hasClass('sticked')) // check if the element has class 'sticked' which adds the top margin of 1px;
       windowScrollTop++; // if so, add 1 to $window.scrollTop()
  else if($('.forlabels').hasClass('sticked2'))
       windowScrollTop--;
  var labels = $('.forlabels'),
      labelsSec = $('.forlabels-section'),
      bottomOfLabels = labels.outerHeight() + labels.offset().top,
      bottomOfLabelsSec = labelsSec.outerHeight() + labelsSec.offset().top,
      topOfLabels = labels.offset().top,
      topOfLabelsSec = labelsSec.offset().top,
      isAboveTopSec = windowScrollTop < topOfLabelsSec, // replace reference to $(window).scrollTop() with the variable.
      isAboveTop = windowScrollTop < topOfLabels, // replace reference to $(window).scrollTop() with the variable.
      isBelowTop = windowScrollTop >= topOfLabels, // replace reference to $(window).scrollTop() with the variable.
      isBelowBottom = bottomOfLabelsSec <= bottomOfLabels;

  if ( !isAboveTopSec && ((isBelowTop && !isBelowBottom) || isAboveTop)) {
    $('.forlabels')
      .addClass('sticked')
      .removeClass("sticked2")
      .text("Sticked");
  } else if (isBelowBottom) {
    $('.forlabels')
      .addClass('sticked2')
      .removeClass('sticked')
      .text("Scrolled Below Bottom");
  } else {
    $('.forlabels')
      .removeClass('sticked sticked2')
      .text("Not sticked ");
  }
});

Replace the above js with your js and it would work as expected.

Rent Charter Buses Company
READ ALSO
Jquery UI spinner, obtaining the value

Jquery UI spinner, obtaining the value

I created my own widget of the Jquery Ui spinner which shows the data from an array in the spinner it self, so that the user can spin on the values of the spinner and when he chooses a certain value and click on a button then i can retrieve the chosen...

439
jquery: load div from other pages into div

jquery: load div from other pages into div

I'd like to load divs that are saved as separate html files into a div of a "main file"This works fine

371
Browser back-button does&#39;t work correctly after window.location.href was changed

Browser back-button does't work correctly after window.location.href was changed

Before my application was written in jQuery and wasn't SPAI have rewritten some of the pages to AngularJS and made them SPA

287
How do I set background-image height using jQuery?

How do I set background-image height using jQuery?

I would like my background image to fill the height of the window on which it is being viewedObviously I don't know this value since it is variable

525