Плавающие элементы карусели переносятся вместо того, чтобы оставаться в одном ряду и не отображаются при прокрутке - PullRequest
0 голосов
/ 26 мая 2018

У меня почти 20 <div> с изображениями в слайдере, но отображаются только 6:

$(window).load(function() {
  var view = $("#tslshow");
  var move = "196px";
  var sliderLimit = -450

  $("#rightArrow").click(function() {
    var currentPosition = parseInt(view.css("left"));
    
    if (currentPosition >= sliderLimit) view.stop(false, true).animate({
      left: "-=" + move
    }, {
      duration: 200
    })
  });

  $("#leftArrow").click(function() {
    var currentPosition = parseInt(view.css("left"));
    
    if (currentPosition < 0) view.stop(false, true).animate({
      left: "+=" + move
    }, {
      duration: 200
    })
  });
});
.bstimeslider {
  background: transparent;
  height: 126px;
  position: relative;  
  width: 1100px;  
}

.bktibx { 
  background: rgba(17,17,17,.7);
  color: #ffffff; 
  display: block; 
  height: 126px; 
  float: left;
  font-size: 16px;
  margin:0 10px 0 0;
  width: 186px; 
}

.bktibx-top { 
  background: rgba(17,17,17,.7);
  color: #ffffff; 
  display: block; 
  float: left;
  font-size: 16px;
  margin: 0 40px 0 0;
  padding: 10px;
  width: 166px; 
}

.bktibx img { 
  height: 88px;
  padding-top: 0px;
  width: 186px;
}

#tslshow {
  left: 0;
  position: absolute;
  width: 1200px;  
}

#leftArrow {
  background: #ff0000; 
  height: 45px;
  left: 0px;
  position: absolute;
  top: 41px;
  width: 40px;
}

#rightArrow { 
  background: #ff0000; 
  height: 45px;
  position: absolute;
  right: 0px;
  top: 41px;
  width: 40px;
}

#viewContainer {
  background: transparent;
  height: 100%;
  margin: 0px 40px 0px 40px;
  overflow: hidden;
  position: absolute;
  width: 1020px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<div class="bstimeslider">

  <div id="rightArrow"></div>
  
  <div id="viewContainer">
    <div id="tslshow">
    
      <div class="bktibx">
        <div class="bktibx-top">
          transparent
        </div>
        <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
      </div>
      
      <div class="bktibx">
        <div class="bktibx-top">
          transparent
        </div>
        <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
      </div>
      
      <div class="bktibx">
        <div class="bktibx-top">
          transparent
        </div>
        <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
      </div>
      
      <div class="bktibx">
        <div class="bktibx-top">
          transparent
        </div>
        <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
      </div>
      
      <div class="bktibx">
        <div class="bktibx-top">
          transparent
        </div>
        <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
      </div>
      
      <div class="bktibx">
        <div class="bktibx-top">
          transparent
        </div>
        <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
      </div>
      
      <div class="bktibx">
        <div class="bktibx-top">
          transparent
        </div>
        <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
      </div>
      
      <div class="bktibx">
        <div class="bktibx-top">
          transparent
        </div>
        <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
      </div>
      
      <div class="bktibx">
        <div class="bktibx-top">
          transparent
        </div>
        <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
      </div>
      
      <div class="bktibx">
        <div class="bktibx-top">
          transparent
        </div>
        <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
      </div>
      
      <div class="bktibx">
        <div class="bktibx-top">
          transparent
        </div>
        <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
      </div>
      
      <div class="bktibx">
        <div class="bktibx-top">
          transparent
        </div>
        <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
      </div>
      
      <div class="bktibx">
        <div class="bktibx-top">
          transparent
        </div>
        <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
      </div>
      
      <div class="bktibx">
        <div class="bktibx-top">
          transparent
        </div>
        <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
      </div>
      
      <div class="bktibx">
        <div class="bktibx-top">
          transparent
        </div>
        <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
      </div>
      
    </div>
  </div>
  
  <div id="leftArrow"></div>
</div>

1 Ответ

0 голосов
/ 26 мая 2018

Ваши элементы обертываются, потому что #tslshow недостаточно широка, как вы можете увидеть, если вы проверите с инспектором.

У вас есть 3 варианта исправить это:

  1. Используйте white-space: nowrap и display: inline-block (с некоторыми дополнительными настройками, которые вы можете увидеть в фрагменте ниже):

    .bktibx {
        display: inline-block; /* Instead of float: left */
    }
    
    #tslshow {
        white-space: nowrap;
        font-size: 0;
    }
    
  2. Использование flexbox :

    .bktibx {
        /* Just remove float: left; */
    }
    
    #tslshow {
        display: flex;
    }
    
  3. Использование max-width: unset и min-width: max-content (эксперимент) :

    #tslshow {
        position: absolute;
        left: 0;
        max-width: unset;
        min-width: max-content;
    }
    

С помощью первой и второй опций вы также можете удалить position: absolute из #tslshow и использовать transform: translate(-Npx) и transition: translate ease-in 250ms для прокрутки и анимации.

В третьем вы все еще можете использовать left, но анимируйте его с помощью transition: left ease-in 250ms вместо использования jQuery.

? Вариант 1 - пробел: nowrap:

const scrollable = document.getElementById('tslshow');
const children = 20;

// Just to avoid having that big ching of HTML:
scrollable.innerHTML = `
  <div class="bktibx">
    <div class="bktibx-top">Title</div>
    <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
  </div>
`.repeat(children);

const move = 196;
const min = - (move * scrollable.children.length) + 10 + scrollable.offsetWidth;

let current = 0;

document.getElementById('rightArrow').onclick = () => {
  current = Math.max(min, current - move);

  scrollable.style.transform = `translate(${ current }px)`;
};

document.getElementById('leftArrow').onclick = () => {
  current = Math.min(0, current + move);

  scrollable.style.transform = `translate(${ current }px)`;
};
.bstimeslider {
  background: transparent;
  height: 126px;
  position: relative;  
  width: 100%;  
}

.bktibx { 
  background: rgba(17,17,17,.7);
  color: #ffffff; 
  display: block; 
  height: 126px;
  font-size: 16px;
  margin:0 10px 0 0;
  width: 186px;
  
  /* I have changed this (instead of float: left)... */
  display: inline-block;
}

.bktibx-top { 
  background: rgba(17,17,17,.7);
  color: #ffffff; 
  display: block;
  font-size: 16px;
  margin: 0 40px 0 0;
  padding: 10px;
  width: 166px;
  
  /* ...removed the float: left here... */
}

.bktibx img { 
  height: 88px;
  padding-top: 0px;
  width: 186px;
}

#tslshow {
  /* ...changed this completelly... */
  white-space: nowrap;
  font-size: 0;
  transition: transform ease-in 250ms;
}

#leftArrow {
  background: #ff0000; 
  height: 45px;
  left: 0px;
  position: absolute;
  top: 41px;
  width: 40px;
}

#rightArrow { 
  background: #ff0000; 
  height: 45px;
  position: absolute;
  right: 0px;
  top: 41px;
  width: 40px;
}

#viewContainer {
  background: transparent;
  height: 100%;
  overflow: hidden;

  /* ...and changed this. */
  position: absolute;
  top: 0;
  left: 40px;
  right: 40px;
}
<div class="bstimeslider">
  <div id="rightArrow"></div>
  
  <div id="viewContainer">
    <div id="tslshow"></div>
  </div>
  
  <div id="leftArrow"></div>
</div>

✨ Вариант 2 - Flexbox:

const scrollable = document.getElementById('tslshow');
const children = 20;

// Just to avoid having that big ching of HTML:
scrollable.innerHTML = `
  <div class="bktibx">
    <div class="bktibx-top">Title</div>
    <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
  </div>
`.repeat(children);

const move = 196;
const min = - (move * scrollable.children.length) + 10 + scrollable.offsetWidth;

let current = 0;

document.getElementById('rightArrow').onclick = () => {
  current = Math.max(min, current - move);

  scrollable.style.transform = `translate(${ current }px)`;
};

document.getElementById('leftArrow').onclick = () => {
  current = Math.min(0, current + move);

  scrollable.style.transform = `translate(${ current }px)`;
};
.bstimeslider {
  background: transparent;
  height: 126px;
  position: relative;  
  width: 100%;  
}

.bktibx { 
  background: rgba(17,17,17,.7);
  color: #ffffff; 
  display: block; 
  height: 126px;
  font-size: 16px;
  margin:0 10px 0 0;
  width: 186px; 

  /* I have removed float: left here... */
}

.bktibx-top { 
  background: rgba(17,17,17,.7);
  color: #ffffff; 
  display: block;
  float: left;
  font-size: 16px;
  margin: 0 40px 0 0;
  padding: 10px;
  width: 166px; 
}

.bktibx img { 
  height: 88px;
  padding-top: 0px;
  width: 186px;
}

#tslshow {
  /* ...changed this completelly... */
  display: flex;
  transition: transform ease-in 250ms;
}

#leftArrow {
  background: #ff0000; 
  height: 45px;
  left: 0px;
  position: absolute;
  top: 41px;
  width: 40px;
}

#rightArrow { 
  background: #ff0000; 
  height: 45px;
  position: absolute;
  right: 0px;
  top: 41px;
  width: 40px;
}

#viewContainer {
  background: transparent;
  height: 100%;
  overflow: hidden;

  /* ...changed this. */
  position: absolute;
  top: 0;
  left: 40px;
  right: 40px;
}
<div class="bstimeslider">
  <div id="rightArrow"></div>
  
  <div id="viewContainer">
    <div id="tslshow"></div>
  </div>
  
  <div id="leftArrow"></div>
</div>

? Вариант 3 - Экспериментальная max-width: max-content

const scrollable = document.getElementById('tslshow');
const children = 20;

// Just to avoid having that big ching of HTML:
scrollable.innerHTML = `
  <div class="bktibx">
    <div class="bktibx-top">Title</div>
    <img src="https://www.bing.com/th?id=OPN.RTNews_iokoUEg279vnqHFa5nIABQ&w=186&h=88&c=7&rs=2&qlt=80&cdv=1&pid=News"/>
  </div>
`.repeat(children);

const move = 196;
const min = - (move * scrollable.children.length) + 10 + scrollable.parentElement.offsetWidth;

let current = 0;

document.getElementById('rightArrow').onclick = () => {
  current = Math.max(min, current - move);

  scrollable.style.left = `${ current }px`;
};

document.getElementById('leftArrow').onclick = () => {
  current = Math.min(0, current + move);

  scrollable.style.left = `${ current }px`;
};
.bstimeslider {
  background: transparent;
  height: 126px;
  position: relative;  
  width: 100%;  
}

.bktibx { 
  background: rgba(17,17,17,.7);
  color: #ffffff; 
  display: block; 
  height: 126px; 
  float: left;
  font-size: 16px;
  margin:0 10px 0 0;
  width: 186px; 
}

.bktibx-top { 
  background: rgba(17,17,17,.7);
  color: #ffffff; 
  display: block; 
  float: left;
  font-size: 16px;
  margin: 0 40px 0 0;
  padding: 10px;
  width: 166px; 
}

.bktibx img { 
  height: 88px;
  padding-top: 0px;
  width: 186px;
}

#tslshow {
  left: 0;
  position: absolute;
  
  /* I have change this... */
  max-width: unset;
  min-width: max-content;
  transition: left ease-in 250ms;
}

#leftArrow {
  background: #ff0000; 
  height: 45px;
  left: 0px;
  position: absolute;
  top: 41px;
  width: 40px;
}

#rightArrow { 
  background: #ff0000; 
  height: 45px;
  position: absolute;
  right: 0px;
  top: 41px;
  width: 40px;
}

#viewContainer {
  background: transparent;
  height: 100%;
  overflow: hidden;
  
  /* ...and this */
  position: absolute;
  top: 0;
  left: 40px;
  right: 40px;
}
<div class="bstimeslider">
  <div id="rightArrow"></div>
  
  <div id="viewContainer">
    <div id="tslshow"></div>
  </div>
  
  <div id="leftArrow"></div>
</div>
...