เหตุการณ์การเลือกไฟล์อินพุต HTML ไม่เริ่มทำงานเมื่อเลือกไฟล์เดียวกัน


204

มีโอกาสใดที่จะตรวจสอบการเลือกไฟล์ทุกไฟล์ที่ผู้ใช้ทำกับ HTML inputของประเภทfileองค์ประกอบหรือไม่

ก่อนหน้านี้มีการถามหลายครั้ง แต่onchangeเหตุการณ์ที่เสนอมักจะไม่เริ่มทำงานหากผู้ใช้เลือกไฟล์เดียวกันอีกครั้ง


7
รหัสของคุณจะต้องเริ่มทำงานหรือไม่หากผู้ใช้กดยกเลิกแล้ว หนึ่งคาดว่าการกดปุ่ม Cancel จะไม่ทำอะไรเลยและฉันคิดว่าผู้ใช้ส่วนใหญ่คาดหวังเพิ่มเติมว่าการเลือกไฟล์เดียวกันใหม่จะมีผลเหมือนกับการยกเลิก ฉันไม่ทราบว่าเป็นไปได้หรือไม่ แต่ฉันขอแนะนำให้คุณพิจารณาการออกแบบนี้ใหม่
KRyan

1
เมื่อยกเลิกจะไม่เริ่มทำงานหรือทำให้ตรวจจับได้ มีความหมายมากกว่าการลบ UI ceveat: หากมีการเรียกการกระทำบางอย่างหลังจากเลือกไฟล์ผู้ใช้มักจะคาดหวังให้การกระทำซ้ำถ้าเขาเลือกไฟล์อีกครั้ง
dronus

บางทีเราอาจมีพฤติกรรมนี้ถ้าเราตั้งinputค่าเป็น '' หลังจากทำบางสิ่งกับไฟล์ แต่นั่นจะเป็นการลบชื่อไฟล์ที่มองเห็นได้ด้วย อย่างไรก็ตามอาจไม่เป็นไรเนื่องจากไฟล์นั้นได้รับการประมวลผลแล้วและผลของการกระทำนั้นอาจปรากฏที่อื่น
dronus

โปรดอธิบายสิ่งที่คุณต้องการจะทำอย่างไร
แชมป์

1
สิ่งที่ฉันต้องการคือการจำลองพฤติกรรมการใช้งานเดสก์ท็อปของโรงเรียนเก่า ถ้าฉัน 'เปิด' ไฟล์เดียวกันอีกครั้งในแอปพลิเคชันเดสก์ท็อปมักจะถูกโหลดใหม่หรือหากมีการกระทำบางอย่างกับไฟล์ (เช่นการแปลงเป็นรูปแบบอื่นตัวอย่าง) การกระทำนี้จะทำอีกครั้ง นี่คือสิ่งที่ผู้ใช้เดสก์ท็อปอาจคาดหวังจากเว็บแอปด้วยเช่นกัน แต่เหตุการณ์fileอินพุตonchangeไม่คล้ายกัน
dronus

คำตอบ:


279

กำหนดค่าของinputถึงเป็นnullในแต่ละonclickเหตุการณ์ สิ่งนี้จะรีเซ็ตค่าinputของและเรียกใช้onchangeเหตุการณ์แม้ว่าจะเลือกพา ธ เดียวกัน

input.onclick = function () {
    this.value = null;
};

input.onchange = function () {
    alert(this.value);
};​

นี่เป็นDEMO

หมายเหตุ: เป็นเรื่องปกติถ้าไฟล์ของคุณมีคำนำหน้าด้วย 'C: \ fakepath \' นี่เป็นคุณลักษณะด้านความปลอดภัยที่ป้องกันไม่ให้ JavaScript รู้เส้นทางที่แน่นอนของไฟล์ เบราว์เซอร์ยังคงรู้จักภายใน


1
ฉันลองตัวอย่าง แต่ (โดยใช้ Chrome 21) ฉันได้รับ `C: \ fakepath` + จากนั้นชื่อไฟล์ที่ฉันเลือก (ไม่รวมเส้นทาง) การแจ้งเตือนจะปรากฏในทุก ๆ ไฟล์เดียวกัน
Jasper de Vries

1
@JasperdeVries นั่นเป็นคุณลักษณะด้านความปลอดภัยที่ป้องกันไม่ให้ JavaScript รู้เส้นทางที่แน่นอนของไฟล์ เบราว์เซอร์ยังคงรู้เส้นทางภายใน
Brian Ustas

1
นอกจากนี้ null เป็นค่าที่อนุญาตสำหรับ <input type = "file"> เท่านั้น ดังนั้นหากคุณกำลังพยายามตั้งค่าเป็นไม่ได้กำหนดและรับข้อยกเว้นนั่นคือเหตุผลว่าทำไม
Noel Abrahams

5
มันไม่ได้ทำงานได้ดีใน IE11 จนกว่าคุณจะทำให้การเปลี่ยนแปลงขนาดเล็ก: สาธิต

21
เป็นการดีกว่าที่จะวางthis.value = nullที่ส่วนท้ายของonchangeเพราะมันเป็นไปได้ที่จะใช้งานองค์ประกอบการป้อนข้อมูลโดยไม่ต้องคลิกที่มัน (โดยใช้แป้นพิมพ์) คุณสามารถจัดเก็บได้input.filesหากคุณต้องการอ้างอิงในภายหลัง
Halcyon

24
<form enctype='multipart/form-data'>
    <input onchange="alert(this.value); this.value=null; return false;" type='file'>
    <br>
    <input type='submit' value='Upload'>
</form>

this.value=null; จำเป็นสำหรับ Chrome เท่านั้น Firefox จะใช้งานได้ดี return false;

นี่คือFIDDLE


2
เรียบง่ายและมีประสิทธิภาพเพียงแค่ทดสอบใน IE และ Chrome ล่าสุดและใช้งานได้อย่างมีเสน่ห์ ขอบคุณที่แบ่งปัน
Atul Chaudhary

8

ในบทความนี้ภายใต้ชื่อเรื่อง "การใช้อินพุตแบบฟอร์มสำหรับการเลือก"

http://www.html5rocks.com/en/tutorials/file/dndfiles/

<input type="file" id="files" name="files[]" multiple />

<script>
function handleFileSelect(evt) {

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

    // files is a FileList of File objects. List some properties.
    var output = [];
    for (var i = 0, f; f = files[i]; i++) {
     // Code to execute for every file selected
    }
    // Code to execute after that

}

document.getElementById('files').addEventListener('change', 
                                                  handleFileSelect, 
                                                  false);
</script>

มันเพิ่มตัวฟังเหตุการณ์เพื่อ 'เปลี่ยน' แต่ฉันทดสอบแล้วมันจะทริกเกอร์แม้ว่าคุณจะเลือกไฟล์เดียวกันและไม่ใช่ถ้าคุณยกเลิก


เมื่อพิจารณาถึงความหมายที่อาจคลุมเครือของ "การเปลี่ยนแปลง" ในกรณีนี้คุณลองใช้เบราว์เซอร์หลายตัวหรือไม่? คุณอาจต้องการระบุสิ่งที่คุณได้ลองใช้บนเว็บเบราว์เซอร์อาจไม่สอดคล้องกับสิ่งเหล่านี้เสมอไป
Thor84no

2
คุณใช้สภาพแวดล้อมแบบใดในการทดสอบ ประสบการณ์ของฉันกับ Chrome เป็นสิ่งที่ฉันกล่าวถึงในchangeเหตุการณ์เหตุการณ์นี้จะเกิดขึ้นเฉพาะกับการเปลี่ยนแปลงชื่อไฟล์
dronus

7

ใช้เหตุการณ์ onClick เพื่อล้างค่าของอินพุตเป้าหมายแต่ละครั้งที่ผู้ใช้คลิกบนฟิลด์ สิ่งนี้ทำให้มั่นใจได้ว่าเหตุการณ์ onChange จะถูกเรียกใช้สำหรับไฟล์เดียวกันเช่นกัน ทำงานให้ฉัน :)

onInputClick = (event) => {
    event.target.value = ''
}

<input type="file" onChange={onFileChanged} onClick={onInputClick} />

ใช้ TypeScript

onInputClick = ( event: React.MouseEvent<HTMLInputElement, MouseEvent>) => {
    const element = event.target as HTMLInputElement
    element.value = ''
}

ขอบคุณสำหรับการแก้ปัญหา
Deepak Tekchandani

1

ทำสิ่งที่คุณต้องการทำหลังจากโหลดไฟล์สำเร็จแล้วหลังจากการประมวลผลไฟล์ของคุณเสร็จสิ้นให้ตั้งค่าการควบคุมไฟล์เป็นสตริงว่างดังนั้น. change () จะถูกเรียกเสมอแม้ชื่อไฟล์จะเปลี่ยนไปหรือไม่ก็ตาม เช่นเช่นคุณสามารถทำสิ่งนี้และทำงานให้ฉันเหมือนมีเสน่ห์

   $('#myFile').change(function () {
       LoadFile("myFile");//function to do processing of file.
       $('#myFile').val('');// set the value to empty of myfile control.
    });

1
handleChange({target}) {
    const files = target.files
    target.value = ''
}

1
เฮ้ ngCourse! คำตอบที่ใช้รหัสเท่านั้นอาจช่วยแก้ปัญหาได้ แต่ก็มีประโยชน์มากกว่าถ้าคุณอธิบายว่าจะแก้ปัญหาอย่างไร ชุมชนต้องใช้ทฤษฎีและรหัสเพื่อทำความเข้าใจคำตอบของคุณอย่างเต็มที่
RBT

แม้ว่ารหัสนี้อาจแก้ปัญหาได้รวมถึงคำอธิบายว่าทำไมและวิธีแก้ปัญหานี้จะช่วยปรับปรุงคุณภาพการโพสต์ของคุณได้อย่างไรและอาจส่งผลให้คะแนนมากขึ้น จำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตไม่ใช่เพียงแค่คนที่ถามตอนนี้ โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายและระบุข้อ จำกัด และสมมติฐานที่ใช้ จากการทบทวน
ดับเบิ้ล

1

การล้างค่าของดัชนี 0 ของท่านทำงานให้ฉัน โปรดลองรหัสด้านล่างหวังว่ามันจะใช้งานได้ (AngularJs)

          scope.onClick = function() {
            input[0].value = "";
                input.click();
            };
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.