You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React应用在IE/Edge中使用dataTransfer的getData/setData报错求助

Fixing React dataTransfer Issues in IE & Edge

Hey there, let's break down exactly what's going on here—those two errors are absolutely linked, and they're classic gotchas with how older versions of IE and Edge handle the dataTransfer API (Chrome is way more forgiving!).

Why You're Seeing These Errors

Let's connect the dots clearly:

  1. "Element not found" error: This stems from strict rules IE/Edge enforce for dataTransfer methods:
    • setData() must be called synchronously inside the dragstart event handler—you can't call it later (like in an async function or unrelated event).
    • getData() can only be accessed in the drop event. Calling it in dragover, dragend, or any other event will throw this error.
  2. JSON.parse error: When the first error occurs, getData() returns an empty string instead of your expected data. Trying to parse an empty string with JSON.parse() will always trigger that "Unexpected input" error.

Step-by-Step Fixes

Here's how to adjust your React code to play nice with IE/Edge:

1. Use the Native Event for dataTransfer

React's synthetic event can sometimes wrap dataTransfer in a way that breaks in older browsers. Always access the native event directly with e.nativeEvent:

const handleDragStart = (e) => {
  // Grab the raw browser event instead of React's synthetic wrapper
  const nativeDragEvent = e.nativeEvent;
};

2. Restrict setData() to dragstart (Synchronously!)

Set your data immediately in the dragstart handler, and use a MIME type IE recognizes (stick with text/plain for widest compatibility—stringify your JSON data to store it here):

const handleDragStart = (e) => {
  const nativeDragEvent = e.nativeEvent;
  // Stringify your data to store as plain text
  const payload = JSON.stringify({ itemId: 123, content: "Drag this item" });
  // Set data synchronously in dragstart (no async calls here!)
  nativeDragEvent.dataTransfer.setData("text/plain", payload);
  // Optional: Define allowed drag behavior
  nativeDragEvent.dataTransfer.effectAllowed = "move";
};

3. Only Call getData() in drop (With Guard Clauses)

In your drop handler, add checks to ensure data exists before parsing it to avoid the JSON error:

const handleDrop = (e) => {
  e.preventDefault(); // Critical to override default browser drop behavior
  const nativeDropEvent = e.nativeEvent;

  // Check if the data type exists before trying to retrieve it
  if (nativeDropEvent.dataTransfer.types.includes("text/plain")) {
    const payloadStr = nativeDropEvent.dataTransfer.getData("text/plain");
    
    // Guard against empty strings before parsing
    if (payloadStr) {
      try {
        const payload = JSON.parse(payloadStr);
        // Do something with your parsed data here
        console.log("Dropped item:", payload);
      } catch (parseErr) {
        console.error("Failed to parse dragged data:", parseErr);
      }
    }
  }
};

4. Don't Forget onDragOver

You need to prevent the default behavior in onDragOver to let the drop event fire in IE/Edge:

const handleDragOver = (e) => {
  e.preventDefault();
};

Full Component Example

Putting it all together in a working component:

import React from "react";

const DragDropComponent = () => {
  const handleDragStart = (e) => {
    const nativeDragEvent = e.nativeEvent;
    const payload = JSON.stringify({ itemId: 123, content: "Drag me!" });
    nativeDragEvent.dataTransfer.setData("text/plain", payload);
    nativeDragEvent.dataTransfer.effectAllowed = "move";
  };

  const handleDragOver = (e) => {
    e.preventDefault();
  };

  const handleDrop = (e) => {
    e.preventDefault();
    const nativeDropEvent = e.nativeEvent;

    if (nativeDropEvent.dataTransfer.types.includes("text/plain")) {
      const payloadStr = nativeDropEvent.dataTransfer.getData("text/plain");
      if (payloadStr) {
        try {
          const payload = JSON.parse(payloadStr);
          alert(`You dropped item #${payload.itemId}: ${payload.content}`);
        } catch (err) {
          console.error("Parse error:", err);
        }
      }
    }
  };

  return (
    <div>
      <div
        draggable
        onDragStart={handleDragStart}
        style={{ padding: "1rem", border: "1px solid #ccc", margin: "1rem" }}
      >
        Drag This Box
      </div>
      <div
        onDrop={handleDrop}
        onDragOver={handleDragOver}
        style={{ padding: "2rem", border: "2px dashed #ccc", margin: "1rem" }}
      >
        Drop Here
      </div>
    </div>
  );
};

export default DragDropComponent;

Key Takeaways

  • IE/Edge have non-negotiable timing rules for dataTransfer—stick to setData in dragstart and getData in drop.
  • Always use the native event instead of React's synthetic event for dataTransfer operations.
  • Guard against empty strings before parsing to avoid JSON errors.

内容的提问来源于stack exchange,提问作者Ben Clarke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:18:02