這是與此處其他人類似的問題,但我還沒有找到與我的場景正確匹配的問題或答案(尚未)。
我有一個網站,它:hover在幾個地方使用 CSS 來顯示一個互動式疊加層,其中包含可點擊的元素(按鈕等)。這在桌面上效果很好:用戶懸停以查看更多資訊,然后可以選擇是否單擊按鈕。在移動設備上,用戶需要單擊元素來觸發懸停偽類并顯示覆寫。這實際上是我想要的行為,但有一個問題,如果在用戶單擊的正下方有一個按鈕,它會立即觸發。
我想要的效果是,對于移動/觸摸,用戶首先必須單擊元素以顯示覆寫,然后他們可以單擊元素內的按鈕等。桌面應該像現在一樣繼續使用懸停。
我不認為這種行為可以單獨使用 CSS 來實作,盡管這當然是理想的......
此處的示例代碼:https ://stackblitz.com/edit/react-epunjm?file=src/App.js
// App.js
import React from "react";
import "./style.css";
export default function App() {
return (
<div className="container">
<div className="content">
Hello StackBlitz!
</div>
<div className="overlay">
<span>This is overlay</span>
<button onClick={() => alert("clicked!")}>BUTTON</button>
</div>
</div>
);
}
// style.css
div {
font-family: Lato;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
gap: 10px;
}
div.container {
position: relative;
width: 200px;
height: 100px;
}
div.content {
background: orange;
}
div.content, div.overlay {
position: absolute;
font-weight: bold;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
div.overlay {
display: none;
color: white;
background: rgba(0,0,0,0.7);
}
div.container:hover div.overlay {
display: inherit;
}
編輯:
非常感謝 Onkar Ruikar 的回答。我從他的想法中獲得靈感,但最終使用了焦點狀態(使用選項卡索引),并禁用了覆寫內容的指標事件,直到覆寫有焦點。這需要使用媒體查詢檢測設備何時有觸摸,并且可能不完全可靠,但應該可以滿足我的需求。
此處的作業示例:https ://stackblitz.com/edit/react-dupeks
uj5u.com熱心網友回復:
單擊一次,在按鈕位置,將觸發以下事件:
content touchStart
container touchStart //here CSS rule brings overlay forth
content touchEnd
container touchEnd
container mouseEnter
overlay mouseEnter
button mouseEnter
button clicked // the button gets clicked in same tap! ??
overlay clicked
container clicked
由于所有這些事情都發生在單點觸控上,所以我們在 CSS 中無能為力。
這是使用 javascript 的一種解決方案:codeandbox demo
let show = () => overlay.style.display = 'inherit';
let hide = () => overlay.style.display = 'none';
// for pointer devices ----------------------
container.addEventListener('mouseenter', () => show());
container.addEventListener('mouseleave', () => hide());
// for touch devices -----------------------
content.addEventListener('touchstart', (e) => {
show()
// break the event chain that leads to click
e.stopPropagation();
e.preventDefault();
});
// there is no reliable mouseleave event in touch devices
// so need to provide close button
hideMe.addEventListener('click', () => hide());
// mimicking mouseleave, not ideal though
(function() {
/* this doesn't work properly
overlay.addEventListener('mouseleave', (e) => {
overlay.style.display = 'none';
})*/
container.addEventListener('click', (e) => e.stopPropagation());
document.addEventListener('click', () => hide());
})();
div {
font-family: Lato;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
gap: 10px;
}
div.container {
position: relative;
width: 200px;
height: 100px;
}
div.content {
background: orange;
}
div.content,
div.overlay {
position: absolute;
font-weight: bold;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
div.overlay {
display: none;
color: white;
background: rgba(0, 0, 0, 0.7);
}
button {
user-select: none;
}
#hideMe {
position: absolute;
top: .5rem;
right: .5rem;
cursor: pointer;
}
<div id="root">
<div id="container" class="container">
<div id="content" class="content">Hello StackBlitz!</div>
<div id="overlay" class="overlay">
<span>This is overlay</span>
<button onclick='alert("clicked!")'>
BUTTON
</button>
<div id="hideMe">X</div>
</div>
</div>
</div>
舊解決方案
顯示代碼片段
div {
font-family: Lato;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
gap: 10px;
}
div.container {
position: relative;
width: 200px;
height: 100px;
}
div.content {
background: orange;
}
div.content,
div.overlay {
position: absolute;
font-weight: bold;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
div.overlay {
display: none;
color: white;
background: rgba(0, 0, 0, 0.7);
}
div.container:hover div.overlay {
display: inherit;
}
button {
user-select: none;
}
<body onload="flag=true">
<div id="root">
<div class="container" ontouchend="flag=false">
<div class="content">Hello StackBlitz!</div>
<div class="overlay">
<span>This is overlay</span>
<button
ontouchend="flag=true; event.stopPropagation()"
onclick='if(flag) alert("clicked!")'>
BUTTON
</button>
</div>
</div>
</div>
</body>
當我們第一次點擊按鈕位置時,觸摸事件會在容器上觸發,但不會在按鈕上觸發。它僅在我們實際點擊按鈕時觸發。所以我們相應地設定了標志。由于桌面瀏覽器不會觸發觸摸事件,這不會影響桌面瀏覽器中的原始行為。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/433099.html
