不能作为文件拖拽目标,必须用等容器并同时监听dragenter、dragover(均需preventdefault())和drop事件,从e.datatransfer.files读取文件;容器须有尺寸且无pointer-events:none。

<textarea></textarea> 本身不能作为文件拖拽上传的目标区域,它不是合法的 drop 目标,也不参与 HTML5 拖放流程。所以“在 <textarea></textarea> 上阻止默认事件来接收大文件”这个思路从根源上就不可行。
真正能接收拖拽文件的是普通容器元素(如 <div>),且必须满足几个硬性条件。下面直接说清楚怎么做、为什么不能用 <code><textarea></textarea>,以及如何安全替代:
✅ 正确做法:用
<div> 代替 <code><textarea></textarea> 做拖拽区<div id="drop-area" class="drop-area">
<p>拖拽文件到这里(支持大文件)</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher"><img
src="https://img.php.cn/upload/skill/000/000/081/179109368394970.jpg" alt="Wechat HTML Publisher" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher" class="overflowclass">Wechat HTML Publisher</a>
<p class="overflowclass">直接上传HTML富文本到微信公众号草稿箱。支持完整的HTML格式,无需Markdown转换。</p>
</div>
<a rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<input type="file" id="file-input" multiple style="display: none;">
</div>
<textarea></textarea> 不响应 dragover/drop 事件,浏览器会忽略你在它上面绑定的这些监听器;<div> 等块级容器才是标准拖拽目标,只要正确阻止默认行为,就能稳定捕获文件。<hr>
<h3>⚠️ 必须同时处理的三件事(缺一不可)</h3>
<ul>
<li>
<p><strong><code>dragenter 和 dragover 都要调用 e.preventDefault()
只在 drop 里阻止已经晚了。浏览器在 dragover 阶段就决定是否允许投放,不阻止就直接打开/下载文件。
const dropArea = document.getElementById('drop-area');
['dragenter', 'dragover', 'dragleave'].forEach(type => {
dropArea.addEventListener(type, e => e.preventDefault(), false);
});
drop 事件中读取文件必须用 e.dataTransfer.files
不是 e.target.files(那是 <input type="file"> 的),也不是 e.dataTransfer.items(兼容性差):
dropArea.addEventListener('drop', e => {
e.preventDefault();
const files = Array.from(e.dataTransfer.files); // FileList → 数组
console.log('收到', files.length, '个文件,总大小:',
files.reduce((sum, f) => sum + f.size, 0));
});
确保容器有实际尺寸和可交互状态
如果 <div> 没内容、没高度、或被 <code>pointer-events: none 覆盖,dragover 根本不会触发——鼠标“进不去”。
.drop-area {
min-height: 120px;
border: 2px dashed #999;
padding: 20px;
text-align: center;
}
❌ 为什么 <textarea></textarea> 行不通?
- 它是表单控件,原生行为是接受文本输入,不暴露
dataTransfer接口; - 即使你给它加
draggable="true"或监听drop,事件也不会冒泡到它身上,更不会触发dataTransfer.files; - 浏览器对
<textarea></textarea>的拖拽逻辑只限于“拖入文字片段”,不是文件。
? 补充建议:兼顾点击上传与拖拽体验
- 隐藏
<input type="file">,但保留它用于点击选择; - 点击
<div> 时手动触发 <code>file-input.click(); - 拖拽进入时加高亮样式(比如
dragenter时加.drag-over类),提升反馈感; - 大文件上传需额外处理:分片、进度、暂停、断点续传——这些和拖拽无关,属于后续
fetch或XMLHttpRequest层逻辑。
不复杂但容易忽略










