最近公司项目有一个需求就是开发一个组件,当有卡片数量占据空间超过容器时,则需要展现左右两个箭头来给用户点击,来滑动出更多的卡片。问题是卡片中间在后端客户会上传宽度不同的logo,根据figma上面的设计来说,并没有将每个logo居中于一个宽度相当的正方形元素中,所以在实现无限循环上有点困难。
提醒:这种像carousel的卡片不是无障碍友好,不到万不得己,不建议大家做这种交互。
<div class="cards-wrapper">
<div class="cards js-scroll-container">
<div class="card js-card"></div>
<div class="card js-card"></div>
<div class="card js-card"></div>
<div class="card js-card"></div>
<div class="card js-card"></div>
<div class="card js-card"></div>
</div>
<button type="button" class="js-button-prev"></button>
<button type="button" class="js-button-next"></button>
</div>
那么,刚开始在php组件中,可以将prev, next两个按钮隐藏,只有当有多余卡片无法容纳当前滑动容器时,才将两个按钮展现给用户,这里就需要用到JS去计算卡片的整体宽度。
// Get all the cards.
const cards = elBlock.querySelectorAll( '.js-card' );
// Get the scrollable container width.
const scrollContainerWidth = elScrollContainer.clientWidth;
// Get the flex gap of scrollable container.
const flexGap = Number(
window
.getComputedStyle( elScrollContainer )
.getPropertyValue( 'gap' )
.replace( 'px', '' )
);
const totalCardsWidth = /* 通过reduce() 获得全部卡片的宽度 */
// If the logos width plus the gaps is bigger than the scroll container width,
// Show the prev and next buttons with the "scrollable" class.
if (
totalCardsWidth + ( elLogoContainers.length - 1 ) * flexGap >
scrollContainerWidth
) {
elBlock.classList.add( 'scrollable' );
}