【问题标题】:Drag 'n drop not working拖放不工作
【发布时间】:2016-02-16 09:17:08
【问题描述】:

我正在尝试在我的网站中创建一个简单的拖放功能来选择文件。我跟着this tutorial 来实现它。我复制并粘贴了代码,它不起作用。

我在 chrome 和 internet explorer 上尝试过,它们都有相同的结果,即它会打开一个带有图像的新页面。我希望它获取文件路径,就像您从常规 input type="file" 上传时一样。

然后我在JSFiddle 上尝试了它,它在JSFiddle 中运行。我怎样才能让它在我的浏览器中工作?这是link to the files

代码sn-p:

function handleFileSelect(evt) {
  evt.stopPropagation();
  evt.preventDefault();

  var files = evt.dataTransfer.files; // FileList object.

  // files is a FileList of File objects. List some properties.
  var output = [];
  for (var i = 0, f; f = files[i]; i++) {
    output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
      f.size, ' bytes, last modified: ',
      f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a',
      '</li>');
  }
  document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}

function handleDragOver(evt) {
  evt.stopPropagation();
  evt.preventDefault();
  evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
}

// Setup the dnd listeners.
var dropZone = document.getElementById('drop_zone');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFileSelect, false);
.example {
  padding: 10px;
  border: 1px solid #ccc;
  width: 50%;
  margin: auto;
}
#drop_zone {
  border: 2px dashed #bbb;
  border-radius: 5px;
  padding: 25px;
  text-align: center;
  font: 20pt bold'Vollkorn';
  color: #bbb;
  height: 100px;
}
<div class="example">
  <div id="drop_zone">Drop files here</div>
  <output id="list"></output>
</div>

【问题讨论】:

  • 您是直接在浏览器中运行这些文件(例如 file://some_dir/test.html)还是先托管它们?
  • 我正在使用带有实时预览功能的支架。我用那个试过了,它没有用。然后我直接在浏览器中试了一下,也没用。
  • Ctrl-Shift-I 在 Chrome 中打开开发工具并转到控制台面板并查找错误。你的 sn-p 对我来说运行良好。
  • sn-p 运行良好,但如果您下载文件,则不会。
  • 那么尼克有你的答案。 jsFiddle 将为您“正确”订购东西。这个var dropZone = document.getElementById('drop_zone'); 为空,因为当您查询它时document.getElementById('drop_zone'); 不存在。脚本按照文档解析阶段遇到的顺序执行。

标签: javascript html css


【解决方案1】:

问题是您的脚本在 DOM 加载之前正在执行。最简单的解决方法是将引用filedrag.js&lt;script&gt; 标记移动到body 的底部。

如果您想在文档头中保留filedrag.js,则需要等到DOM 完全加载后才能尝试引用drop_zone 等元素。既然您决定使用 jQuery,那么您可以这样做:

function handleFileSelect(evt) {
    evt.stopPropagation();
    evt.preventDefault();

    var files = evt.dataTransfer.files; // FileList object.

    // files is a FileList of File objects. List some properties.
    var output = [];
    for (var i = 0, f; f = files[i]; i++) {
        output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
        f.size, ' bytes, last modified: ',
        f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a',
            '</li>');
    }
    $('#list').innerHTML = '<ul>' + output.join('') + '</ul>';
}

function handleDragOver(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
}

// This is necessary or jQuery won't include the data property when an event is triggered
// It's recommended you use the native event listeners, as this method will add extra overhead.
$.event.props.push("dataTransfer");

// Setup the dnd listeners.
window.onload = function(e) {
    var dropZone = $('#drop_zone');
    dropZone.on('dragover', handleDragOver);
    dropZone.on('drop', handleFileSelect);
}

【讨论】:

  • 感谢您的回答!只是想出了另一种方法。如果我在 js 文件中插入:$(document).ready(function() 那么我在哪里插入 script 标记并不重要。原因与您编写的逻辑相同。因为我要插入$(document).ready(function(),所以我希望它都是 JQuery,你能把它转换成 JQuery 吗?
  • @Jessica 当然,我会在一个小时左右完成。我马上就要回家了
  • @Jessica 抱歉这么久才回复你!我刚刚更新了帖子。更改非常小,但正如您所见,在 jQuery 的 $(document).ready(..) 事件触发之前,不会执行任何代码。如果您愿意,您可以将所有代码放在 .ready() 回调中,但您会受到该单个函数范围的限制。
  • 很抱歉给您带来了困惑。我的意思是,你能把整个代码转换成jquery吗?
  • 谢谢!还有 addEventListener。有没有办法在 JQuery 中做到这一点?
猜你喜欢
  • 2011-07-09
  • 2023-04-01
  • 1970-01-01
  • 2020-06-25
  • 2021-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-31
相关资源
最近更新 更多