从外部拖拽文件到HTML元素时自定义光标样式不生效的解决方案咨询
从外部拖拽文件到HTML元素时自定义光标样式不生效的解决方案咨询
我最近碰到个棘手的问题:当从文件系统、邮件这类浏览器外部拖拽文件到页面指定元素上时,我设置的自定义CSS光标样式完全不生效。正常hover这个元素时,自定义的SVG光标能正常显示,但拖拽文件悬停在元素上方时,只会显示系统默认的带[+Copy]的指针,完全无视我的CSS配置。
我之前翻到过一个8年前的相关问题,当时高赞回答说这个需求没法实现,但现在浏览器技术更新这么快,我抱着侥幸心理来问问——现在有没有新的解决方案,或者有没有新的标准支持这个场景了?
我甚至尝试了Firefox专属的-moz-drag-over伪类,写了如下CSS:
#div1:-moz-drag-over { cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 300 300'><path fill='%23FFF' stroke='%23E50024' stroke-width='50' d='M150 25 a125 125 0 1 0 2 0z m 2 100 a25 25 0 1 1-2 0z'/></svg>"), auto; }
但看起来这个伪类好像根本不存在,完全不起作用。
补充说明一下:我的问题和其他类似提问的核心区别在于,我是专门要在拖拽外部文件的过程中修改CSS的cursor属性,普通hover或者页面内拖拽的场景我已经能正常实现了,唯独外部文件拖拽悬停时的光标无法自定义。
下面是我写的SSCCE代码,能复现这个问题:
HTML
<h1>File Drop Upload Example</h1> <p>Drag your file(s) into the Drop Zone</p> <div id="div1"> <p>File Drop Zone</p> </div>
CSS
body { } #div1:active { cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 300 300'><path fill='%23FFF' stroke='%23E50024' stroke-width='50' d='M150 25 a125 125 0 1 0 2 0z m 2 100 a25 25 0 1 1-2 0z'/></svg>"), auto; } #div1 { float: left; width: 100px; height:100px; padding: 10px; border: 1px solid black; align: center; vertical-align: middle; background-color: lightblue; cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 300 300'><path fill='%23FFF' stroke='%23E50024' stroke-width='50' d='M150 25 a125 125 0 1 0 2 0z m 2 100 a25 25 0 1 1-2 0z'/></svg>"), auto; } div p { color: red; }
JavaScript
document.addEventListener("DOMContentLoaded", (e) => { const dropZone = document.getElementById("div1") dropZone.addEventListener("dragenter", (e) => { console.log("In enter " + dropZone) e.preventDefault(); dropZone.style.backgroundColor = "#FFF" }) dropZone.addEventListener("dragover", (e) => { console.log("In over " + dropZone) e.preventDefault(); }) dropZone.addEventListener("dragleave", (e) => { console.log("In leave") e.preventDefault(); dropZone.style.backgroundColor = "" }) dropZone.addEventListener("drop", catchFiles) }) function catchFiles(e) { e.preventDefault(); document.getElementById("div1").style.backgroundColor = "" console.log("File(s) dropped"); let fileHolder = new FormData() let fileCount = 0 if (e.dataTransfer.items) { // Use DataTransferItemList interface to access the file(s) [...e.dataTransfer.items].forEach((item, i) => { // If dropped items aren't files, reject them if (item.kind === "file") { const file = item.getAsFile() console.log(`… file[${i}].name = ${file.name}`) fileHolder.append("file"+i, file, file.name) fileCount++ } }); } else { // Use DataTransfer interface to access the file(s) [...e.dataTransfer.files].forEach((file, i) => { console.log(`… file[${i}].name = ${file.name}`); fileHolder.append("file"+i, file, file.name) fileCount++ }); } if (fileCount == 0) { alert("Zero files received") return } alert("got " + fileCount + " files") return const abortControl = new AbortController(); const signal = abortControl.signal; const fetchOpts = {signal:signal, method:'POST', body: fileHolder, cache:"no-cache"}; const response = fetch("https://localhost:7196/data/uploadfiles", fetchOpts).catch( err => { console.log("Upload failed: " + err.message); return }); if (!signal.aborted) { alert("Cancelled") return } }
有没有大佬知道现在有没有办法实现这个需求?如果确实还是做不到的话,也麻烦直接告诉我,我就死了这条心啦😅
内容来源于stack exchange
相关产品推荐
相关产品推荐

