Странное поведение функции прокрутки — jQuery

#javascript #jquery

Вопрос:

Я пытаюсь изменить положение css с фиксированного на статическое и наоборот, на основе прокрутки пикселей… Сценарий работает нормально, как и предполагалось, но в момент изменения позиции css возникает своего рода задержка.

Если я медленно прокручиваю до точки переключения, с консоли я вижу, как положение быстро переключается с фиксированного на статическое и со статического на фиксированное.

В любом случае, загляните в фрагмент, прокрутите его ближе к концу и посмотрите, что произойдет… Я не могу понять причину. Надеюсь на вашу помощь! Спасибо!

Откройте вырезанный в полноэкранном режиме, чтобы лучше видеть!

 $(window).scroll(function() {
    var scrolled = $(window).scrollTop();
    var add_px = $('body').height();
    var px_scroll = scrolled   add_px;
    
    var tot = $(document).height();
    var ftr = $('#footer').css("margin-bottom");
    ftr = ftr.replace('px','');
    ftr = ftr.replace('-','');
    var total = tot - ftr;
    
    if ( px_scroll > total ) {
        $('#act_btns').css({'position':'static'});
    } else {
        $('#act_btns').css({'position':'fixed'});
    }
}); 
 html, body { height: 100%; margin:0; padding: 0; }

#main_container {
    position: relative;
    width: 100%;
    height: auto;
    min-height: 100%;
    text-align: center;
}

#act_btns {
    position: fixed;
    margin: 0 auto;
    left: 0;
    right: 0;
    bottom: 50px;
}
#act_btns input {
    color: #fff;
    border: 0px;
    width: 100px;
    height: 40px;
    margin: 0 5px;
    box-shadow: 0 0 5px 5px #000;
}

#footer {
    position: absolute;
    bottom: 0;
    margin-bottom: -200px;
    width: 100%;
    background: rgba(0, 0, 0, 0.8);
    padding: 10px 7px 15px 7px;
    box-sizing: border-box;
    text-align: center;
} 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>

<html>
<body>
<div id="main_container">

<div style="position:relative;margin:0 auto 20px;width:80%;height:2500px;background:#ccc;"></div>

<div id="act_btns">
<input type="submit" name="save_list" id="save_btn" value="Salva">
<input type="submit" name="reset_list" id="rst_btn" value="Reset">
</div>

<div id="footer"><p id="copyright">Copyright © 2016 - 2021</p></div>

</div>
</body>
</html> 

Ответ №1:

Проблема, с которой вы сталкиваетесь, заключается в следующем: вы вычисляете total значение при каждом изменении положения прокрутки. Поэтому, когда вы прокручиваете и меняете положение элемента с fixed на static , вы добавляете height (60 пикселей) на total . (Это видно, если вы console.log(scrolled, total) ). Потому fixed что элементы положения не занимают никакого места.

Самое простое решение — рассчитать total время загрузки страницы. А потом, если это не изменится, ты сможешь идти с этой высотой вечно. Поэтому единственное изменение, которое я сделал в вашем коде, — это переместил вычисление за total пределы функции прокрутки.

 var tot = $(document).height();
var ftr = $('#footer').css("margin-bottom");
ftr = ftr.replace('px','');
ftr = ftr.replace('-','');
var total = tot - ftr;


$(window).scroll(function() {
    var scrolled = $(window).scrollTop();
    var add_px = $('body').height();
    var px_scroll = scrolled   add_px;
    
    if ( px_scroll > total ) {
        $('#act_btns').css({'position':'static'});
    } else {
        $('#act_btns').css({'position':'fixed'});
    }
}); 
 html, body { height: 100%; margin:0; padding: 0; }

#main_container {
    position: relative;
    width: 100%;
    height: auto;
    min-height: 100%;
    text-align: center;
}

#act_btns {
    position: fixed;
    margin: 0 auto;
    left: 0;
    right: 0;
    bottom: 50px;
}
#act_btns input {
    color: #fff;
    border: 0px;
    width: 100px;
    height: 40px;
    margin: 0 5px;
    box-shadow: 0 0 5px 5px #000;
}

#footer {
    position: absolute;
    bottom: 0;
    margin-bottom: -200px;
    width: 100%;
    background: rgba(0, 0, 0, 0.8);
    padding: 10px 7px 15px 7px;
    box-sizing: border-box;
    text-align: center;
} 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>

<html>
<body>
<div id="main_container">

<div style="position:relative;margin:0 auto 20px;width:80%;height:2500px;background:#ccc;"></div>

<div id="act_btns">
<input type="submit" name="save_list" id="save_btn" value="Salva">
<input type="submit" name="reset_list" id="rst_btn" value="Reset">
</div>

<div id="footer"><p id="copyright">Copyright © 2016 - 2021 VirtualCode.Net</p></div>

</div>
</body>
</html> 

Это может привести к некоторым проблемам, если вы загружаете изображения, а что нет, что может занять больше места (высоты) при полной загрузке, и расчет уже выполнен. Чтобы никогда не сталкиваться с этой проблемой, вы можете обернуть расчет внутрь

 $(window).load(function(){
    // add total calculation code here
});
 

Комментарии:

1. Спасибо за объяснение, я не думал, что относительное положение добавляет пиксели… 🙁 Я просто собираюсь протестировать ваш код на своем местном веб-сайте

2. Есть ли проблема, из консоли я вижу сообщение об ошибке: Ошибка ссылки не найдена: общее число не определено, похоже, я не могу использовать эту переменную вне функции прокрутки…

3. Извините, у меня был сценарий в заголовке… Теперь нужно двигаться вниз, и все работает нормально! Еще раз большое спасибо! 😉

4. @Devilix приятного, счастливого кодирования!