优雅的处理从网页外部拖拽图片

测试基于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正在变的越来越难以被掌握!

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容