broken heart
broken heart

Reputation: 61

fixed element when it appears on the page

Now I have, when I scroll to a certain element, it is then fixed in the place I need, but at the same time it jumps from one place to another

I need to make sure that as soon as this element completely appears at the bottom of the page, it is immediately fixed so that it does not jump from one place to another later

But so far I haven't been able to find a solution

$(document).ready(function() {
  var element = $(".btn");
  var height_el = element.offset().top;
  var element_stop = $(".end");
  var height_el_stop = element_stop.offset().top;

  $(window).scroll(function() {
    if($(window).scrollTop() > height_el_stop) {
      element.removeClass("fixed");      
    } else {  
      if ($(window).scrollTop() > height_el) {
        element.addClass("fixed");
      } else {
        element.removeClass("fixed");
      }
    }
  });
});
.info {
  margin: 100px auto;
  text-align: center;
}

.btn {
  width: 200px;
  padding: 12px 50px;
  background-color: blue;
  margin: 0 auto;
  text-align: center;
}

.fixed {
  position: fixed;
  z-index: 99;
  bottom: 0;
  left: 50%;
  transform: translate(-50%, -50%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="btn">button</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info end">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>

Upvotes: 1

Views: 181

Answers (3)

Arleigh Hix
Arleigh Hix

Reputation: 10877

The behavior you want is simple with position: sticky; You only need to use js to unstick it when you want.

$(document).ready(function() {
  var element = $(".btn");
  var element_stop = $(".end");
  var height_el_stop = element_stop.offset().top;

  $(window).scroll(function() {
    if ($(window).scrollTop() > height_el_stop) {
      element.addClass("unstick");
    } else {
      element.removeClass("unstick");
    }
  });
});
.info {
  margin: 100px auto;
  text-align: center;
}

.btn {
  width: 200px;
  padding: 12px 50px;
  background-color: blue;
  margin: 0 auto;
  text-align: center;
  position: sticky;
  z-index: 99;
  top: 100vh;
  left: 50%;
  transform: translate(-50%, -100%);
}

.btn.unstick {
  position: static;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="btn">button</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info end">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>

Upvotes: 1

Peter Thoeny
Peter Thoeny

Reputation: 7616

You need to take into account the viewport height, e.g. window height:

$(document).ready(function() {
  var height_window = $(window).height();
  var element = $(".btn");
  var height_el = element.offset().top;
  var element_stop = $(".end");
  var height_el_stop = element_stop.offset().top;
  console.log(height_window, height_el, height_el_stop)

  $(window).scroll(function() {
    let scrollTop = $(window).scrollTop();
    if(scrollTop > height_el_stop) {
      element.removeClass("fixed");      
    } else if (scrollTop + height_window > height_el) {
        element.addClass("fixed");
    } else {
      element.removeClass("fixed");
    }
  });
});
.info {
  margin: 100px auto;
  text-align: center;
}

.btn {
  width: 200px;
  padding: 12px 50px;
  background-color: blue;
  margin: 0 auto;
  text-align: center;
}

.fixed {
  position: fixed;
  z-index: 99;
  bottom: 0;
  left: 50%;
  transform: translate(-50%, -50%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="btn">button</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info end">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>

Upvotes: 1

Felix Tenn
Felix Tenn

Reputation: 130

I have reproduced your code and tried but i am not really good at CSS. I have changed bit of your JS code as follows:

$(document).ready(function () {
    var element = $(".btn");
    var height_el = element.offset().top;
    var element_stop = $(".end");
    var height_el_stop = element_stop.offset().top;

    $(window).scroll(function () {
        if ($(window).scrollTop() > height_el_stop) {
            element.removeClass("fixed");
        } else {
            if ($(window).scrollTop() > height_el) {
                element.css('position','fixed').css('top','0');
            } else {
                element.css('position','static');
            }
        }
    });
});
.info {
            margin: 100px auto;
            text-align: center;
        }

        .btn {
            width: 200px;
            padding: 12px 50px;
            background-color: blue;
            margin: 0 auto;
            text-align: center;
        }

        .fixed {
            position: fixed;
            z-index: 99;
            bottom: 0;
            left: 50%;
            transform: translate(-50%, -50%);
        }
<html lang="">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-w   idth, initial-scale=1.0">
    <title>fix element</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>

<body>   

<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="btn">button</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info end">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>
<div class="info">info</div>



</body>

</html>

Upvotes: 0

Related Questions