伪类 `:checked` 的视图过渡不起作用
我有一个 视图过渡:
checkbox.oninput = () => {
document.startViewTransition(() => {
checkbox.classList.toggle('checked');
});
};
.container {
display: grid;
grid-template: 100px 100px / 100px 100px;
}
label {
view-transition-name: foo;
}
:has(.checked) {
grid-column: 2;
grid-row: 2;
}
<div class="container">
<label>
<input type="checkbox" id="checkbox" oninput="">
Click here
</label>
</div>
但我不喜欢这段代码。我想在CSS选择器中使用 :checked 伪类,而不是使用冗余的 .checked 类并保持同步。那样会更地道。当我用 :checked 代替 .checked 时,视图过渡就不会发生。这个问题该如何修复?
解决方案
问题在于,在你调用 document.startViewTransition() 的时候,:checked 规则已经被应用。你需要在即将触发 input 事件之前就挂上一个事件监听。虽然存在一个 beforeinput 事件,但它只适用于文本可编辑输入中的键盘输入,而不适用于复选框。
因此,换一种仍然有些丑陋的方法:在输入事件中,同步地抵消输入的 checked 值,这样 :checked 就能与之前的状态相匹配。然后启动过渡,在其更新回调中,把 checked 属性重新设回它本来要变成的值。现在过渡已经掌握了它所需的一切信息:
checkbox.oninput = e => {
if (document.startViewTransition) {
checkbox.checked = !checkbox.checked;
document.startViewTransition(() => {
checkbox.checked = !checkbox.checked;
});
}
}
.container {
display: grid;
grid-template: 100px 100px / 100px 100px;
label {
view-transition-name: foo;
&:has(:checked) {
grid-column: 2;
grid-row: 2;
}
}
}
<div class="container">
<label>
<input type="checkbox" id="checkbox" oninput="">
Click here
</label>
</div>
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。