javascript - 使用 JavaScript 启用 CSS 幻灯片自动播放
问题描述
我只使用 CSS 制作了一个简单的幻灯片,单击单选按钮时,元素的边距会发生变化,因此它会显示所需的幻灯片。您可以在下面的代码片段中看到它是如何工作的。我还用 JavaScript 制作了这个幻灯片自动播放。该脚本每 3 秒检查一次列表中的下一个单选按钮。
现在我需要帮助以使幻灯片自动循环播放,并在您手动检查任何单选按钮时停止自动播放。
$(document).ready(function() {
function autoplay() {
$("input[name=radio-button]:checked").nextAll(':radio:first').prop('checked', true);
};
setInterval(autoplay, 3000);
});
body {
margin: 0;
padding: 0;
}
.slider {
width: 300%;
transition: margin 1s;
height: 100px;
}
#radio-button1:checked ~ .slider {
margin-left: 0%;
}
#radio-button2:checked ~ .slider {
margin-left: -100%;
}
#radio-button3:checked ~ .slider {
margin-left: -200%;
}
.slider-item {
float: left;
width: 33.33%;
height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<input type="radio" name="radio-button" id="radio-button1" checked />
<input type="radio" name="radio-button" id="radio-button2" />
<input type="radio" name="radio-button" id="radio-button3" />
<div class="slider">
<div class="slider-item" style="background: #F00"></div>
<div class="slider-item" style="background: #0F0"></div>
<div class="slider-item" style="background: #00F"></div>
</div>
解决方案
创建一个curr
变量,在区间内将其递增并使用 Modulo%
将其循环回 0:
jQuery(function($) { // DOM ready and $ alias in scope
var curr = 0;
function autoplay() {
curr = ++curr % 3; // Increment and Reset to 0 when 3
$("[name=radio-button]")[curr].checked = true;
}
setInterval(autoplay, 3000);
});
body {
margin: 0;
padding: 0;
}
.slider {
width: 300%;
transition: margin 1s;
height: 100px;
}
#radio-button1:checked~.slider {
margin-left: 0%;
}
#radio-button2:checked~.slider {
margin-left: -100%;
}
#radio-button3:checked~.slider {
margin-left: -200%;
}
.slider-item {
float: left;
width: 33.33%;
height: 100%;
}
<input type="radio" name="radio-button" id="radio-button1" checked />
<input type="radio" name="radio-button" id="radio-button2" />
<input type="radio" name="radio-button" id="radio-button3" />
<div class="slider">
<div class="slider-item" style="background: #F00"></div>
<div class="slider-item" style="background: #0F0"></div>
<div class="slider-item" style="background: #00F"></div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
更好的方法:
- 溢出一个超级父,所以你不会得到滚动条
- 使用
display: flex;
而不是丑陋的花车。 - 使用
$('.slider').each(
这样您就可以在一个页面中拥有多个滑块! - 创建一个
anim()
play()
andstop()
函数来控制发生的事情。 transform:
使用和制作动画transition
,因为过渡是 GPU 加速的。虽然边距不是,但需要回流和重绘。- 使用
curr * -100
% 为变换设置动画 - 需要时使用
curr %= tot
(Modulo operator) 将curr
索引环回为 0。 - 为什么要手动创建按钮?手动创建幻灯片,让 JS 为您创建按钮。
- 通过
setInterval
将其存储到变量中来使用itv
- 停止使用自动动画
clearInterval(itv)
- 用于
.hover(stop, play)
在 mouseenter 上停止并在 mouseleave 上自动播放
$('.slider').each(function(slider_idx) { // Use each, so you can have multiple sliders
let curr = 0; // Set current index
let itv = null; // The interval holder
const $slider = $(this);
const $nav = $('.slider-nav', $slider);
const $items = $('.slider-items', $slider);
const $item = $('.slider-item', $slider);
const tot = $item.length; // How many
const btns = [...new Array(tot)].map((_, i) => $('<input>', {
type: 'radio',
name: `slider-btn-${slider_idx}`,
checked: curr == i,
change() { // On button change event
curr = i; // Set current index to this button index
anim();
}
})[0]);
function anim() {
$items.css({transform: `translateX(-${curr*100}%)`}); // Animate
btns[curr].checked = true; // Change nav btn state
}
function play() {
itv = setInterval(() => {
curr = ++curr % tot; // increment curr and reset to 0 if exceeds tot
anim(); // and animate!
}, 3000); // Do every 3sec
}
function stop() {
clearInterval(itv);
}
$nav.empty().append(btns); // Insert buttons
$slider.hover(stop, play); // Handle hover state
play(); // Start autoplay!
});
/*QuickReset*/ * {margin: 0; box-sizing: border-box;}
.slider {
position: relative;
height: 100px;
}
.slider-overflow {
overflow: hidden; /* use an overflow parent! You don't want scrollbars */
height: inherit;
}
.slider-items {
display: flex; /* Use flex */
flex-flow: row nowrap;
height: inherit;
transition: transform 1s; /* Don't use margin, use transform */
}
.slider-item {
flex: 0 0 100%;
height: inherit;
}
.slider-nav {
position: absolute;
width: 100%;
bottom: 0;
text-align: center;
}
<div class="slider">
<div class="slider-overflow">
<div class="slider-items"> <!-- This one will transition -->
<div class="slider-item" style="background:#0bf;">curr = 0</div>
<div class="slider-item" style="background:#fb0;">curr = 1</div>
<div class="slider-item" style="background:#f0b;">curr = 2</div>
</div>
</div>
<div class="slider-nav">
<!-- JS will populate buttons here -->
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
因此,两个 DIV 元素都.slider-nav
需要.slider-overflow
在公共父级内部.slider
- 以便我们在与这些元素进行任何交互后正确停止(暂停)自动动画。
推荐阅读
- function - Ocaml 表达式类型混淆
- javascript - 使用 JavaScript 的 eBay API CORS 请求返回未定义
- arrays - 角度过滤器嵌套数组
- c# - 好奇我缺少什么使用目录
- python - For Loop ignored while running an async function (Discord Bot using the Python API)
- php - laravel 应用程序中的 htaccess
- python - PyCharm 格式在换行时添加了制表符和空格的混合
- bash - 用于检查目录结构的 Bash 脚本?
- node.js - 如果 npm 已经有 npm-shrinkwrap.json 用于锁定目的,为什么还要创建 package-lock.json?
- arrays - 数组的子数组列表