连接两个切换按钮以相互切换
Connect two toggle buttons to switch each other
我有两个拨动开关按钮,其中按钮 1 被默认选中。单击第一个按钮时,第二个按钮应打开,第一个按钮应关闭,单击第二个按钮后,第一个按钮应打开,第二个按钮应关闭。一次只能打开一个按钮。
我尝试了不同的方法,但没有一个是完美的。
HTML代码:
<div class="col-md-1" style="margin-top:2em; margin-left:-2em">
<span class="switch">
<input type="checkbox" class="switch" id="switch-id1" @click="" checked>
</span>
</div>
<div class="col-md-1" style="margin-top:2em; margin-left:-2em">
<span class="switch">
<input type="checkbox" class="switch" id="switch-id2" @click="" unchecked>
</span>
</div>
CSS :
$switch-height: calc(#{$input-height} * .8) !default;
$switch-height-sm: calc(#{$input-height-sm} * .8) !default;
$switch-height-lg: calc(#{$input-height-lg} * .8) !default;
$switch-border-radius: $switch-height !default;
$switch-bg: $custom-control-indicator-bg !default;
$switch-checked-bg: map-get($theme-colors, 'primary') !default;
$switch-unchecked-bg: map-get($theme-colors, 'primary') !default;
$switch-disabled-bg: $custom-control-indicator-disabled-bg !default;
$switch-disabled-color: $custom-control-description-disabled-color !default;
$switch-thumb-bg: $white !default;
$switch-thumb-border-radius: 50% !default;
$switch-thumb-padding: 2px !default;
$switch-focus-box-shadow: 0 0 0 $input-btn-focus-width rgba(map-get($theme-colors, 'primary'), .25);
$switch-transition: .2s all !default;
.switch {
font-size: $font-size-base;
position: relative;
input {
position: absolute;
height: 1px;
width: 1px;
background: none;
border: 0;
clip: rect(0 0 0 0);
clip-path: inset(50%);
overflow: hidden;
padding: 0;
+ label {
position: relative;
min-width: calc(#{$switch-height} * 2);
border-radius: $switch-border-radius;
height: $switch-height;
line-height: $switch-height;
display: inline-block;
cursor: pointer;
outline: none;
user-select: none;
vertical-align: middle;
text-indent: calc(calc(#{$switch-height} * 2) + 3.5rem);
}
+ label::before,
+ label::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: calc(#{$switch-height} * 2);
bottom: 0;
display: block;
}
+ label::before {
right: 0;
background-color: $switch-bg;
border-radius: $switch-border-radius;
transition: $switch-transition;
}
+ label::after {
top: $switch-thumb-padding;
left: $switch-thumb-padding;
width: calc(#{$switch-height} - calc(#{$switch-thumb-padding} * 2));
height: calc(#{$switch-height} - calc(#{$switch-thumb-padding} * 2));
border-radius: $switch-thumb-border-radius;
background-color: $switch-thumb-bg;
transition: $switch-transition;
}
&:checked + label::before {
background-color: $switch-checked-bg;
}
&:checked + label::after {
margin-left: $switch-height;
}
&:focus + label::before {
outline: none;
box-shadow: $switch-focus-box-shadow;
}
&:disabled + label {
color: $switch-disabled-color;
cursor: not-allowed;
}
&:disabled + label::before {
background-color: $switch-disabled-bg;
}
}
// Small variation
&.switch-sm {
font-size: $font-size-sm;
input {
+ label {
min-width: calc(#{$switch-height-sm} * 2);
height: $switch-height-sm;
line-height: $switch-height-sm;
text-indent: calc(calc(#{$switch-height-sm} * 2) + .5rem);
}
+ label::before {
width: calc(#{$switch-height-sm} * 2);
}
+ label::after {
width: calc(#{$switch-height-sm} - calc(#{$switch-thumb-padding} * 2));
height: calc(#{$switch-height-sm} - calc(#{$switch-thumb-padding} * 2));
}
&:checked + label::after {
margin-left: $switch-height-sm;
}
}
}
// Large variation
&.switch-lg {
font-size: $font-size-lg;
input {
+ label {
min-width: calc(#{$switch-height-lg} * 2);
height: $switch-height-lg;
line-height: $switch-height-lg;
text-indent: calc(calc(#{$switch-height-lg} * 2) + .5rem);
}
+ label::before {
width: calc(#{$switch-height-lg} * 2);
}
+ label::after {
width: calc(#{$switch-height-lg} - calc(#{$switch-thumb-padding} * 2));
height: calc(#{$switch-height-lg} - calc(#{$switch-thumb-padding} * 2));
}
&:checked + label::after {
margin-left: $switch-height-lg;
}
}
}
+ .switch {
margin-left: 1rem;
}
}
你可以用 vue 做到这一点:
const app = Vue.createApp({
data: () => ({
status: true
}),
methods: {
clicked(val) {
this.status === val ? this.status = !val : this.status = val
// some other stuff you need on click
}
}
})
app.mount('#demo')
<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<div id="demo">
<div class="col-md-1" style="margin-top:2em; margin-left:2em">
<span class="switch">
<input type="checkbox" class="switch" id="switch-id1" @click="clicked(false)" :checked="status">
</span>
</div>
<div class="col-md-1" style="margin-top:2em; margin-left:2em">
<span class="switch">
<input type="checkbox" class="switch" id="switch-id2" @click="clicked(true)" :checked="!status">
</span>
</div>
</div>
我有两个拨动开关按钮,其中按钮 1 被默认选中。单击第一个按钮时,第二个按钮应打开,第一个按钮应关闭,单击第二个按钮后,第一个按钮应打开,第二个按钮应关闭。一次只能打开一个按钮。 我尝试了不同的方法,但没有一个是完美的。
HTML代码:
<div class="col-md-1" style="margin-top:2em; margin-left:-2em">
<span class="switch">
<input type="checkbox" class="switch" id="switch-id1" @click="" checked>
</span>
</div>
<div class="col-md-1" style="margin-top:2em; margin-left:-2em">
<span class="switch">
<input type="checkbox" class="switch" id="switch-id2" @click="" unchecked>
</span>
</div>
CSS :
$switch-height: calc(#{$input-height} * .8) !default;
$switch-height-sm: calc(#{$input-height-sm} * .8) !default;
$switch-height-lg: calc(#{$input-height-lg} * .8) !default;
$switch-border-radius: $switch-height !default;
$switch-bg: $custom-control-indicator-bg !default;
$switch-checked-bg: map-get($theme-colors, 'primary') !default;
$switch-unchecked-bg: map-get($theme-colors, 'primary') !default;
$switch-disabled-bg: $custom-control-indicator-disabled-bg !default;
$switch-disabled-color: $custom-control-description-disabled-color !default;
$switch-thumb-bg: $white !default;
$switch-thumb-border-radius: 50% !default;
$switch-thumb-padding: 2px !default;
$switch-focus-box-shadow: 0 0 0 $input-btn-focus-width rgba(map-get($theme-colors, 'primary'), .25);
$switch-transition: .2s all !default;
.switch {
font-size: $font-size-base;
position: relative;
input {
position: absolute;
height: 1px;
width: 1px;
background: none;
border: 0;
clip: rect(0 0 0 0);
clip-path: inset(50%);
overflow: hidden;
padding: 0;
+ label {
position: relative;
min-width: calc(#{$switch-height} * 2);
border-radius: $switch-border-radius;
height: $switch-height;
line-height: $switch-height;
display: inline-block;
cursor: pointer;
outline: none;
user-select: none;
vertical-align: middle;
text-indent: calc(calc(#{$switch-height} * 2) + 3.5rem);
}
+ label::before,
+ label::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: calc(#{$switch-height} * 2);
bottom: 0;
display: block;
}
+ label::before {
right: 0;
background-color: $switch-bg;
border-radius: $switch-border-radius;
transition: $switch-transition;
}
+ label::after {
top: $switch-thumb-padding;
left: $switch-thumb-padding;
width: calc(#{$switch-height} - calc(#{$switch-thumb-padding} * 2));
height: calc(#{$switch-height} - calc(#{$switch-thumb-padding} * 2));
border-radius: $switch-thumb-border-radius;
background-color: $switch-thumb-bg;
transition: $switch-transition;
}
&:checked + label::before {
background-color: $switch-checked-bg;
}
&:checked + label::after {
margin-left: $switch-height;
}
&:focus + label::before {
outline: none;
box-shadow: $switch-focus-box-shadow;
}
&:disabled + label {
color: $switch-disabled-color;
cursor: not-allowed;
}
&:disabled + label::before {
background-color: $switch-disabled-bg;
}
}
// Small variation
&.switch-sm {
font-size: $font-size-sm;
input {
+ label {
min-width: calc(#{$switch-height-sm} * 2);
height: $switch-height-sm;
line-height: $switch-height-sm;
text-indent: calc(calc(#{$switch-height-sm} * 2) + .5rem);
}
+ label::before {
width: calc(#{$switch-height-sm} * 2);
}
+ label::after {
width: calc(#{$switch-height-sm} - calc(#{$switch-thumb-padding} * 2));
height: calc(#{$switch-height-sm} - calc(#{$switch-thumb-padding} * 2));
}
&:checked + label::after {
margin-left: $switch-height-sm;
}
}
}
// Large variation
&.switch-lg {
font-size: $font-size-lg;
input {
+ label {
min-width: calc(#{$switch-height-lg} * 2);
height: $switch-height-lg;
line-height: $switch-height-lg;
text-indent: calc(calc(#{$switch-height-lg} * 2) + .5rem);
}
+ label::before {
width: calc(#{$switch-height-lg} * 2);
}
+ label::after {
width: calc(#{$switch-height-lg} - calc(#{$switch-thumb-padding} * 2));
height: calc(#{$switch-height-lg} - calc(#{$switch-thumb-padding} * 2));
}
&:checked + label::after {
margin-left: $switch-height-lg;
}
}
}
+ .switch {
margin-left: 1rem;
}
}
你可以用 vue 做到这一点:
const app = Vue.createApp({
data: () => ({
status: true
}),
methods: {
clicked(val) {
this.status === val ? this.status = !val : this.status = val
// some other stuff you need on click
}
}
})
app.mount('#demo')
<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<div id="demo">
<div class="col-md-1" style="margin-top:2em; margin-left:2em">
<span class="switch">
<input type="checkbox" class="switch" id="switch-id1" @click="clicked(false)" :checked="status">
</span>
</div>
<div class="col-md-1" style="margin-top:2em; margin-left:2em">
<span class="switch">
<input type="checkbox" class="switch" id="switch-id2" @click="clicked(true)" :checked="!status">
</span>
</div>
</div>