需求
- 单选组按钮
- 不确定待选项长度
- 左右滑切换待选项
- 根据待选项长度自动隐藏/显示切换按钮
效果如下:
屏幕录制的软件有点问题,鼠标的pointer可能不准,应该不影响展示。
代码
导入所需的库
import React, { useState, useEffect } from 'react'
import {
Radio,
} from 'antd'
import 'antd/dist/antd.css';
import './style.css';
组件结构
<div className="container">
{/* 控制滑动的左右按钮 */}
<button
className="left-arrow"
id='left'
onClick={handleMove}
>
<</button>
{
(subWidth > fatherwidth) && (
<button
className="right-arrow"
id='right'
onClick={handleMove}
>
>
</button>
)
}
<div className="sub-container" style={{ width: subWidth }}>
{/* 单选按钮组 */}
<Radio.Group
name="slidebtn"
optionType="button"
buttonStyle="solid"
defaultValue={slideData[0].id}
onChange={key => console.log("选中的按钮的key为:", key)}
>
{
slideData.map(item =>
<Radio
value={item.id}
className="radiobtn"
style={{ marginRight: '20px' }}
>
{item.text}
</Radio>
)
}
</Radio.Group>
</div>
</div>
关键样式
// style.css
.container {
width: 500px;
height: 32px;
margin: 0 auto;
border: 1px solid #333333;
overflow: hidden;
position: relative;
/* background-color: #bfc; */
}
.sub-container {
position: relative;
left: 0;
width: 1000px;
transition: left 2s;
}
.right-arrow, .left-arrow {
display: block;
height: 100%;
line-height: 28px;
width: 24px;
position: absolute;
top: 0;
text-align: center;
background-color: #fff;
z-index: 999;
border: 1px solid #efefef;
}
.left-arrow {
display: none;
left: 0;
}
.right-arrow {
right: 0;
}
常量/状态
// 父容器的固定宽度
const fatherwidth = 500
// 子容器
const subcon = document.querySelector(".sub-container")
// 子容器的宽度根据内容而定
const [subWidth, setSubWidth] = useState(0)
// 要渲染的单选组待选项
const { data } = props
const [slideData, setSlideData] = useState(data)
Notes: 本文设定待选组均为中文汉字,根据
font-size设定子容器宽度,如果button有padding或者margin,可以加上对应的值。
回调函数/方法
// 计算子容器的宽度
const computeWidth = () => {
let width = 0
const btns = document.querySelectorAll(".radiobtn")
btns.forEach(btn => {
width += btn.offsetWidth
})
return width
}
// 处理左右移动
const handleMove = (e) => {
console.log(subcon)
// 容器的偏移量
const offsetLeft = Number(subcon?.style?.left.slice(0, -2))
// 左右箭头
const leftArrow = document.querySelector('#left')
const rightArrow = document.querySelector('#right')
if (e.target.id === 'left') {
// 点击左箭头,向右移动,控制左箭头的隐藏和右箭头的显示
subcon.style.left = (offsetLeft + fatherwidth) + 'px'
if (Number(subcon.style.left.slice(0, -2)) >= 0) {
leftArrow.style.display = 'none'
if (subWidth > fatherwidth) {
rightArrow.style.display = 'block'
}
} else {
rightArrow.style.display = 'block'
}
} else {
// 控制右箭头的隐藏和左箭头的显示
subcon.style.left = (offsetLeft - fatherwidth) + 'px'
if (offsetLeft - fatherwidth <= 0) {
leftArrow.style.display = 'block'
}
if ( offsetLeft + 2 * fatherwidth >= subWidth) {
rightArrow.style.display = 'none'
}
}
}
觉得有用可以点赞收藏哦~
tips: 本人代码更偏向hooks~
完整代码在github:github.com/gmx-white/s…