Fade In при прокрутке вниз, Fade Out при прокрутке вверх-на основе положения элемента в окне

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

Это ближайший jsfiddle, который я нашел. http://jsfiddle.net/tcloninger/e5qaD/

$(document).ready(function() {

/* Every time the window is scrolled ... */
$(window).scroll( function(){

    /* Check the location of each desired element */
    $('.hideme').each( function(i){

        var bottom_of_object = $(this).position().top + $(this).outerHeight();
        var bottom_of_window = $(window).scrollTop() + $(window).height();

        /* If the object is completely visible in the window, fade it it */
        if( bottom_of_window > bottom_of_object ){

            $(this).animate({'opacity':'1'},500);

        }    
    }); 
}); 
});

Он делает именно то, что я хочу при прокрутке вниз, но я также хочу, чтобы элементы исчезали, если я прокручиваю их.

I попробовал это без успеха.

            if( bottom_of_window > bottom_of_object ){

                $(this).animate({'opacity':'1'},500);  

            } else {

               $(this).animate({'opacity':'0'},500); }

большое спасибо, что нашли время, чтобы посмотреть на это.

4 ответов


причина, по которой ваша попытка не работала, заключается в том, что две анимации (fade-in и fade-out) работали друг против друга.

прямо перед тем, как объект стал видимым, он все еще был невидимым, и поэтому анимация для затухания будет работать. Затем, через долю секунды, когда тот же самый объект стал видимым, анимация начала исчезать, но она все еще продолжалась. Так они будут работать друг против друга, и вы увидите ничего.

в конечном итоге объект станет видимым (большую часть времени), но это займет некоторое время. И если вы прокрутите вниз с помощью кнопки со стрелкой на кнопке полосы прокрутки, анимация будет работать, потому что вы будете прокручивать с большим шагом, создавая меньше событий прокрутки.


достаточное объяснение, решение (JS, CSS, HTML):

$(window).on("load",function() {
  $(window).scroll(function() {
    var windowBottom = $(this).scrollTop() + $(this).innerHeight();
    $(".fade").each(function() {
      /* Check the location of each desired element */
      var objectBottom = $(this).offset().top + $(this).outerHeight();
      
      /* If the element is completely within bounds of the window, fade it in */
      if (objectBottom < windowBottom) { //object comes into view (scrolling down)
        if ($(this).css("opacity")==0) {$(this).fadeTo(500,1);}
      } else { //object goes out of view (scrolling up)
        if ($(this).css("opacity")==1) {$(this).fadeTo(500,0);}
      }
    });
  }).scroll(); //invoke scroll-handler on page-load
});
.fade {
  margin: 50px;
  padding: 50px;
  background-color: lightgreen;
  opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

<div>
  <div class="fade">Fade In 01</div>
  <div class="fade">Fade In 02</div>
  <div class="fade">Fade In 03</div>
  <div class="fade">Fade In 04</div>
  <div class="fade">Fade In 05</div>
  <div class="fade">Fade In 06</div>
  <div class="fade">Fade In 07</div>
  <div class="fade">Fade In 08</div>
  <div class="fade">Fade In 09</div>
  <div class="fade">Fade In 10</div>
</div>
(скрипка:http://jsfiddle.net/eLwex993/2/)
  • я завернул fade-codeline в предложение if:if ($(this).css("opacity")==0) {...}. Это гарантирует, что объект исчезает только тогда, когда opacity и 0. То же самое относится и к исчезновению. И это предотвращает затухание и затухание от работы друг против друга, потому что теперь только один из двух работает одновременно на объект.
  • сменил .animate() to .fadeTo(). Это специализированная функция jQuery для непрозрачности, намного короче для записи и, вероятно, легче, чем анимация.
  • сменил .position() to .offset(). Это всегда вычисляет относительно тела, тогда как положение относительно родителя. Для вашего случая, я считаю, что смещение-это путь.
  • сменил $(window).height() to $(window).innerHeight(). Последнее, по моему опыту, надежнее.
  • сразу после scroll-handler, я вызываю этот обработчик один раз на странице-load с $(window).scroll();. Теперь вы можете дать все нужные объекты на странице .fade класс и объекты, которые должны быть невидимыми при загрузке страницы, будут немедленно исчезать.
  • я убрал #container из HTML и CSS, потому что (по крайней мере, для этого ответа) это не обязательно. (Я подумал, может быть, вам нужно height:2000px потому что ты использовал .position() вместо .offset(), иначе я не знаю. Не стесняйтесь, конечно, оставить его в вашем код.)

обновление

если вы хотите, чтобы значения непрозрачности, кроме 0 и 1 использовать следующий код:

$(window).on("load",function() {
  function fade(pageLoad) {
    var windowBottom = $(window).scrollTop() + $(window).innerHeight();
    var min = 0.3;
    var max = 0.7;
    var threshold = 0.01;
    
    $(".fade").each(function() {
      /* Check the location of each desired element */
      var objectBottom = $(this).offset().top + $(this).outerHeight();
      
      /* If the element is completely within bounds of the window, fade it in */
      if (objectBottom < windowBottom) { //object comes into view (scrolling down)
        if ($(this).css("opacity")<=min+threshold || pageLoad) {$(this).fadeTo(500,max);}
      } else { //object goes out of view (scrolling up)
        if ($(this).css("opacity")>=max-threshold || pageLoad) {$(this).fadeTo(500,min);}
      }
    });
  } fade(true); //fade elements on page-load
  $(window).scroll(function(){fade(false);}); //fade elements on scroll
});
.fade {
  margin: 50px;
  padding: 50px;
  background-color: lightgreen;
  opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

<div>
  <div class="fade">Fade In 01</div>
  <div class="fade">Fade In 02</div>
  <div class="fade">Fade In 03</div>
  <div class="fade">Fade In 04</div>
  <div class="fade">Fade In 05</div>
  <div class="fade">Fade In 06</div>
  <div class="fade">Fade In 07</div>
  <div class="fade">Fade In 08</div>
  <div class="fade">Fade In 09</div>
  <div class="fade">Fade In 10</div>
</div>
(скрипка: http://jsfiddle.net/eLwex993/3/)
  • я добавил порог в предложение if, см. объяснение ниже.
  • я создал переменные для threshold и min/max в начале функция. В остальной части функции на эти переменные ссылаются. Таким образом, если вы хотите снова изменить значения, вам нужно сделать это только в одном месте.
  • я также добавил || pageLoad к предложению if. Это было необходимо, чтобы убедиться, что все объекты выцветают до правильной непрозрачности при загрузке страницы. pageLoad является логическим, который отправляется в качестве аргумента, когда fade() вызывается.
    мне пришлось поместить fade-код внутри extra function fade() {...}, для того чтобы иметь возможность отправить вдоль pageLoad boolean при вызове обработчика прокрутки.
    Я не видел другого способа сделать это, если кто-то еще это сделает, пожалуйста, оставьте комментарий.

объяснение:
Причина кода в играть не работает, потому что фактические значения непрозрачности всегда немного отличаются от значения, которое вы установили. Поэтому, если вы установите непрозрачность в 0.3 фактическое значение (в данном случае)0.300000011920929. Это просто одна из тех маленьких ошибок, которые вы должны узнать, по пути проб и ошибок. Вот почему это предложение if не будет работать:if ($(this).css("opacity") == 0.3) {...}.

я добавил порог, чтобы учесть эту разницу:== 0.3 становится <= 0.31.
(я установил порог в 0.01, это можно изменить, конечно, до тех пор, пока фактическая непрозрачность будет падать между заданным значением и этим порогом.)

операторы теперь изменены с == в <= и >=.


обновление 2:

если вы хотите выцветать элементы на основе их видимого процента, используйте следующий код:

$(window).on("load",function() {
  function fade(pageLoad) {
    var windowTop=$(window).scrollTop(), windowBottom=windowTop+$(window).innerHeight();
    var min=0.3, max=0.7, threshold=0.01;
    
    $(".fade").each(function() {
      /* Check the location of each desired element */
      var objectHeight=$(this).outerHeight(), objectTop=$(this).offset().top, objectBottom=$(this).offset().top+objectHeight;
      
      /* Fade element in/out based on its visible percentage */
      if (objectTop < windowTop) {
        if (objectBottom > windowTop) {$(this).fadeTo(0,min+((max-min)*((objectBottom-windowTop)/objectHeight)));}
        else if ($(this).css("opacity")>=min+threshold || pageLoad) {$(this).fadeTo(0,min);}
      } else if (objectBottom > windowBottom) {
        if (objectTop < windowBottom) {$(this).fadeTo(0,min+((max-min)*((windowBottom-objectTop)/objectHeight)));}
        else if ($(this).css("opacity")>=min+threshold || pageLoad) {$(this).fadeTo(0,min);}
      } else if ($(this).css("opacity")<=max-threshold || pageLoad) {$(this).fadeTo(0,max);}
    });
  } fade(true); //fade elements on page-load
  $(window).scroll(function(){fade(false);}); //fade elements on scroll
});
.fade {
  margin: 50px;
  padding: 50px;
  background-color: lightgreen;
  opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

<div>
  <div class="fade">Fade In 01</div>
  <div class="fade">Fade In 02</div>
  <div class="fade">Fade In 03</div>
  <div class="fade">Fade In 04</div>
  <div class="fade">Fade In 05</div>
  <div class="fade">Fade In 06</div>
  <div class="fade">Fade In 07</div>
  <div class="fade">Fade In 08</div>
  <div class="fade">Fade In 09</div>
  <div class="fade">Fade In 10</div>
</div>
(скрипка: http://jsfiddle.net/eLwex993/5/)

Я немного изменил ваш код и сделал его более надежным. С точки зрения прогрессивного улучшения, вероятно, лучше иметь всю логику затухания в JavaScript. В Примере myfunksyde любой пользователь без JavaScript ничего не видит из-за opacity: 0;.

    $(window).on("load",function() {
    function fade() {
        var animation_height = $(window).innerHeight() * 0.25;
        var ratio = Math.round( (1 / animation_height) * 10000 ) / 10000;

        $('.fade').each(function() {

            var objectTop = $(this).offset().top;
            var windowBottom = $(window).scrollTop() + $(window).innerHeight();

            if ( objectTop < windowBottom ) {
                if ( objectTop < windowBottom - animation_height ) {
                    $(this).html( 'fully visible' );
                    $(this).css( {
                        transition: 'opacity 0.1s linear',
                        opacity: 1
                    } );

                } else {
                    $(this).html( 'fading in/out' );
                    $(this).css( {
                        transition: 'opacity 0.25s linear',
                        opacity: (windowBottom - objectTop) * ratio
                    } );
                }
            } else {
                $(this).html( 'not visible' );
                $(this).css( 'opacity', 0 );
            }
        });
    }
    $('.fade').css( 'opacity', 0 );
    fade();
    $(window).scroll(function() {fade();});
});

смотрите здесь:http://jsfiddle.net/78xjLnu1/16/

Ура, Мартин!--3-->


Я знаю, что уже поздно, но я беру исходный код и меняю некоторые вещи, чтобы легко управлять css. Поэтому я сделал код с addClass () и removeClass ()

вот полный код : http://jsfiddle.net/e5qaD/4837/

        if( bottom_of_window > bottom_of_object ){
            $(this).addClass('showme');
       }
        if( bottom_of_window < bottom_of_object ){
            $(this).removeClass('showme');

извините, это и старая нить, но некоторые люди все равно нуждаются в этом, я думаю,

Примечание: я достиг этого, используя Animate.библиотека css для анимации затухания.

я использовал ваш код и просто добавил .скрытый класс (используя скрытый класс bootstrap), но вы все равно можете просто определить .hidden { opacity: 0; }

$(document).ready(function() {

/* Every time the window is scrolled ... */

$(window).scroll( function(){

/* Check the location of each desired element */
$('.hideme').each( function(i){

    var bottom_of_object = $(this).position().top + $(this).outerHeight();
    var bottom_of_window = $(window).scrollTop() + $(window).height();


    /* If the object is completely visible in the window, fade it it */
    if( bottom_of_window > bottom_of_object ){

        $(this).removeClass('hidden');
        $(this).addClass('animated fadeInUp');
    }    else {
            $(this).addClass('hidden');
               }

}); 
}); 
});

другое Примечание: применение этого к контейнерам может привести к сбою.