首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么‘`dataTransfer`’方法对我的对象返回null?

为什么‘`dataTransfer`’方法对我的对象返回null?
EN

Stack Overflow用户
提问于 2020-05-19 17:00:18
回答 1查看 277关注 0票数 0

我正在使用React构建一个拖放应用程序,并遵循本教程:https://jsfiddle.net/xv5mu40h/8/

然而,当我在我的终端尝试它时,我会得到这样的错误消息:TypeError: Cannot read property 'cloneNode' of null,特别提到了这一行代码:const nodeCopy = document.getElementById(data).cloneNode(true);

我已经在这行代码之前记录了data是什么,当我试图拖放任何对象(在本例中称为奖励)时,data似乎是空的。任何帮助都是非常感谢的!

注意:我已经尽可能多地提取了不相关的代码;对于更多的焦点,我认为问题在于拖放函数(而不是任何生命周期方法或唯一标识符方法)。

代码语言:javascript
复制
class Home extends Component {
  // Constructor for home
  constructor(props) {
    super(props);
    this.state = {
      rewards: [],
      cat1Counter: 1,
      cat2Counter: 1,
      cat3Counter: 1,
      cat4Counter: 1,
      cat5Counter: 1
    };
  }

  // Fetch rewards once component mounts
  componentDidMount() {
    this.props.fetchRewards();
  }

  // Update local state once all rewards are fetched
  componentDidUpdate(prevProps) {
    if (this.props.rewards !== prevProps.rewards) this.setState({rewards: this.props.rewards});
  }

  // Creates a unique ID for a reward copy
  getUniqueId(prefix) {
    let id = '';
    if (prefix === 'reward-1') {
      id = `${prefix} copy-${this.state.cat1Counter++}`
    } else if (prefix === 'reward-2') {
      id = `${prefix} copy-${this.state.cat2Counter++}`
    } else if (prefix === 'reward-3') {
      id = `${prefix} copy-${this.state.cat3Counter++}`
    } else if (prefix === 'reward-4') {
      id = `${prefix} copy-${this.state.cat4Counter++}`
    } else if (prefix === 'reward-5') {
      id = `${prefix} copy-${this.state.cat5Counter++}`
    }

    return id;
  }

  // Allow for elements to be dropped in other elements
  allowDrop(e) {
    e.preventDefault();
  }

  // Removes a node
  removeNode(node) {
    node.parentNode.removeChild(node);
  }

  // Drags a reward
  drag(e) {
    e.dataTransfer.setData('text', e.target.id);
  }

  // Drops the reward
  drop(e) {
    e.preventDefault();
    const data = e.dataTransfer.getData('text');
    const isLeft = 'reward-1' === data || 'reward-2' === data;

    const nodeCopy = document.getElementById(data).cloneNode(true);
    nodeCopy.id = `${this.getUniqueId(data)}`;

    if (isLeft) {
      e.target.appendChild(nodeCopy);
    } else {
      if (e.target.id !== 'P') {
        this.removeNode(document.getElementById(data));
        e.target.appendChild(nodeCopy);
      }
    }

    e.stopPropagation();
    return false;
  }

  render () {
    return (
      <div className="home-container">
        <div className="rewards-container">
          <h2>Rewards</h2>

          <ul>
            {this.state.rewards.map(reward => <li key={reward._id} draggable onDragStart={e => this.drag(e)}>{reward.name}</li>)}
          </ul>
        </div>

        <div className="categories-container">
          <h2>Categories</h2>

          <div className="list-wrapper">
            <ul id="category-1" onDrop={e => this.drop(e)} onDragOver={e => this.allowDrop(e)}><p>C1</p></ul>
            <ul id="category-2" onDrop={e => this.drop(e)} onDragOver={e => this.allowDrop(e)}><p>C2</p></ul>
            <ul id="category-3" onDrop={e => this.drop(e)} onDragOver={e => this.allowDrop(e)}><p>C3</p></ul>
            <ul id="category-4" onDrop={e => this.drop(e)} onDragOver={e => this.allowDrop(e)}><p>C4</p></ul>
            <ul id="category-5" onDrop={e => this.drop(e)} onDragOver={e => this.allowDrop(e)}><p>C5</p></ul>
          </div>
        </div>
      </div>
    );
  }
};

更新

根据下面的答案,我已经将onDrag更改为onDragStart,现在它可以在将对象从奖励列表中拖到类别中时工作;但是,当我尝试在类别之间拖动克隆对象时,bug仍然会弹出。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-19 17:06:29

您必须设置数据onDragStart。每次拖动时都会调用onDrag,并且可能不是设置的正确位置。您可以将onDrag更改为onDragStart

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61896681

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档