我正在尝试制作一个嵌入文本的切换开关。每月和每年定价之间的切换。
这是模拟的图片:
该网站是用 React 构建的。我尝试使用 React-Toggle Pkg
我可以用这个包完美地获得样式,但我找不到在切换中获取文本的好方法。
<Toggle
name="t-6"
radius="50px"
radiusBackground="50px"
knobRadius="50px"
width="400px"
height="55px"
knobWidth="200px"
knobHeight="40px"
onToggle={(e) => console.log("onToggle", e.target)}
/>
也许它没有实现,查看文档它看起来不像。
不要绝望,使用一点 DOM(更少的行然后包括组件)和 CSS,您可以通过几个无线电输入和随附的标签来实现这一点。
document.querySelectorAll('input[name="pricing"]').forEach(input =>
input.addEventListener("change", function() {
document.getElementById('out').innerHTML = `Value: ${this.value}`
})
)
document.getElementById('out').innerHTML = `Value: monthly`
.pricing-toggle {
background-color: #3FAED7;
padding: 14px 5px;
border-radius: 30px;
display: inline-block
}
.pricing-toggle [name="pricing"] {
display: none
}
.pricing-toggle input[type="radio"]+label {
background-color: #3FAED7;
color: white;
padding: 10px 20px;
border-radius: 30px;
cursor: pointer;
user-select: none;
}
.pricing-toggle input[type="radio"]:checked+label {
background-color: white;
color: #00008B;
}
<div class="pricing-toggle">
<input type="radio" id="pricing-toggle-monthly" name="pricing" value="monthly" checked>
<label class="radio-button" for="pricing-toggle-monthly"> Monthly</label>
<input type="radio" id="pricing-toggle-annually" name="pricing" value="annually">
<label class="radio-button" for="pricing-toggle-annually"> Annually</label>
</div>
<div id="out"><div>
示例中不需要 js,使用 scss,CSS 可以小得多
我用React + tailwindcss做了一个:https://codesandbox.io/p/devbox/vibrant-http-rnd7m9,随意调整大小和颜色。我复制了下面的组件代码:
import classNames from "classnames";
import { useState } from "react";
interface SwitchProps {
checked: boolean;
uncheckedLabel: string;
checkedLabel: string;
handleToggle: (state: boolean) => void;
}
export const Switch = ({
checked,
uncheckedLabel,
checkedLabel,
handleToggle,
}: SwitchProps) => {
const [checkedState, setCheckedState] = useState(checked);
const handleClick = (state: boolean) => {
handleToggle(state);
setCheckedState(state);
};
return (
<div className="flex-none items-center justify-center">
<label className="relative inline-flex cursor-pointer items-center">
<input
type="checkbox"
className="peer sr-only"
checked={checkedState}
onChange={(e) => {
const currentState = e.currentTarget.checked;
handleClick(currentState);
}}
/>
<span
data-unchecked-label={uncheckedLabel}
data-checked-label={checkedLabel}
className="h-7 w-28 rounded-full border bg-slate-500 after:absolute after:left-0.5 after:top-[2px] after:h-6 after:w-14 after:rounded-full after:border after:border-gray-700 after:bg-white after:text-center after:transition after:content-[attr(data-unchecked-label)] peer-checked:after:translate-x-[52px] peer-checked:after:border-gray-700 peer-checked:after:content-[attr(data-checked-label)]"
>
<label
className={classNames(
"mt-0.5 block cursor-pointer select-none text-white",
checkedState ? "ml-3 text-left" : "mr-3 text-right"
)}
onClick={() => handleClick(!checkedState)}
>
{checkedState ? uncheckedLabel : checkedLabel}
</label>
</span>
</label>
</div>
);
};