2016-12-31 7 views
1

Я работаю над своим собственным слайд-шоу JavaScript, используя jQuery 3.1.1. Он работает нормально, но почему-то переходная анимация негладкая. Когда есть только две фотографии, она работает нормально, но как только я добавлю третий, она не работает хорошо.JavaScript слайд-шоу не является гладким

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

!function($) { 
 
    "use strict"; 
 
    $.slideshow = function(container) { 
 
    let $container = $(container); 
 
    let children = $container.find('.slide').length; 
 
    $container.find('.slide').each(function(index) { 
 
     let zIndex = 210 - index; 
 
     let bg = $(this).data('bg'); 
 
     $(this).css('background-image', 'url(' + bg + ')'); 
 
    }); 
 
    let settings = { 
 
     'transition': 500, 
 
     'delay': 6000, 
 
    }; 
 
    let currentSlide = 0; 
 
    $.fn.showNext = function() { 
 
     let nextSlide = ((currentSlide + 1) < children) ? (currentSlide + 1) : 0; 
 
     let $current = $container.find('.slide:nth-child(' + (currentSlide + 1) + ')'); 
 
     let $next = $container.find('.slide:nth-child(' + (nextSlide + 1) + ')'); 
 
     $current.animate({ 
 
     'opacity': 0 
 
     }, settings.transition); 
 
     setTimeout(function() { 
 
     $current.css('z-index', 200); 
 
     $current.css('opacity', 1); 
 
     $next.css('z-index', 210); 
 
     }, settings.transition + 100); 
 
     console.log(currentSlide, nextSlide); 
 
     currentSlide = ((currentSlide + 1) < children) ? (currentSlide + 1) : 0; 
 
     setTimeout(function() { 
 
     $container.showNext(); 
 
     }, settings.delay); 
 
    }; 
 
    setTimeout(function() { 
 
     $container.showNext(); 
 
    }, settings.delay); 
 
    }; 
 
}(jQuery); 
 

 
$.slideshow('.slideshow');
.slideshow-wrapper { 
 
     height: 100vh; 
 
     overflow: hidden; 
 
     position: relative; 
 
     width: 100%; 
 
    } 
 
    
 
    .slideshow { 
 
     height: 100%; 
 
     position: relative; 
 
     width: 100%; 
 
    } 
 
    
 
    .slide { 
 
     background-position: center; 
 
     background-size: cover; 
 
     height: 100%; 
 
     left: 0; 
 
     overflow: hidden; 
 
     position: absolute; 
 
     top: 0; 
 
     width: 100%; 
 
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
 
<div class="slideshow-wrapper"> 
 
    <div class="slideshow"> 
 
    <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/6.jpg"></div> 
 
    <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/5.jpg"></div> 
 
    <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/4.jpg"></div> 
 
    </div> 
 
</div>

ответ

2

Есть несколько проблем в коде JQuery. Вот что я обнаружил:

  1. Это работает в состояние гонки, где JavaScript выполняется , прежде чем HTML успел загрузить. Ни один из начальных тегов div еще не загружен в объект документа. Контейнер div имеет длину 0. Единый setTimeout с нагрузкой 0мс разблокирует то, что & позволяет загружать HTML до запуска JS.
  2. Третье изображение (4.jpg) показано 1-м, а не 1-м изображением (6.jpg). Z-индекс изменяется в коде, но не применяется обратно к изображениям.
  3. Прозрачность «тока» анимируется до 0 &, а затем сразу же нажимается до 1. Я думаю, вы хотите изменить непрозрачность «next» на 1 вместо «current» от 1 до 0 и затем вернуться к 1.
  4. Переходы инициализации начинаются с плавного, но затем повторяющиеся анимации имеют тенденцию к более быстрому циклу & исчезают на белой странице перед появлением «следующего» изображения. Пользователи могут обнаружить, что толчок, что анимация начинается с 6-секундной задержкой &, затем ускоряется до 1/2 секунды на изображение. Эта последняя анимация слишком быстрая.
  5. Анимация появлялась вместо растворения. Он также не использует кросс-растворение, но я рекомендую использовать его. Я добавил его, чтобы показать вам, как это работает.
  6. Код не очищается, поэтому вы сталкиваетесь с проблемами с кодировкой, при этом console.log & вынужден использовать $ container для его исправления. Переменная контейнера не может быть обновлена ​​с помощью «let container = ...» после того, как она будет передана как параметр с (контейнер). Когда я исправлю это, передав имя параметра «селектор», я могу удалить $ в переменных контейнера. Это помогает отличить, какой код привязан к jQuery &, которого нет.
  7. Существовала большая зависимость от использования метода setTimeout, но, как вы, наверное, уже знаете ... те запускают только 1x &, затем останавливаются. Чтобы сделать их непрерывными, начальный setTimeout был изменен на setInterval.

Пробуйте этот edited JS Fiddle, который исправляет эти проблемы. Btw, вот метод jQuery .animate.

изменения CSS:

  1. Добавленные "непрозрачности: 0;" ко всем слайдам.
  2. Добавлен "opacity: 1;" к первому слайду.

CSS:

.slideshow-wrapper { 
    height: 100vh; 
    overflow: hidden; 
    position: relative; 
    width: 100%; 
} 

.slideshow { 
    height: 100%; 
    position: relative; 
    width: 100%; 
} 

.slide { 
    background-position: center; 
    background-size: cover; 
    height: 100%; 
    left: 0; 
    opacity: 0; /* <-- New --- */ 
    overflow: hidden; 
    position: absolute; 
    top: 0; 
    width: 100%; 
} 

.slide:first-child { /* <-- New --- */ 
    opacity: 1; 
} 

JavaScript имеет много правок

!function($) { 
    "use strict"; 

    $.slideshow = function(selector) { 
     let container = $(selector); 
     let children = container.find('.slide').length; 

     container.find('.slide').each(function(index) { 
      let zIndex = 210 - index; 
      $(this).css('z-index', zIndex); // <-- This was missing, as it was loading the last image as the 1st image. 
      let bg = $(this).data('bg'); 
      $(this).css('background-image', 'url(' + bg + ')'); 
     }); 

     let settings = { 
      'delay': 2000 
     }; 

     let currentSlide = 0; 

     $.fn.showNext = function() { 
      let nextSlide = ((currentSlide + 1) < children) ? (currentSlide + 1) : 0; 
      let current = container.find('.slide:nth-child(' + (currentSlide + 1) + ')'); 
      let next = container.find('.slide:nth-child(' + (nextSlide + 1) + ')'); 

      next.animate({ 
      'opacity': 1, 
      'z-index': 210 
      }, settings.transition); 

      // Creates the Cross-Dissolve, as 1 image "next" is fadding up from opacity 0 to 1, while current is fadding down from 1 to 0. 
      current.animate({ 
      'opacity': 0, 
      'z-index': 200 
      }, settings.transition); 
     }; 

     // Starts the animation loop. 
     setInterval(function() { 
      container.showNext(); 
      currentSlide = ((currentSlide + 1) < children) ? (currentSlide + 1) : 0; 
     }, settings.delay); 
    }; 
}(jQuery); 

setTimeout(function() { 
    $.slideshow('.slideshow'); 
}, 0); // Fixes the race condition, by allowing the HTML to load before the JS runs. 

HTML - никаких изменений, но удалить тег сценария при использовании jsfiddle

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
<div class="slideshow-wrapper"> 
    <div class="slideshow"> 
    <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/6.jpg"></div> 
    <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/5.jpg"></div> 
    <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/4.jpg"></div> 
    </div> 
</div> 

Получите удовольствие от игры с edited JS Fiddle, чтобы настроить ее!

+0

Я очень ценю, что вы внимательно изучаете мой код. Использование 'setInteval' определенно то, что я хотел вместо нескольких тайм-аутов. Я думаю, что фрагмент здесь ведет себя несколько иначе, чем мой фактический продукт, но то, что я закончил, - это получить предыдущий образ и сделать его z-индекс ниже следующего в очереди с переходом; они были такими же, чтобы иногда показывать неправильный образ. Спасибо огромное! –

+0

Добро пожаловать! Раньше я сталкивался с подобными проблемами со слайд-шоу. Рад, что я могу помочь вам сегодня! – Clomp

+0

«Это бежит в состояние гонки» -> Условия гонки в Javascript невозможны из-за однопоточной природы. То, что вы описываете, не ждет, пока ресурс будет доступен, прежде чем действовать на него, так же, как и то, что произойдет, если вы попытаетесь открыть файл до его существования, просмотрите диск до его установки и т. Д. В этом случае Метод 'setTimeout()' следует избегать, потому что нет гарантии, что DOM будет готов к следующему тику. Вы хотите перенести инициализатор слайд-шоу в событие 'document.ready', например:' $ (function() {$ .slideshow ('. Slideshow');}); '. –

0

Основная проблема заключается здесь

setTimeout(function() { 
     $current.css('z-index', 200); 
     $current.css('opacity', 1); // this should be $next.css('opacity', 1); 
     $next.css('z-index', 210); 
     } 

Вы должны также попытаться избавиться от 3 SetTimeout(), они выглядят избыточными. Вы можете использовать setInteval() для изменения изображения. Измените свойства css в обратном вызове завершения анимации, и вы можете избавиться от другого setTimeout().

Проверьте это:

!function($) { 
 
    "use strict"; 
 
    $.slideshow = function(container) { 
 
    let $container = $(container); 
 
    let children = $container.find('.slide').length; 
 
    $container.find('.slide').each(function(index) { 
 
     let zIndex = 210 - index; 
 
     let bg = $(this).data('bg'); 
 
     $(this).css('background-image', 'url(' + bg + ')'); 
 
    }); 
 
    let settings = { 
 
     'transition': 500, 
 
     'delay': 6000, 
 
    }; 
 
    let currentSlide = 0; 
 
    $.fn.showNext = function() { 
 
     let nextSlide = ((currentSlide + 1) < children) ? (currentSlide + 1) : 0; 
 
     let $current = $container.find('.slide:nth-child(' + (currentSlide + 1) + ')'); 
 
     let $next = $container.find('.slide:nth-child(' + (nextSlide + 1) + ')'); 
 
     $current.animate({ 
 
     'opacity': 0 
 
     }, settings.transition,function(){ 
 
     
 
     $current.css('z-index', 200); 
 
     $next.css('opacity', 1); 
 
     $next.css('z-index', 210); 
 
     
 
     }); 
 
     currentSlide = ((currentSlide + 1) < children) ? (currentSlide + 1) : 0; 
 
    }; 
 
    setInterval(function() { 
 
     $container.showNext(); 
 
    }, settings.delay); 
 
    }; 
 
}(jQuery); 
 

 
$.slideshow('.slideshow');
.slideshow-wrapper { 
 
     height: 100vh; 
 
     overflow: hidden; 
 
     position: relative; 
 
     width: 100%; 
 
    } 
 
    
 
    .slideshow { 
 
     height: 100%; 
 
     position: relative; 
 
     width: 100%; 
 
    } 
 
    
 
    .slide { 
 
     background-position: center; 
 
     background-size: cover; 
 
     height: 100%; 
 
     left: 0; 
 
     overflow: hidden; 
 
     position: absolute; 
 
     top: 0; 
 
     width: 100%; 
 
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
 
<div class="slideshow-wrapper"> 
 
    <div class="slideshow"> 
 
    <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/6.jpg"></div> 
 
    <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/5.jpg"></div> 
 
    <div class="slide" data-bg="https://s3.amazonaws.com/StartupStockPhotos/uploads/20160503/4.jpg"></div> 
 
    </div> 
 
</div>

Смежные вопросы