简体   繁体   中英

File input's input event and/or change event fire in Chrome and Opera, but not in Firefox, Edge or IE11

I have created a Drag&Drop file uploader, and it works fine in Chrome and Opera. Firefox, Edge and Internet Explorer however, are giving me headaches.

I have the following minimal example (with console logging for convenience):

 <!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 and Opera runs this page as we'd expect. The events are fired at the appropriate times, and the uploadFiles() function is eventually called.

Firefox, Edge and IE are able to fire the dragover and drop events, but the input event on the input element is not triggered when the file(s) are inserted from the dataTransfer.

I've been searching all day, and have found several similar questions, but none of the proposed solutions have worked for me.

Trigger the input event after you appended the file content, or even better call uploadFiles in the drop event

 <!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> 

As @madalinivascu pointed out in a comment to his answer, there's no need to go via the input for my purposes, as I can call uploadFiles() directly from the drop event callback function after rewriting uploadFiles() and its callers slightly. Now it works in all major browsers!

 <!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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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