简体   繁体   English

如何使用纯JavaScript和CSS创建垂直轮播

[英]How to create a vertical carousel using plain JavaScript and CSS

I am trying to create a vertical carousel using vanilla JavaScript and CSS. 我正在尝试使用vanilla JavaScript和CSS创建一个垂直轮播。 I know that jQuery has a carousel library but I want to have a go at building this from scratch using no external libraries. 我知道jQuery有一个轮播库但是我想要从头开始构建这个没有外部库的东西。 I started off by just trying to move the top image and then I planned to move on to making the next image move. 我开始尝试移动顶部图像,然后我计划继续进行下一个图像移动。 I got stuck on the first image. 我卡在第一张图片上。 This is where I need your help, StackOverflowers. 这是我需要你帮助的地方,StackOverflowers。

My HTML: 我的HTML:

<div class="slider vertical" >
    <img class="first opened" src="http://malsup.github.io/images/beach1.jpg">
    <img class="opened" src="http://malsup.github.io/images/beach2.jpg">
    <img src="http://malsup.github.io/images/beach3.jpg">
    <img src="http://malsup.github.io/images/beach4.jpg">
    <img src="http://malsup.github.io/images/beach5.jpg">
    <img src="http://malsup.github.io/images/beach9.jpg">
</div>
<div class="center">
    <button id="prev">∧ Prev</button>
    <button id="next">∨ Next</button>
</div>

JavaScript: JavaScript的:

var next = document.getElementById('next');
var target = document.querySelector('.first');

next.addEventListener('click', nextImg, false);

function nextImg(){
     if (target.classList.contains('opened')) {
        target.classList.remove('opened');
        target.classList.add('closed');
    } else {
        target.classList.remove('closed');
        target.classList.add('opened');
    }
}

CSS: CSS:

div.vertical {
    width: 100px;
}

.slider {
    position: relative;
    overflow: hidden;
    height: 250px;

        -webkit-box-sizing:border-box;
       -moz-box-sizing:border-box;
        -ms-box-sizing:border-box;
            box-sizing:border-box;

    -webkit-transition:-webkit-transform 1.3s ease;
       -moz-transition:   -moz-transform 1.3s ease;
        -ms-transition:    -ms-transform 1.3s ease;
            transition:        transform 1.3s ease;
}

.slider img {
    width: 100px;
    height: auto;
    padding: 2px;
}

.first.closed{
    /* partially offscreen */
    -webkit-transform: translate(0, -80%);
       -moz-transform: translate(0, -80%);
        -ms-transform: translate(0, -80%);
            transform: translate(0, -80%);
}

.first.opened{
    /* visible */
    -webkit-transform: translate(0, 0%);
       -moz-transform: translate(0, 0%);
        -ms-transform: translate(0, 0%);
            transform: translate(0, 0%);
}

My mode of thinking was: 我的思维方式是:

  1. use classes to move and show content 使用类来移动和显示内容
  2. use JavaScript to add and remove classes 使用JavaScript添加和删除类

I think I may not have broken the problem down properly. 我想我可能没有正确地解决问题。

This is how I would like it to look: http://jsfiddle.net/natnaydenova/7uXPx/ 这就是我希望它的样子: http//jsfiddle.net/natnaydenova/7uXPx/

And this is my abysmal attempt: http://jsfiddle.net/6cb58pkr/ 这是我的糟糕尝试: http//jsfiddle.net/6cb58pkr/

An alternative to using CSS transform properties is to give the carousel absolute positioning inside a wrapper div and manipulate the carousel's top property. 使用CSS transform属性的另一种方法是将转盘绝对定位在包装器div并操纵转盘的top属性。 Then you can use any easing function you like to animate the sliding motion. 然后,您可以使用任何您喜欢的缓动功能来设置滑动动画。 In the snippet below, I use cubic easing in/out . 在下面的代码段中,我使用立方缓和输入/输出

A tricky thing to watch out for is the order in which you rotate the images and perform the sliding animation. 需要注意的一个棘手的事情是旋转图像和执行滑动动画的顺序。 When you want to show the next picture below, you have to: 当您想要显示下面的下一张图片时,您必须:

  • slide the carousel up by the height of one picture frame 将旋转木马滑动到一个相框的​​高度
  • rotate the first image to the end 将第一张图像旋转到最后
  • reset the carousel's vertical offset to zero 将轮播的垂直偏移重置为零

To show the next picture above: 要显示上面的下一张图片:

  • rotate the last image to the beginning 将最后一张图像旋转到开头
  • instantly move the carousel up by the height of one picture frame 立即将旋转木马移动到一个相框的​​高度
  • slide the carousel down until its vertical offset reaches zero 向下滑动转盘,直到其垂直偏移达到零

In the following snippet, you can set the width of the carousel by adjusting Carousel.width at the top of the script. 在下面的代码片段中,您可以通过调整脚本顶部的Carousel.width来设置轮播的宽度。 (Although the image height doesn't have to be the same as the image width, I do assume that all images have the same dimensions.) You can also play around with the Carousel.numVisible and Carousel.duration parameters. (虽然图像高度不必与图像宽度相同,但我确实假设所有图像具有相同的尺寸。)您还可以使用Carousel.numVisibleCarousel.duration参数。

 var Carousel = { width: 100, // Images are forced into a width of this many pixels. numVisible: 2, // The number of images visible at once. duration: 600, // Animation duration in milliseconds. padding: 2 // Vertical padding around each image, in pixels. }; function rotateForward() { var carousel = Carousel.carousel, children = carousel.children, firstChild = children[0], lastChild = children[children.length - 1]; carousel.insertBefore(lastChild, firstChild); } function rotateBackward() { var carousel = Carousel.carousel, children = carousel.children, firstChild = children[0], lastChild = children[children.length - 1]; carousel.insertBefore(firstChild, lastChild.nextSibling); } function animate(begin, end, finalTask) { var wrapper = Carousel.wrapper, carousel = Carousel.carousel, change = end - begin, duration = Carousel.duration, startTime = Date.now(); carousel.style.top = begin + 'px'; var animateInterval = window.setInterval(function () { var t = Date.now() - startTime; if (t >= duration) { window.clearInterval(animateInterval); finalTask(); return; } t /= (duration / 2); var top = begin + (t < 1 ? change / 2 * Math.pow(t, 3) : change / 2 * (Math.pow(t - 2, 3) + 2)); carousel.style.top = top + 'px'; }, 1000 / 60); } window.onload = function () { document.getElementById('spinner').style.display = 'none'; var carousel = Carousel.carousel = document.getElementById('carousel'), images = carousel.getElementsByTagName('img'), numImages = images.length, imageWidth = Carousel.width, aspectRatio = images[0].width / images[0].height, imageHeight = imageWidth / aspectRatio, padding = Carousel.padding, rowHeight = Carousel.rowHeight = imageHeight + 2 * padding; carousel.style.width = imageWidth + 'px'; for (var i = 0; i < numImages; ++i) { var image = images[i], frame = document.createElement('div'); frame.className = 'pictureFrame'; var aspectRatio = image.offsetWidth / image.offsetHeight; image.style.width = frame.style.width = imageWidth + 'px'; image.style.height = imageHeight + 'px'; image.style.paddingTop = padding + 'px'; image.style.paddingBottom = padding + 'px'; frame.style.height = rowHeight + 'px'; carousel.insertBefore(frame, image); frame.appendChild(image); } Carousel.rowHeight = carousel.getElementsByTagName('div')[0].offsetHeight; carousel.style.height = Carousel.numVisible * Carousel.rowHeight + 'px'; carousel.style.visibility = 'visible'; var wrapper = Carousel.wrapper = document.createElement('div'); wrapper.id = 'carouselWrapper'; wrapper.style.width = carousel.offsetWidth + 'px'; wrapper.style.height = carousel.offsetHeight + 'px'; carousel.parentNode.insertBefore(wrapper, carousel); wrapper.appendChild(carousel); var prevButton = document.getElementById('prev'), nextButton = document.getElementById('next'); prevButton.onclick = function () { prevButton.disabled = nextButton.disabled = true; rotateForward(); animate(-Carousel.rowHeight, 0, function () { carousel.style.top = '0'; prevButton.disabled = nextButton.disabled = false; }); }; nextButton.onclick = function () { prevButton.disabled = nextButton.disabled = true; animate(0, -Carousel.rowHeight, function () { rotateBackward(); carousel.style.top = '0'; prevButton.disabled = nextButton.disabled = false; }); }; }; 
 body { font-family: sans-serif; } .buttons { margin: 5px 0; } button { font-size: 14px; display: inline; padding: 3px 6px; border: 2px solid #ccc; background: #fff; border-radius: 5px; outline: none; } button:hover { border: 2px solid #888; background: #ffe; cursor: pointer; } #carouselWrapper { position: relative; overflow: hidden; } #carousel { position: absolute; visibility: hidden; } 
 <div id="spinner"> Loading... </div> <div id="carousel"> <img src="http://malsup.github.io/images/beach1.jpg"> <img src="http://malsup.github.io/images/beach2.jpg"> <img src="http://malsup.github.io/images/beach3.jpg"> <img src="http://malsup.github.io/images/beach4.jpg"> <img src="http://malsup.github.io/images/beach5.jpg"> <img src="http://malsup.github.io/images/beach9.jpg"> </div> <div class="buttons"> <button id="prev">&uarr; Prev</button> <button id="next">&darr; Next</button> </div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM