如果您在 Firefox 桌面版 91.0.2(當時的最新版本)Windows 10 64 位(可能也包括其他版本)中打開 測驗 URL,并打開 F12 選單,然后單擊回應式設計模式按鈕(ctrl shift m...又稱移動視圖按鈕)并按住圖片左側的左鍵,您將看到數字上升到約 25 - 然后停止并重置為零,并觸發 onCancel。我的理論是,這就是直到正常觸發背景關系選單所需的時間。
如果您在常規桌面視圖或 Chrome 瀏覽器的常規桌面視圖中進行嘗試,那么它將如期作業--它將一直數到 100(甚至更多),直到您松手,然后 onFinish 被觸發。
完整的代碼在這里。代碼沙盒
index.html
<! DOCTYPE html>
<html lang="en"/span>>
<head>/span>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
< meta name="theme-color" content="#000000" />
<!--
manifest.json提供了元資料,當你的網路應用被添加到
主螢屏時使用的元資料。見https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel=" manifest" href="%PUBLIC_URL%/manifest. json" />。
< link rel="快捷圖示" href="%PUBLIC_URL%/favicon. ico" />。
<!--
注意上面的標簽中使用了%PUBLIC_URL%。
在構建程序中,它將被替換為`public`檔案夾的URL。
只有`public`檔案夾內的檔案可以從HTML中參考。
與"/favicon.ico "或 "favicon.ico "不同,"%PUBLIC_URL%/favicon.ico "將
在客戶端路由和非根公共URL下都能正常作業。
了解如何通過運行`npm run build`來配置非根公共URL。
-->
<title>React App</title>/span>
<script>
window.addEventListener(
"contextmenu",
function (e) {
//在這里做一些事情....../span>
e.preventDefault && e.preventDefault() 。
e.stopPropagation && e.stopPropagation() 。
e.cancelBubble = true;
return false。
},
falseconst noContext = document.getElementById("ItemImage") 。
noContext.addEventListener("contextmenu", (e) => /span> {
e.preventDefault && e.preventDefault()。
e.stopPropagation && e.stopPropagation() 。
e.cancelBubble = true;
return false;
});
function absorbEvent_(event) {
var e = event;
e.preventDefault && e.preventDefault() 。
e.stopPropagation && e.stopPropagation() 。
e.cancelBubble = true;
return false;
}
function preventLongPressMenu(node) {
node.ontouchstart = absorbEvent_;
node.ontouchmove = absorbEvent_;
node.ontouchend = absorbEvent_;
node.ontouchcancel = absorbEvent_;
}
function init() {
preventLongPressMenu(document.getElementById("ItemImage") )。
}
</script>>
<style>
/* https://www.arungudelli.com/tutorial/css/disable-text-selection-in-html-using-user-select-css-property/ */
.disable-select {
user-select: none; /* 由Chrome和Opera支持 */ {
-webkit-user-select: none; /* Safari */ 支持
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
}
</style>
</head>
<body>
<noscript>
你需要啟用JavaScript來運行這個應用程式。
</noscript>你需要啟用JavaScript來運行這個應用程式。
<div id="root"/span>> </div>>
<!
這個HTML檔案是一個模板。
如果你在瀏覽器中直接打開它,你會看到一個空頁面。
你可以在這個檔案中添加網路字體、元標簽或分析。
構建步驟將把捆綁的腳本放到<body>標簽中。
要開始開發,運行`npm start`或`yarn start`。
要創建一個生產捆綁包,使用`npm run build`或`yarn build`。
-->
</body>
</html>
App.js
import React, { useCallback, useRef, useState } from "react"。
import "./styles.css"。
import { useLongPress } from "use-long-press" ;
import Item from "./Item" ;
function App(/span>) {
const [progress, setProgress] = useState(0)。
const progressTimer = useRef()。
function handleTime() {
setProgress((prevState) => (prevState = 5) )。
}
const callback = useCallback((event) => //span> {
event.preventDefault && event.preventDefault()。
event.stopPropagation && event.stopPropagation()。
event.cancelBubble = true;
console.log("long pressed!")。
}, []);
const longPressEvent = useLongPress(callback, {
onStart: (event) => {
console.log("On Start"/span>)。
event.preventDefault && event.preventDefault()。
event.stopPropagation && event.stopPropagation()。
event.cancelBubble = true;
progressTimer.current = setInterval(handleTime, 100)。
},
onFinish: (event) => {
console.log("On finish"/span>)。
event.preventDefault && event.preventDefault()。
event.stopPropagation && event.stopPropagation()。
event.cancelBubble = true;
setProgress(0)。
clearInterval(progressTimer.current)。
},
onCancel: (event) => {
console.log("On cancel") 。
event.preventDefault && event.preventDefault()。
event.stopPropagation && event.stopPropagation()。
event.cancelBubble = true;
setProgress(0)。
clearInterval(progressTimer.current)。
},
threshold: 2000,
captureEvent: true,
cancelOnMovement: false,
detect: "both"。
});
let content = (
<div className="content-center">/span>
{進度}
<Item
events={longPressEvent}。
name="name"/span>
image="file.png"/span>
progress={progress}
/>
</div>/span>
);
return <React. Fragment>{content}</React.Fragment> 。
}
export default App;
Item.js
import React from "react";
import "./Item.css"。
import VerticalProgress from "./VerticalProgress"/span>;
import faker from "faker";
export default function Item(props) {
return (
<div className="flex justify-center w-full disable-select">
<div
className="float-left absolute z-50 w-full disable-select"
style={{ height: 500 }}。
{...props.events}}
>
<div></div>
</div>/span>
<VerticalProgress className="z-0" progress={props. progress} />
<img
className="z-0 disable-select"
src={faker.image.image()}
alt={props.name}>
height="200"
id="ItemImage"。
/>
</div>/span>
);
}
我的問題是:我如何防止在 Firefox 桌面移動測驗模式中提前呼叫 onCancel?如果它發生在那里,那么它肯定會發生在其他瀏覽器中,如 Safari 或實際的 Firefox 移動版。即使不是這樣,這也是一個非常意想不到的副作用,并且使移動測驗變得困難。
第二個問題:是什么導致了
IndexSizeError。Selection.getRangeAt: 0超出了范圍
錯誤?
uj5u.com熱心網友回復:
這是在模擬器上的一個錯誤。在手機上,它可以正常作業。
TL;DR
這個問題似乎與觸摸模擬有關(它發生在任何螢屏尺寸/設備上)。當啟用時,發射的事件從onMouseDown/onMouseStart變為onTouchStart/onTouchEnd,它們的行為也發生了變化。默認情況下,在幾分之一秒之后,Firefox 將打開背景關系選單(您可以在 "打開沙盒 "按鈕上測驗默認行為),這將結束觸摸并啟動onTouchEnd(以及一個onMouseMove)。
很奇怪。無論我做了什么嘗試,都無法阻止觸摸結束(但會阻止選單顯示)。
盡管如此,我在移動設備上測驗了您的代碼(Android 上的 Firefox 91.4.0 - 3 臺設備 - 2 個供應商),一切都正常運行。這是我的代碼
。根據我的觀察,在移動設備上沒有背景關系選單,除了少數元素,如<img>或<a>,它們有自己的選單(復制鏈接),我一直無法洗掉。但在任何情況下(即使出現彈出式選單),useLongPress都能如期作業。
注意事項
不要將React等框架和原始DOM函式(如addEventListener())混合在一起。你在index.html中添加的代碼不會像你期望的那樣作業。做這樣的事情:
const __absorb = useCallback((event) => /span> {
event.preventDefault && event.preventDefault()。
...
return false。
}, []);
<a onContextMenu={__absorb}>/span>
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/320695.html
標籤:
下一篇:絕對位置的跨頁自動被推離網頁
