【发布时间】:2019-03-17 15:19:01
【问题描述】:
我正在尝试创建 vanila js 动态滑块。我完成了调整大小,现在开始制作动画,向左滑动,对于初学者。这是一个问题。已经存在且可见的幻灯片完美地向左移动。但是我在动画之前创建的新幻灯片不会移动,它们只是显示在最终位置。我做错了什么?
function Slider(options) {
const slider = document.querySelector("#" + options.id);
const blocks = {};
["left", "main", "right"].forEach(name => addBlock(name));
const iWidth = options.itemWidth;
const items = [];
let currentPosition = 0;
insertItems();
function addBlock(name) {
blocks[name] = document.createElement('div');
blocks[name].className = name;
slider.appendChild(blocks[name]);
}
function insertItems() {
const slider = {items: blocks.main, position: currentPosition};
slider.width = blocks.main.clientWidth;
slider.canFit = Math.floor(slider.width / iWidth);
slider.gap = (slider.width - slider.canFit * iWidth) / (slider.canFit > 1 ? slider.canFit - 1 : 1);
for (let i = 0; i < options.max; i++) {
items.push(new Item({slider: slider, item: {width: iWidth, index: i}}))
}
}
function updateItems() {
const slider = {position: currentPosition};
slider.width = blocks.main.clientWidth;
slider.canFit = Math.floor(slider.width / iWidth);
slider.gap = (slider.width - slider.canFit * iWidth) / (slider.canFit > 1 ? slider.canFit - 1 : 1);
for (let i = 0; i < options.max; i++) {
items[i].update(slider);
}
}
function slideLeft() {
const width = blocks.main.clientWidth;
const canFit = Math.floor(width / iWidth);
const gap = (width - canFit * iWidth) / (canFit > 1 ? canFit - 1 : 1);
currentPosition -= canFit * (gap + iWidth);
for (let i = 0; i < options.max; i++) {
items[i].slide(currentPosition);
}
}
window.addEventListener("resize", updateItems);
blocks.left.addEventListener("click", slideLeft);
}
const sld = new Slider({
id: "wrapper",
itemWidth: 250,
max: 20,
})
function Item(opt) {
let item = null;
let curSliderPos = opt.slider.position;
showIn(calculateLeft(curSliderPos));
function calculateLeft(sliderPosition) {
let position = opt.item.index * (opt.item.width + opt.slider.gap);
position += sliderPosition;
if (opt.slider.canFit == 1) position += 0.5 * opt.slider.gap;
return position;
}
function isVisibleIn(pos) {
if (pos >= opt.slider.width) return false;
if (pos + opt.item.width <= 0) return false;
return true;
}
function showIn(pos, force = false) {
if ((force || isVisibleIn(pos)) && !item) {
item = document.createElement('div');
item.className = "item";
item.innerText = opt.item.index;
item.style.position = "absolute";
item.style.display="inline-block";
opt.slider.items.appendChild(item);
}
if (item) {
item.style.left = pos + "px";
}
}
this.update = function(slider) {
curSliderPos = slider.position;
opt.slider.width = slider.width;
opt.slider.gap = slider.gap;
opt.slider.canFit = slider.canFit;
showIn(calculateLeft(opt.slider.position));
}
this.slide = function(newPos) {
const oldElementPos = calculateLeft(curSliderPos);
const newElementPos = calculateLeft(newPos);
if(isVisibleIn(oldElementPos) || isVisibleIn(newElementPos)) {
showIn(oldElementPos, true);
item.style.transition = "left 2s";
showIn(newElementPos, true);
curSliderPos = newPos;
}
}
}
【问题讨论】:
-
我认为你应该简化这一点,并制作一个 main 类的 flexbox 和 justify-content: space-between。只需将物品放在那里,不要使用位置:绝对。现在您所要做的就是为类 main 设置动画,而不是单独为所有项目设置动画。
-
谢谢,但我想尝试更灵活的东西,我可以在需要时添加和删除新块。问题是,我在一步中创建、设置旧位置、设置过渡和设置新位置。 CSS 只是不打扰这个动画。当我在设置新位置之前添加超时时,它开始按我的意愿工作。 codepen.io/TogusaRusso/pen/GYOvom
标签: javascript css