使用JSX实现Carousel轮播组件的方法(前端组件化)(5)

第一步是先把当前图片往右边移动一步,之前我们说的 index * -100% 让任何一张在 index 位置的图片移动到当前位置的公式,那么要再往右边移动多一个位置,那就是 (index + 1) * -100% 即可

第二步就是让下一张图移动到当前显示的位置,这个就是直接用 index * -100% 咯

最后我们还需要更新一次我们记录, currentIndex = nextIndex,这样就大功告成了!

接下来我们把上面的逻辑翻译成 JavaScript:

class Carousel extends Component { // 构造函数 // 创建 DOM 节点 constructor() { super(); this.attributes = Object.create(null); } setAttribute(name, value) { this.attributes[name] = value; } render() { this.root = document.createElement('div'); this.root.classList.add('carousel'); for (let picture of this.attributes.src) { let child = document.createElement('div'); child.style.backgroundImage = `url('${picture}')`; this.root.appendChild(child); } // 当前图片的 index let currentIndex = 0; setInterval(() => { let children = this.root.children; // 下一张图片的 index let nextIndex = (currentIndex + 1) % children.length; // 当前图片的节点 let current = children[currentIndex]; // 下一张图片的节点 let next = children[nextIndex]; // 禁用图片的动效 next.style.transition = 'none'; // 移动下一张图片到正确的位置 next.style.transform = `translateX(${-100 * (nextIndex - 1)}%)`; // 执行轮播效果,延迟了一帧的时间 16 毫秒 setTimeout(() => { // 启用 CSS 中的动效 next.style.transition = ''; // 先移动当前图片离开当前位置 current.style.transform = `translateX(${-100 * (currentIndex + 1)}%)`; // 移动下一张图片到当前显示的位置 next.style.transform = `translateX(${-100 * nextIndex}%)`; // 最后更新当前位置的 index currentIndex = nextIndex; }, 16); }, 3000); return this.root; } mountTo(parent) { parent.appendChild(this.render()); } }

如果我们先去掉 overflow: hidden 的话,我们就可以很清晰的看到所有图片移动的轨迹了:

使用JSX实现Carousel轮播组件的方法(前端组件化)

实现拖拽轮播

一般来说我们的轮播组件除了这种自动轮播的功能之外,还有可以使用我们的鼠标进行拖动来轮播。所以接下来我们一起来实现这个手动轮播功能。

因为自动轮播和手动轮播是有一定的冲突的,所以我们需要把我们前面实现的自动轮播的代码给注释掉。然后我们就可以使用这个轮播组件下的 children (子元素),也就是所有图片的元素,来实现我们的手动拖拽轮播功能。

那么拖拽的功能主要就是涉及我们的图片被拖动,所以我们需要给图片加入鼠标的监听事件。如果我们根据操作步骤来想的话,就可以整理出这么一套逻辑:

我们肯定是需要先把鼠标移动到图片之上,然后点击图片。所以我们第一个需要监听的事件必然就是 mousedown 鼠标按下事件。点击了鼠标之后,那么我们就会开始移动我们的鼠标,让我们的图片跟随我们鼠标移动的方向去走。这个时候我们就要监听 mousemove 鼠标移动事件。当我们把图片拖动到我们想要的位置之后,我们就会松开我们鼠标的按键,这个时候也是我们要计算这个图片是否可以轮播的时候,这个就需要我们监听 mouseup 鼠标松开事件。

this.root.addEventListener('mousedown', event => { console.log('mousedown'); }); this.root.addEventListener('mousemove', event => { console.log('mousemove'); }); this.root.addEventListener('mouseup', event => { console.log('mouseup'); });

使用JSX实现Carousel轮播组件的方法(前端组件化)

执行一下以上代码后,我们就会在 console 中看到,当我们鼠标放到图片上并且移动时,我们会不断的触发 mousemove。但是我们想要的效果是,当我们鼠标按住时移动才会触发 mousemove,我们鼠标单纯在图片上移动是不应该触发事件的。

所以我们需要把 mousemove 和 mouseup 两个事件,放在 mousedown 事件的回调函数当中,这样才能正确的在鼠标按住的时候监听移动和松开两个动作。这里还需要考虑,当我们 mouseup 的时候,我们需要把 mousemove 和 mouseup 两个监听事件给停掉,所以我们需要用函数把它们单独的存起来。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsdgsj.html