测试基于chrome 74
需求如下:
1.禁止放下图片后覆盖当前网页
2.当图片进入时提示用户将图片放在哪里,没有放到指定位置时,则重置状态
完整的例子如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>从网页外部拖拽图片</title>
<style>
.drop-here {
line-height: 200px;
width: 200px;
height: 200px;
text-align: center;
border: 1px solid #000;
}
</style>
</head>
<body>
<div
class="drop-here"
ondragover="dragover.call(this,event)"
ondrop="drop.call(this,event)"
></div>
</body>
<script>
let dropHereDom = document.querySelector(".drop-here");
let dragSeed = 0;
document.addEventListener(
"dragover",
e => {
e.preventDefault();
dropHereDom.textContent = "拖到这里";
e.dataTransfer && (e.dataTransfer.dropEffect = "none");
window.clearTimeout(dragSeed);
dragSeed = window.setTimeout(() => {
dropHereDom.textContent = "";
}, 100);
},
true
);
function drop(event) {
event.preventDefault();
const dragData = [];
//获得图片
if (event.dataTransfer.items && event.dataTransfer.items.length > 0) {
for (let i = 0; i < event.dataTransfer.items.length; i++) {
if (event.dataTransfer.items[i].kind === "file") {
const file = event.dataTransfer.items[i].getAsFile();
if (file) {
dragData.push(file);
}
}
}
console.log(dragData);
}
console.log(event); //看不到event.dataTransfer.items有东西
}
function dragover(event) {
event.dataTransfer && (event.dataTransfer.dropEffect = "copy");
}
</script>
</html>
禁止放下图片后覆盖当前网页
document.addEventListener("dragover");注意第三个参数,表示在捕获阶段监听。
e.dataTransfer && (e.dataTransfer.dropEffect = "none"); 全局禁止元素被放下
dragover()中 event.dataTransfer && (event.dataTransfer.dropEffect = "copy"),表示拖拽元素在drop-here中可以被放下,如果document.addEventListener("dragover")不在捕获阶段监听,此处就要加上event.stopPropagation()了。
drop() 中的event.preventDefault();禁止在drop-here中放下图片会覆盖当前网页。
当图片进入时提示用户将图片放在哪里,没有放到指定位置时,则重置状态
从网页外部拖入图片有其特殊性,试了几种方式,图片拖入到网页外放下不能处理。
拖动网页内部图片时就没有这么麻烦,相同情况下总是可以触发dragend事件
因此在document.addEventListener("dragover")中,利用dragover会一直触发,不断的clearTimeout,然后setTimeout,当不触发dragover时,表示拖拽结束了。
dataTransfer 下的dropEffect
dropEffect 表示拖拽的视觉效果以及行为 ,常见的值有copy,move,link,none
https://developer.mozilla.org/zh-CN/docs/Web/API/DataTransfer/dropEffect
与其相关的还有effectAllowed
绑定事件时候的this
<div class="drop-here" ondragover="dragover.call(this,event) ondrop="drop.call(this,event)"></div>
ondragover="dragover.call(this,event) 中的this是指向当前的DOM元素的,如果函数名称变成ondragover就会报错Maximum call stack size exceeded,自己调用自己...
这里要diss下Vue了,在2.5.0中,绑定事件既可以drop也可以drop(),个人认为应该和原生的统一。
同时React绑定事件可以onDragStart这种写法,也要和原生统一才好。
怎么说呢,框架尽量减少新概念、新写法对开发者以及团队会更友好,感觉React正在变的越来越难以被掌握!
网友评论