简体   繁体   English

如何使用 JavaScript 检测图像是否已粘贴或拖放到内容可编辑区域?

[英]How do I detect, with JavaScript, if an image was pasted or dropped into a contenteditable area?

I have a script that prevents the user from pasting, or dropping dragged images into a contenteditable area.我有一个脚本可以防止用户粘贴或将拖动的图像拖放到内容可编辑区域。 When the user tries to do one of those two things, I want an alert to tell him he cannot do that.当用户尝试做这两件事中的一件时,我想要一个警报告诉他他不能这样做。 I tried adding alert("custom message") right before the last break.我尝试在最后一次休息之前添加alert("custom message") But it gets triggered in both cases (pasting and dropping).但它在两种情况下都会触发(粘贴和删除)。 How can I have two different alerts: one for when the user pastes an image ("you cannot paste images here"), and another for when the user drops a dragged image ("you cannot drop images here", within my code?我怎样才能有两种不同的警报:一种是当用户粘贴图像时(“您不能在此处粘贴图像”),另一种是当用户在我的代码中放置拖动的图像时(“您不能在此处放置图像”?

https://jsfiddle.net/36cfdpoh/ https://jsfiddle.net/36cfdpoh/

 window.onload = function() { document.getElementById("editDiv").oninput = function() { var thisElement = this; var currentElementChildren, currentElementChildrenLength; var elements = this.children; var elementsLength = elements.length; if (elementsLength > 0) { for (i = 0; i < elementsLength; i++) { if (elements[i].tagName == "IMG") { thisElement.children[i].remove(); break; } else { currentElementChildren = elements[i].children; currentElementChildrenLength = currentElementChildren.length; if (currentElementChildrenLength > 0) { for (ii = 0; ii < currentElementChildrenLength; ii++) { if (currentElementChildren[ii].tagName == "IMG") { thisElement.children[i].children[ii].remove(); alert("you cannot drop images here"); break; } } } } } } } }
 #editDiv { width: 250px; height: 50px; border: solid 1px #000; margin-bottom: 20px; } img { width: 250px; }
 <div id="editDiv" contenteditable="true"> <p>Try to drop or paste that image here.</p> </div> <img src="https://i7.pngguru.com/preview/134/138/533/star-golden-stars.jpg">

You can separately attach paste & drop event to dom and then check which one is firing您可以单独将粘贴拖放事件附加到 dom,然后检查哪个正在触发

There are two solutions to this.有两种解决方案。 Using the input event or using drop and paste events:使用input事件或使用drop paste

index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <link rel="stylesheet" type="text/css" href="styles.css">
  <title>Image phobia</title>
</head>

<body>
  <h1>Image phobia</h1>

  <div id="editDiv" contenteditable="true">
    <p>Try to drop or paste that image here.</p>
  </div>

  <img height="100" width="100" src="https://i7.pngguru.com/preview/134/138/533/star-golden-stars.jpg">
  <img height="100" width="100" src="https://i7.pngguru.com/preview/134/138/533/star-golden-stars.jpg">

  <script src="main.js" />
</body>

</html>

input event solution: input事件解决方案:

main.js

"use strict";
(function() {
  window.addEventListener("load", () => {
    const editDiv = document.getElementById("editDiv");

    // return a message depending on input type
    function alertMessage(type) {
      switch (type) {
        case "insertFromPaste":
          return "You can't paste images here";
        case "insertFromDrop":
          return "You can't drop images here";
      }
    }

    // recursive function to delete image from an element's children
    function removeImages(children) {
      let hadImage = false;
      for (let i = children.length - 1; i >= 0; i--) {
        const child = children[i];
        if (child.tagName === "IMG") {
          child.remove();
          hadImage = true;
          continue;
        }
        if (child.children.length) {
          hadImage = removeImages(child.children);
          if (hadImage) {
            break;
          }
        }
      }
      return hadImage;
    }

    function preventImageInput(e) {
      const inputType = e.inputType;
      if (inputType === "insertFromDrop" || inputType === "insertFromPaste") {
        if (e.target.children.length) {
          const hadImage = removeImages(e.target.children);
          if (hadImage) {
            alert(alertMessage(inputType));
          }
        }
      }
    }

    editDiv.addEventListener("input", preventImageInput);
  });
})();

drop and paste events solution: drop paste解决方案:

main.js

"use strict";
(function() {
  window.addEventListener("load", () => {
    const editDiv = document.getElementById("editDiv");

    // return message depending on event type
    function alertMessage(type) {
      switch (type) {
        case "paste":
          return "You can't paste images here";
        case "drop":
          return "You can't drop images here";
      }
    }

    function preventImageInput(e) {
      // you must use setTimeout because when both the paste or drop events are fired
      // the content isn't changed yet and you won't have access to the new content
      setTimeout(() => {
        const images = e.target.querySelectorAll("img");
        if (images.length) {
          for (let i = images.length - 1; i >= 0; i--) {
            const image = images[i];
            image.remove();
          }
          alert(alertMessage(e.type));
        }
      });
    }

    editDiv.addEventListener("paste", preventImageInput);
    editDiv.addEventListener("drop", preventImageInput);
  });
})();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM