文件输入的输入事件和/或更改事件在Chrome和Opera中触发,但在Firefox,Edge或IE11中不触发

时间:2018-11-05 11:52:38

标签: javascript jquery html

我已经创建了一个拖放文件上传器,它在Chrome和Opera中运行良好。 Firefox,Edge和Internet Explorer让我头疼。

我有以下最小示例(为方便起见,使用控制台日志记录):

<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
  <script>
    $(document).ready(function() {
      console.log("Document is ready.");

      document.addEventListener("drop", function(e) { // Fires on drop event
        console.log("Drop event recorded on document.");
        input = document.querySelector("#file-input"); // Find file input
        input.files = e.dataTransfer.files; // Set dropped files into file input
        e.preventDefault(); // Prevent default behavior (like opening the file(s) in the browser tab)
      });

      document.addEventListener("dragover", function(e) {
        console.log("Dragover event recorded on document.");
        e.preventDefault(); // Prevent default behavior (like opening the file(s) in the browser tab)
      });
    });

    function uploadFiles() {
      console.log("Function uploadFiles() called, it works in this browser!");
      // File upload logic here
      alert("Got new file(s), it works in this browser!");
    }
  </script>
</head>
<body>
  <h1>Test input event</h1>
  <p>Drop file(s) anywhere on the page to trigger the input event. The event is fired as expected in Chrome and Opera, but not in Firefox, Edge or Internet Explorer 11.</p>
  <p>When the event is fired, you will be notified by an alert message.</p>
  <input type="file" multiple id="file-input" oninput="console.log('oninput fired on input element.'); uploadFiles();" disabled/>
</body>
</html>

Chrome和Opera会像我们期望的那样运行此页面。在适当的时间触发事件,并最终调用uploadFiles()函数。

Firefox,Edge和IE能够触发拖放事件,但是当从dataTransfer插入文件时,不会触发输入元素上的输入事件。

我整天都在搜索,并且发现了几个类似的问题,但是没有一个提议的解决方案对我有用。

2 个答案:

答案 0 :(得分:0)

在添加文件内容后触发input事件,或者最好在放置事件中调用uploadFiles

<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
  <script>
    $(document).ready(function() {
      console.log("Document is ready.");

      document.addEventListener("drop", function(e) { // Fires on drop event
        console.log("Drop event recorded on document.");
        input = document.querySelector("#file-input"); // Find file input
        input.files = e.dataTransfer.files; // Set dropped files into file input
         $("#file-input").trigger('input');//trigger the upload
        e.preventDefault(); // Prevent default behavior (like opening the file(s) in the browser tab)
      });

      document.addEventListener("dragover", function(e) {
        console.log("Dragover event recorded on document.");
        e.preventDefault(); // Prevent default behavior (like opening the file(s) in the browser tab)
      });
    });

    function uploadFiles() {
      console.log("Function uploadFiles() called, it works in this browser!");
      // File upload logic here
      alert("Got new file(s), it works in this browser!");
    }
  </script>
</head>
<body>
  <h1>Test input event</h1>
  <p>Drop file(s) anywhere on the page to trigger the input event. The event is fired as expected in Chrome and Opera, but not in Firefox, Edge or Internet Explorer 11.</p>
  <p>When the event is fired, you will be notified by an alert message.</p>
  <input type="file" multiple id="file-input" oninput="console.log('oninput fired on input element.'); uploadFiles();" disabled/>
</body>
</html>

答案 1 :(得分:0)

正如@madalinivascu在对他的回答的评论中所指出的,出于我的目的,无需通过输入,因为在重写uploadFiles()之后,我可以直接从drop事件回调函数调用uploadFiles()和它的调用者略有不同。现在,它可以在所有主流浏览器中使用!

<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-1.12.4.min.js"
          integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
          crossorigin="anonymous"></script>
  <script>
    $(document).ready(function() {

      document.addEventListener("drop", function(e) { // Fires on drop event
        uploadFiles(e.dataTransfer.files); // Call uploadFiles() on drop
        e.preventDefault(); // Prevent default behavior (like opening the file(s) in the browser tab)
      });

      document.addEventListener("dragover", function(e) {
        e.preventDefault(); // Prevent default behavior (like opening the file(s) in the browser tab)
      });
    });

    function uploadFiles(files) {
      // File upload logic here
      alert("It works!");
    }
  </script>
</head>
<body>
  <h1>Test drop event</h1>
  <p>
    Drop file(s) anywhere on the page to trigger the drop event.
    The function uploadFiles() is now called as expected in all major browsers (not tested in Safari tho).
  </p>
  <!-- Input is now obsolete unless you want to provide an alternative file selection method -->
  <input type="file" multiple id="file-input" oninput="uploadFiles(this.files);" disabled/>
</body>
</html>