เปิดกล่องโต้ตอบไฟล์ใน JavaScript


109

ฉันต้องการวิธีแก้ปัญหาเพื่อแสดงกล่องโต้ตอบเปิดไฟล์ใน HTML ในขณะที่คลิกไฟล์div. กล่องโต้ตอบเปิดไฟล์จะต้องเปิดขึ้นเมื่อdivคลิก

ฉันไม่ต้องการแสดงกล่องไฟล์อินพุตเป็นส่วนหนึ่งของหน้า HTML ต้องแสดงในกล่องโต้ตอบแยกต่างหากซึ่งไม่ใช่ส่วนหนึ่งของหน้าเว็บ


4
การแจ้งเตือนไม่ใช่กล่องโต้ตอบไฟล์? - คุณสามารถชี้แจงสิ่งที่คุณถามได้หรือไม่?
LiamB

3
ฉันคิดว่าเขากำลังบอกว่าเขาต้องการป๊อปอัป "เปิดไฟล์" มาตรฐาน
Valentin Rocher

1
ฉันต้องการกล่องโต้ตอบเปิดไฟล์เมื่อคลิก div จะต้องเป็นเหมือนการแจ้งเตือนซึ่งไม่ใช่ส่วนหนึ่งของหน้าเว็บ
ArK

คำตอบ:


53

นี่เป็นสิ่งที่ดี

การสาธิต Fine Uploader

เป็นการ<input type='file' />ควบคุมตัวเอง แต่มีการวาง div ไว้ด้านบนและใช้สไตล์ css เพื่อให้ได้ความรู้สึกนั้น ความทึบของตัวควบคุมไฟล์ถูกตั้งค่าเป็น 0 เพื่อให้ดูเหมือนว่าหน้าต่างโต้ตอบจะเปิดขึ้นเมื่อคลิกที่ div


1
มีวิธีควบคุมไฟล์ที่แสดงโดย javascript ไหม ... บอกว่าฉันต้องการเปิดกล่องโต้ตอบไฟล์และต้องการแค่นามสกุลไฟล์ที่มี. pdf เพื่อแสดง ..
Ajax3.14

1
@ Ajax3.14 เบราว์เซอร์ใหม่มีวัตถุ FileReader เบราว์เซอร์เก่าที่คุณต้องใช้ค่าและมองหานามสกุลไฟล์
Vicary

2
@ Ajax3.14 ไม่จำเป็นต้องใช้ FileReader หรือแยกส่วนขยาย เบราว์เซอร์จำนวนมากสนับสนุนคุณสมบัติ accept ในการป้อนไฟล์ สิ่งนี้ช่วยให้คุณ จำกัด ประเภทไฟล์ที่แสดงในกล่องโต้ตอบไฟล์เบราว์เซอร์ Fine Uploader ให้การเข้าถึงฟังก์ชันนี้ผ่านคุณสมบัติ acceptFiles ของตัวเลือกการตรวจสอบความถูกต้อง ดูส่วนการตรวจสอบความถูกต้องของเอกสารตัวเลือกสำหรับรายละเอียดเพิ่มเติม โปรดทราบว่าไม่รองรับแอตทริบิวต์ accept ใน IE9 หรือรุ่นก่อนหน้า
Ray Nicholus

1
นี่มันดียังไง? นี่เป็นแนวทางปฏิบัติที่ดีเลยหรือ ไม่ควรเป็นแบบนี้stackoverflow.com/a/18659941/915865 ?
Kat Lim Ruiz

1
@KatLimRuiz ไม่คำตอบที่คุณเชื่อมโยงไม่ใช่ทางออกที่ดี สิ่งนี้จะทำให้ IE เกิดข้อผิดพลาดหากคุณส่งแบบฟอร์มที่เกี่ยวข้องทางโปรแกรมด้วยเช่นกัน
Ray Nicholus

78

    $("#logo").css('opacity','0');
    
    $("#select_logo").click(function(e){
       e.preventDefault();
       $("#logo").trigger('click');
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#" id="select_logo">Select Logo</a> <input type="file" id="logo">

สำหรับ IE เพิ่มสิ่งนี้:

$("#logo").css('filter','alpha(opacity = 0');

3
เหตุใดคุณจึงส่งคืนเท็จในตัวจัดการการคลิก #select_logo
Sethish

4
มันจะไม่สร้างข้อผิดพลาด 404 มันจะพยายามและไปที่หน้าปัจจุบันโดยมี # เพิ่มที่ท้าย ซึ่งจะทำให้หน้ากระโดดขึ้นไปด้านบน ดังนั้นจึงเป็นการดีที่จะอยู่ที่นั่นด้วยเหตุผลที่แตกต่างออกไป :)
manavo

3
แม้ว่าฉันยังไม่ได้ทดสอบมากพอ "visibility: hidden;" ดูเหมือนจะเข้ากันได้มากขึ้น นอกจากนี้แม้จะมีความทึบ: 0 เหตุการณ์การคลิกจะทริกเกอร์หากองค์ประกอบ "มองไม่เห็น" คลิกในขณะที่การเปิดเผย: ซ่อนจะไม่ทำงาน
Aron

MDN ระบุว่าdocument.getElementById("logo").click()เพียงพอแล้ว นอกจากนี้ยังแสดงวิธีอื่น "Drag & Drop" developer.mozilla.org/en-US/docs/Web/API/File/…
Eric

2
คุณควรแปลงสิ่งนี้เป็น Javascript ปกติ JQuery ไม่ได้เป็นตรรกะที่จะใช้กับโปรเจ็กต์ขนาดเล็กเช่นนี้ ^ _ ^
Mister SirCode

57

ฉันไม่รู้ว่าทำไมไม่มีใครชี้ให้เห็น แต่นี่เป็นวิธีการทำโดยไม่ต้องใช้ Javascript และยังเข้ากันได้กับเบราว์เซอร์ใด ๆ


แก้ไข: ใน Safari ที่ได้รับการปิดใช้งานเมื่อซ่อนอยู่ด้วยinput วิธีที่ดีที่จะใช้display: noneposition: fixed; top: -100em


<label>
  Open file dialog
  <input type="file" style="position: fixed; top: -100em">
</label>

หากคุณต้องการคุณสามารถไป"วิธีที่ถูกต้อง"โดยใช้forในการlabelชี้ไปidที่อินพุตดังนี้:

<label for="inputId">file dialog</label>
<input id="inputId" type="file" style="position: fixed; top: -100em">

4
วิธีนี้ใช้งานได้อย่างมีเสน่ห์อย่างไรก็ตามคำแนะนำบางประการมีดังนี้ 1. <input>แท็กควรมีnameแอตทริบิวต์ 2. หากforระบุแอตทริบิวต์<input>แท็กไฟล์จะต้องมีidไฟล์.
Raptor

5
Simplicity is the ultimate sophistication
ncubica

2
เยี่ยมมาก! มันใช้งานได้อย่างมีเสน่ห์แม้จะมีภาพพื้นหลังหรือทำให้ป้ายกำกับได้รับคลิกจาวาสคริปต์ ขอบคุณ!
Leo Nomdedeu

2
BTW มีคนชี้ให้เห็นการจับคู่กับโซลูชันนี้ใน Safari อินพุตที่ซ่อนอยู่ด้วยdisplay: noneถูกปิดใช้งาน วิธีแก้ปัญหาคือใช้วิธีการอื่นเพื่อซ่อนอินพุต ฉันจะอัปเดตคำตอบเพื่อสะท้อนให้เห็นว่า
JP de la Torre

1
@JPdelaTorre มันจะดีกว่าถ้าคุณใช้ opacity: 0 แทนเพื่อซ่อนอินพุต
Adrian

40

จริงๆแล้วคุณไม่จำเป็นต้องมีความทึบการมองเห็นการ<input>จัดแต่งทรงผมและอื่น ๆ เพียงแค่ดู:

<a href="#">Just click me.</a>
<script type="text/javascript">
    $("a").click(function() {
        // creating input on-the-fly
        var input = $(document.createElement("input"));
        input.attr("type", "file");
        // add onchange handler if you wish to get the file :)
        input.trigger("click"); // opening dialog
        return false; // avoiding navigation
    });
</script>

การสาธิตในjsFiddle ทดสอบใน Chrome 30.0 และ Firefox 24.0 ไม่ทำงานใน Opera 12.16 อย่างไรก็ตาม


3
นี่น่าจะเป็นคำตอบที่ถูกต้อง สำหรับการใช้งาน Javascript อย่างแท้จริงไม่จำเป็นต้องแก้ไขโค้ด HTML ใด ๆ
Zhang Buzz

21
คำถามโง่ ๆ แต่หลังจากนั้นคุณจะได้ไฟล์ที่เลือกอย่างไร
Jay Wick

2
นี่เป็นวิธีแก้ปัญหาที่อันตรายซึ่งอาจทำให้เกิดปัญหาที่ไม่คาดคิด ตัวอย่างเช่นเบราว์เซอร์บางตัว (เช่น IE) อาจป้องกันไม่ให้ส่งแบบฟอร์มทางโปรแกรมหากเปิดไฟล์โดยใช้โปรแกรมด้วย วิธีที่ดีที่สุดในการแก้ปัญหานี้คือใช้ CSS ไม่ใช่ JavaScript
Ray Nicholus

3
@Charleston น่าเสียดายที่มันไม่ทำงานในบางเบราว์เซอร์ พวกเขาควรจะทำให้มันทำงานได้ :)
Tigran Saluev

3
ในปี 2020 โซลูชันนี้ดูเหมือนจะดีที่สุด ทดสอบบน BrowserStack ใน Edge, Safari, Opera, Firefox และ Chrome ใช้ได้กับทุกคน
V. Rubinetti

15

นี่คือสิ่งที่ได้ผลดีที่สุดสำหรับฉัน (ทดสอบบน IE8, FF, Chrome, Safari)

#file-input {
  cursor: pointer;
  outline: none;
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  overflow: hidden;
  filter: alpha(opacity=0); /* IE < 9 */
  opacity: 0;
}
.input-label {
  cursor: pointer;
  position: relative;
  display: inline-block;
}
<label for="file-input" class="input-label">
  Click Me <!-- Replace with whatever text or icon you wish to use -->
  <input type="file" id="file-input">
</label>

คำอธิบาย: ฉันวางตำแหน่งอินพุตไฟล์ไว้เหนือองค์ประกอบที่จะคลิกโดยตรงดังนั้นการคลิกใด ๆ ก็จะไปที่มันหรือป้ายกำกับ (ซึ่งจะดึงกล่องโต้ตอบการอัปโหลดขึ้นมาเหมือนกับว่าคุณคลิกที่ป้ายกำกับเอง) ฉันมีปัญหาบางอย่างกับส่วนปุ่มของอินพุตเริ่มต้นที่ยื่นออกมาจากด้านข้างของป้ายกำกับดังนั้นจึงจำเป็นต้องoverflow: hiddenป้อนข้อมูลและdisplay: inline-blockบนฉลาก


1
เพิ่มอินพุตให้สูงสุดและตั้งค่าความทึบเป็นศูนย์ ใช้งานได้ดีมาก!
Kinorsi

13

จะเป็นอย่างไรหากปิดจาวาสคริปต์บนเครื่องไคลเอนต์ ใช้โซลูชันต่อไปนี้สำหรับทุกสถานการณ์ คุณไม่จำเป็นต้องใช้ javascript / jQuery :

HTML

<label for="fileInput"><img src="File_upload_Img"><label>
<input type="file" id="fileInput"></label>

CSS

#fileInput{opacity:0}  
body{
    background:cadetblue;
}

คำอธิบาย: for="Your input Id". ทริกเกอร์เหตุการณ์การคลิกโดยค่าเริ่มต้นโดย HTML ดังนั้นโดยค่าเริ่มต้นจะทริกเกอร์เหตุการณ์การคลิกไม่จำเป็นต้องใช้ jQuery / javascript ถ้าทำโดย HTML ทำไมต้องใช้ jQuery / jScript และคุณไม่สามารถบอกได้ว่าลูกค้าปิดการใช้งาน JS หรือไม่ ฟีเจอร์ของคุณควรใช้งานได้แม้ว่า JS จะปิดอยู่ก็ตาม

ทำงาน jsFiddle (คุณไม่จำเป็นต้องใช้ JS, jquery)


3
ทำไมต้องเป็นพื้นหลัง?
Solomon Ucko

12

อันดับแรกเพิ่มในแท็กหัว :

<script>
   function showDialog(openFileDialog) {
       document.getElementById(openFileDialog).click();
   }
   function fileName(openFileDialog) {
       return document.getElementById(openFileDialog).value;
   }
   function hasFile(openFileDialog) {
       return document.getElementById(openFileDialog).value != "";
   }
   function fileNameWithoutFakePath(openFileDialog) {
       var fileName = document.getElementById(openFileDialog).value;
       return fileName.substr(fileName.lastIndexOf('\\') + 1);
   }
   function fakePathWithoutFileName(openFileDialog) {
       var fileName = document.getElementById(openFileDialog).value;
       return fileName.substr(0, fileName.lastIndexOf('\\'));
   }
</script>

หากคุณมีสคริปต์อยู่แล้วแท็กเพียงเพิ่มฟังก์ชันเหล่านี้ด้านบน

ในร่างกายของคุณหรือแท็กฟอร์มเพิ่ม:

<input type="file" style="display:none" id="yourDesiredOrFavoriteNameForTheNewOpenFileDialogInstance"/>

ไม่ว่าจะอยู่ที่ใดใน html ของคุณก็เหมือนกับการที่คุณได้สร้างอินสแตนซ์ใหม่ของคลาส OpenFileDialog เป็นตัวแปรส่วนกลางซึ่งมีชื่อเป็นidขององค์ประกอบไม่ว่าจะอยู่ที่ใดในโค้ดหรือ xaml ของคุณแต่ในสคริปต์หรือโค้ดของคุณ คุณไม่สามารถพิมพ์ชื่อของเขาแล้วอ่านคุณสมบัติหรือเรียกใช้ฟังก์ชันได้เนื่องจากมีฟังก์ชันส่วนกลางที่ทำหน้าที่ที่ไม่ได้กำหนดไว้ในประเภทอินพุตองค์ประกอบ = "ไฟล์" คุณต้องให้ฟังก์ชันเหล่านี้เป็น id ของประเภทอินพุตที่ซ่อน = "file" ซึ่งเป็นชื่อของอินสแตนซ์ OpenFileDialog เป็นสตริง

เพื่อให้ชีวิตของคุณง่ายขึ้นในการสร้างอินสแตนซ์กล่องโต้ตอบเปิดไฟล์ไปยัง html ของคุณคุณสามารถสร้างฟังก์ชันที่ทำได้:

function createAndAddNewOpenFileDialog(name) {
     document.getElementById("yourBodyOrFormId").innerHtml += "<input type='file' style='display:none' id='" + name + "'/>"
}

และหากคุณต้องการลบกล่องโต้ตอบที่เปิดอยู่คุณสามารถสร้างและใช้ฟังก์ชันต่อไปนี้:

function removeOpenFileDialog(name) {
    var html = document.getElementById("yourBodyOrFormId").innerHtml;
    html = html.replace("<input type='file' style='display:none' id='" + name + "'/>", "");
    document.getElementById("yourBodyOrFormId").innerHtml = html;
}

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

function doesOpenFileDialogExist(name) {
    return document.getElementById("yourBodyOrFormId").innerHtml.indexOf("<input type='file' style='display:none' id='" + name + "'/>") != -1
}

และถ้าคุณไม่ต้องการสร้างและเพิ่มกล่องโต้ตอบเปิดไฟล์ในแท็กbodyหรือformใน html เนื่องจากเป็นการเพิ่ม hidden input type = "file" s คุณสามารถทำได้ในสคริปต์โดยใช้ฟังก์ชัน create ด้านบน :

function yourBodyOrFormId_onload() {
    createAndAddNewOpenFileDialog("openFileDialog1");
    createAndAddNewOpenFileDialog("openFileDialog2");
    createAndAddNewOpenFileDialog("openFileDialog3");
    createAndAddNewOpenFileDialog("File Upload");
    createAndAddNewOpenFileDialog("Image Upload");
    createAndAddNewOpenFileDialog("bla");
    //etc and rest of your code
}

ตรวจสอบให้แน่ใจว่าคุณได้เพิ่มแท็กร่างกายหรือแบบฟอร์มไว้ใกล้ ๆ :

onload="yourBodyOrFormId_onload()"

คุณไม่จำเป็นต้องทำบรรทัดนี้ด้านบนถ้าคุณทำไปแล้ว

เคล็ดลับ:คุณสามารถเพิ่มไฟล์ JScript ใหม่ในโปรเจ็กต์หรือเว็บไซต์ของคุณได้หากคุณยังไม่มีและในไฟล์นี้คุณสามารถวางฟังก์ชั่นไดอะล็อกไฟล์ที่เปิดอยู่ทั้งหมดไว้ห่างจากแท็กสคริปต์และ html หรือหน้าเว็บฟอร์มและใช้ ไว้ใน html หรือหน้าเว็บฟอร์มของคุณจากไฟล์ JScript นี้ แต่อย่าลืมก่อนที่จะเชื่อมโยงหน้า html หรือเว็บฟอร์มกับไฟล์ JScript แน่นอน คุณสามารถทำได้เพียงลากไฟล์ JScript ไปที่หน้า html ของคุณในไฟล์หัวแท็ก หากหน้าของคุณเป็นรูปแบบเว็บไม่ใช่ html ธรรมดาและคุณไม่มีแท็กหัวให้วางไว้ที่ใดก็ได้เพื่อให้สามารถใช้งานได้ อย่าลืมกำหนดตัวแปรส่วนกลางในไฟล์ JScript ซึ่งค่าจะเป็น body หรือ form id เป็นสตริง หลังจากที่คุณเชื่อมโยงไฟล์ JScript กับหน้า html หรือเว็บฟอร์มของคุณแล้วคุณสามารถ onload เหตุการณ์ของ body of form ตั้งค่าของตัวแปรนั้นเป็น body หรือ form id ของคุณ จากนั้นในไฟล์ JScript คุณไม่จำเป็นต้องให้ id ของเนื้อหาหรือรูปแบบของหน้าเดียวกับเอกสารอีกต่อไปเพียงแค่ให้ค่าของตัวแปรนั้น คุณสามารถเรียกตัวแปรbodyIdหรือformIdหรือbodyOrFormIdหรือชื่ออื่น ๆ ที่คุณต้องการได้

ขอให้โชคดี!


1
ไม่ควรแก้ไข innerHTML โดยตรง
Solomon Ucko

9

วิธีที่ง่ายที่สุด:

#file-input {
  display: none;
}
<label for="file-input">
  <div>Click this div and select a file</div>
</label>
<input type="file" id="file-input"/>

สิ่งที่สำคัญคือการใช้งานdisplay: noneเพื่อให้แน่ใจว่าจะไม่มีที่ใดถูกครอบครองโดยอินพุตไฟล์ที่ซ่อนอยู่ (สิ่งที่เกิดขึ้นโดยใช้opacity: 0)



2

สิ่งเดียวที่ไม่มี<input type="file">คือการฝังภาพเคลื่อนไหวแฟลชโปร่งใสไว้บน div จากนั้นคุณสามารถใช้ที่ผู้ใช้สร้างเหตุการณ์ค (สอดคล้องกับ Flash 10 กฎความปลอดภัยใหม่) ที่จะเรียกเรียกร้องให้แฟลชของFileReference.browse

มันมีการพึ่งพาที่เพิ่มเข้ามาในโหมด quirksmodeแต่ในทางกลับกันคุณจะได้รับกิจกรรมมากมาย (เช่นเหตุการณ์ที่สร้างขึ้นในความคืบหน้า)


-1

อาจใช้

$('<input type="file" />').click()

ในกรณีของฉันสิ่งนี้ทำให้เกิดการเปลี่ยนเส้นทางโดยอัตโนมัติไปยังหน้าเดียวกับที่เกิดเหตุการณ์การคลิกเดิมทำให้ทั้งหน้าโหลดซ้ำและสูญเสียข้อมูลทั้งหมดที่ป้อนไว้ก่อนหน้านี้ในหน้า
Muntasir
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.