Загрузка / замена IMG или видео, указанного в data-src - PullRequest
1 голос
/ 15 марта 2020

Моя цель состоит в том, чтобы отображать другое изображение или видео, отображаемое в элементе div, которое изменяется при наведении на другие элементы.

Я думаю, что у меня это работает только с изображением, проверяя, какой файл изображения указан в data-src и загрузку в тег img на странице. Однако мне нужно изменить разметку с img на video, когда указан файл mov ie - вот с чем мне нужна помощь.

Вы можете увидеть «рабочую» версию изображения здесь (не 3-й элемент имеет заполнитель видео в data-src, поэтому не будет отображаться): https://codepen.io/moy/pen/BaNxzdL

Так что в настоящее время на странице у меня есть этот пустой тег изображения:

<div class="carousel__bg">
    <img src="" />
</div>

Файлы изображений указываются для нескольких элементов карусели в data-src, как показано в примере ниже:

<div class="carousel__item" data-src="img/content/1-wide.jpg">
    <div class="carousel__content">
        <h4 class="carousel__title">Behind The Scenes</h4>
        <span class="carousel__flag">// Featured</span>
        <h2 class="carousel__subtitle">Denim Cox in Fuck Yes Dude!</h2>
        <a href="#" class="carousel__btn">Read the Article</a>
    </div>
    <img src="img/content/1.jpg" class="carousel__image" />
</div>

И javascript, который получает URL-адрес изображения и добавляет его на страницу, - это :

$(function() {

    var overlay = $('.carousel__bg img'), cached = {};

    $('.carousel__item').mouseenter(function() {

        var item = $(this),
        spot = $(this).index('.carousel__item'),
        value = item.attr('data-src');

        overlay.fadeTo(0,0).attr('src', value);

        if (!overlay[0].complete && !cached[spot]) {

            cached[spot] = true;
            $('.carousel__bg').addClass('loading');

            overlay.one('load', function() {
                $('.carousel__bg').removeClass('loading');
                overlay.fadeTo(300,1);
            });
        }
        else overlay.fadeTo(300,1);
    })

    .mouseleave(function() {
        overlay.finish();
    });
});

Очевидно, что проблема в том, что если я укажу data-src="video/safari.mp4", он не будет работать, так как он пытается добавить видео в элемент img. Так как же мне go переключаться между тегами img / video? С этим связана проблема, связанная с возможностью загрузки обеих версий файла в формате mp4 + webm / ogg?

Так что нужно будет переработать, чтобы «вставить» элемент img или video в страница в зависимости от расширения? Я попытался использовать оператор if / else, чтобы проверить, содержит ли data-src расширение .mp4 и просто жестко запрограммировал элемент video на странице в текст, но не смог заставить это работать. : /

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

Редактировать

В некотором смысле я решил поместить эти предметы в карусель, чтобы посмотреть, будет ли этот эффект работать - и это в значительной степени работает!

Однако я заметил способ, которым я теряю изображения в CSS (исчезать) все они появляются, когда .carousel наведен, но затем нацелен на отдельный элемент и перезаписан) теперь является проблемой, когда вы наводите курсор на кнопки «предыдущий / следующий», так как изображения не исчезают.

Кто-нибудь получил лучший способ справиться с этим? Я попробовал метод 100% CSS, но, возможно, добавил класс, который будет лучше?

Пример гладкой карусели: https://codepen.io/moy/pen/JjdvRyG

1 Ответ

1 голос
/ 15 марта 2020

Элемент video не является сложным, важная часть заключается в добавлении mime-типа видео для добавления к элементу source. data-src принимает массив URL-адресов видео (разных типов) и добавляет различные источники к элементу после нахождения типа.

Я обновил codepen

Что касается кнопок, они находятся внутри элемента .carousel, поэтому они будут наводить курсор на все элементы, основанные на этом. Я сделал некоторые элементы более точными c, чтобы они меняли стиль только при наведении списка элементов.

Наконец, для того, чтобы слушатели могли применить элемент к гладкому элементу, я изменил их на .on .

var VIDEO_TYPES = {
  'mp4': 'video/mp4',
  'webm': 'video/webm',
  'ogv': 'video/ogg',
}



/**
 * Slick
 */

$(document).ready(function() {
  $('.slick-carousel').slick({
      //centerMode: true,
      centerPadding: '0',
      slidesToShow: 3,
      arrows: true,
      dots: false,
      prevArrow: '<a class="slick-arrow slick-arrow--prev"><span>&larr;</span></a>',
      nextArrow: '<a class="slick-arrow slick-arrow--next"><span>&rarr;</span></a>',
      responsive: [{
          breakpoint: 960,
          settings: {
            centerMode: true,
            slidesToShow: 1
          }
        },
        {
          breakpoint: 600,
          settings: {
            centerMode: true,
            slidesToShow: 1
          }
        },
        {
          breakpoint: 480,
          settings: {
            centerMode: true,
            slidesToShow: 1
          }
        }
      ]
    })
    .on('setPosition', function(event, slick) {
		slick.$slider.find(".slick-slide .tile:not(.position-set)").addClass('position-set').css('height', slick.$slideTrack.height() - 30 + 'px');
    });
    
    
 /**
 * Image Swap
 */
   var cached = {};
  var overlay_video = $(".carousel__bg video");
  var overlay_img = $(".carousel__bg img");
  var overlay = $(".carousel__bg");
  $(".carousel__item")
    .on('mouseenter', function() {
      
      var item = $(this),
        spot = $(this).index(".carousel__item"),
        value = item.data("src");
      
      overlay_video.empty();

      var overlay_item;
      overlay.fadeTo(0, 0);
      //videos will have an array ur urls
      var is_video = value instanceof Array;
      if(is_video) {
        overlay_item = overlay_video;
        overlay_img.attr("src", '');
       
        
        overlay_video.append(value.map((url) => {
           var extension = url.split('.').pop(); 
           var type = VIDEO_TYPES[extension];
            return `<source src="${url}" type="${type}">`
        }));
        
      } else {
        overlay_item = overlay_img;
        overlay_img.attr("src", value);
      }
      //force the video element to reload
      overlay_video.get(0).load();
      
      if (!overlay_item.complete && !cached[spot]) {
        cached[spot] = true;
        overlay.addClass("loading");
     
       
        overlay_item.one(is_video ? "loadeddata" : "load", function() {
           overlay.removeClass("loading");
           overlay.fadeTo(300, 1);
        });
      } else  overlay.fadeTo(300, 1);
    })

    .on('mouseleave', function() {
      overlay.finish();
    });
});
/**
 * Base styling.
 */

html {
	background: rgb(255,255,255);
	font-size: 62.5%;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	-webkit-overflow-scrolling: touch;
	-webkit-text-size-adjust: 100%;
}

body {
	background-color: transparent;
	color: rgb(0,0,0);
	font-variant-ligatures: common-ligatures discretionary-ligatures historical-ligatures;
	font-family: 'Roboto', sans-serif;
	font-size: 1.6rem;
	font-weight: 400;
	line-height: 1.6rem;
	margin: 0;
	padding: 30px 0 0;
	text-rendering: optimizeLegibility;
}



/**
 * Carousel
 */

.carousel {
	background: rgb(0,0,0);
	color: rgb(255,255,255);
	height: 640px;
	margin: 0 auto;
	overflow: hidden;
	position: relative;
	width: 100%;
	max-width: 1200px;
}

.carousel:before,
.carousel:after {
	background: rgba(255,255,255,.25);
	content: "";
	height: 100%;
	position: absolute;
	top: 0;
	left: 33.33333%;
	width: 1px;
	z-index: 30;
}

.carousel:after {
	left: 66.66666%;
}



/**
 * Background (fullwidth) image
 */

.carousel__bg {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	height: 100%;
	width: 100%;
}

.carousel__bg.loading {
	background: url(../img/interface/loading.gif) no-repeat center center;
}

.carousel__bg img, .carousel__bg video {
	display: block;
	height: 640px;
	object-fit: cover;
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	width: 100%; 
}



/**
 * Individual carousel item
 */

.carousel__item {
	box-sizing: border-box;
	float: left;
	height: 640px;
	position: relative;
	width: 33.33333%; 
}

.carousel__item:hover {
	cursor: pointer;
}



/* Text Content */

.carousel__content {
	background: rgba(0,0,0,.45);
	box-sizing: border-box;
	color: rgb(255,255,255);
	height: 100%;
	min-height: 100%;
	padding: 30px;
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	z-index: 15;
}


.carousel__title,
.carousel__subtitle,
.carousel__flag {
	color: rgb(255,255,255);
	letter-spacing: 1px;
	font-family: 'Anton', sans-serif;
	font-weight: 400;
	line-height: 1;
	margin: 0 0 5px;
	padding: 0;
	text-transform: uppercase;
}

.carousel__title {
	font-size: 20px;
	transition: all .25s;
}

.carousel__subtitle {
	display: none;
	font-size: 48px;
}

.carousel__flag {
	color: rgb(45,190,193);
	font-size: 14px;
}



/* Button */

.carousel__btn {
	background: transparent;
	border: 1px solid rgb(255,255,255);
	box-sizing: border-box;
	color: rgb(255,255,255);
	display: block;
	font-family: 'Anton', sans-serif;
	font-size: 12px;
	font-weight: 400;
	height: 45px;
	line-height: 45px;
	letter-spacing: 1px;
	opacity: 0;
	position: absolute;
	padding: 0 30px;
	bottom: 30px;
	left: 30px;
	right: 30px;
	text-align: center;
	text-decoration: none;
	text-transform: uppercase;
	transition: all .15s;
	-webkit-backface-visibility: hidden;
}

.carousel__btn:visited {
	background: transparent;
}

.carousel__btn:focus,
.carousel__btn:hover {
	background: rgb(45,190,193);
	border-color: rgb(45,190,193);
}



/* Image */

.carousel__image {
	display: block;
	height: 100%;
	opacity: 1;
	object-fit: cover;
	transition: all .30s;
	position: relative;
	width: 100%;
	max-width: 100%;
	-webkit-backface-visibility: hidden;
}



/* When hovering over the carousel, fade all the titles out */

.carousel>.slick-carousel>.slick-list:hover .carousel__title {
	opacity: .30;
}

/* But not the one contained without the 'item' you're hovering over */

.carousel:hover .carousel__item:hover .carousel__title {
	opacity: 1;
}

/* Fade all images out so the fullwidth background image is visble */

.carousel>.slick-carousel>.slick-list:hover  .carousel__image {
	opacity: 0;
}

/* Hide the flag element */

.carousel>.slick-carousel>.slick-list:hover .carousel__flag {
	display: none;
}

/* Show the subtitle */

.carousel:hover .carousel__item:hover .carousel__subtitle {
	display: block;
}

/* Display the CTA of the active item */

.carousel:hover .carousel__item:hover .carousel__btn {
	opacity: 1;
}






/* Slick Prev/Next */

.slick-carousel,
.slick-list,
.slick-track {
	height: 100%;
	min-height: 100%;
}


.slick-arrow {
	background: transparent;
	border: 1px solid rgb(255,255,255);
	color: rgb(255,255,255);
	display: block;
	font-family: 'Anton', sans-serif;
	font-size: 24px;
	height: 45px;
	line-height: 45px;
	margin-top: -30px;
	overflow: hidden;
	position: absolute;
	top: 50%;
	left: 30px;
	text-align: center;
	transform: rotate(45deg);
	transition: all .15s;
	width: 45px;
	z-index: 60;
}

.slick-arrow:hover {
	background: rgb(255,255,255);
	color: rgb(0,0,0);
}

.slick-arrow span {
	display: block;
	transform: rotate(-45deg);
}

.slick-arrow--next {
	left: auto;
	right: 30px;
}



/* Slick Core */

.slick-slider
{
    position: relative;

    display: block;
    box-sizing: border-box;

    -webkit-user-select: none;
       -moz-user-select: none;
        -ms-user-select: none;
            user-select: none;

    -webkit-touch-callout: none;
    -khtml-user-select: none;
    -ms-touch-action: pan-y;
        touch-action: pan-y;
    -webkit-tap-highlight-color: transparent;
}

.slick-list
{
    position: relative;

    display: block;
    overflow: hidden;

    margin: 0;
    padding: 0;
}
.slick-list:focus
{
    outline: none;
}
.slick-list.dragging
{
    cursor: pointer;
    cursor: hand;
}

.slick-slider .slick-track,
.slick-slider .slick-list
{
    -webkit-transform: translate3d(0, 0, 0);
       -moz-transform: translate3d(0, 0, 0);
        -ms-transform: translate3d(0, 0, 0);
         -o-transform: translate3d(0, 0, 0);
            transform: translate3d(0, 0, 0);
}

.slick-track
{
    position: relative;
    top: 0;
    left: 0;

    display: block;
    margin-left: auto;
    margin-right: auto;
}
.slick-track:before,
.slick-track:after
{
    display: table;

    content: '';
}
.slick-track:after
{
    clear: both;
}
.slick-loading .slick-track
{
    visibility: hidden;
}

.slick-slide
{
    display: none;
    float: left;

    height: 100%;
    min-height: 1px;
}
[dir='rtl'] .slick-slide
{
    float: right;
}
.slick-slide img
{
    display: block;
}
.slick-slide.slick-loading img
{
    display: none;
}
.slick-slide.dragging img
{
    pointer-events: none;
}
.slick-initialized .slick-slide
{
    display: block;
}
.slick-loading .slick-slide
{
    visibility: hidden;
}
.slick-vertical .slick-slide
{
    display: block;

    height: auto;

    border: 1px solid transparent;
}
.slick-arrow.slick-hidden {
    display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.min.js"></script>
<div class="carousel">

  <div class="carousel__bg">
    <img src="" />
    <video autoplay muted loop></video>
  </div>

  <div class="slick-carousel">

    <div class="carousel__item" data-src="https://www.fillmurray.com/750/550">
      <div class="carousel__content">
        <h4 class="carousel__title">Behind The Scenes</h4>
        <span class="carousel__flag">// Featured</span>
        <h2 class="carousel__subtitle">Lorem ipsum dolor</h2>
        <a href="#" class="carousel__btn">Read the Article</a>
      </div>
      <img src="https://www.fillmurray.com/g/400/600" class="carousel__image" />
    </div>

    <div class="carousel__item" data-src="https://www.fillmurray.com/800/600">
      <div class="carousel__content">
        <h4 class="carousel__title">Reed Stark</h4>
        <span class="carousel__flag">// Featured</span>
        <h2 class="carousel__subtitle">Lorem ipsum dolor</h2>
        <a href="#" class="carousel__btn">Watch the Video</a>
      </div>
      <img src="https://www.fillmurray.com/g/450/650" class="carousel__image" />
    </div>

    <div class="carousel__item" data-src='[ "https://www.w3schools.com/tags/movie.mp4", "https://www.w3schools.com/tags/movie.ogg"]'>
      <div class="carousel__content">
        <h4 class="carousel__title">Fresh Drops</h4>
        <span class="carousel__flag">// Featured</span>
        <h2 class="carousel__subtitle">Lorem ipsum dolor</h2>
        <a href="#" class="carousel__btn">See The Collection</a>
      </div>
      <img src="https://www.fillmurray.com/g/350/550" class="carousel__image" />
    </div>
    
    <div class="carousel__item" data-src='[ "https://www.w3schools.com/tags/movie.mp4", "https://www.w3schools.com/tags/movie.ogg"]'>
      <div class="carousel__content">
        <h4 class="carousel__title">Fresh Drops</h4>
        <span class="carousel__flag">// Featured</span>
        <h2 class="carousel__subtitle">Lorem ipsum dolor</h2>
        <a href="#" class="carousel__btn">See The Collection</a>
      </div>
      <img src="https://www.fillmurray.com/g/300/500" class="carousel__image" />
    </div>

  </div>

</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...