ทริกเกอร์กล่องโต้ตอบ "เลือกไฟล์" โดยใช้โปรแกรม


101

ฉันมีองค์ประกอบอินพุตไฟล์ที่ซ่อนอยู่ เป็นไปได้ไหมที่จะเรียกใช้กล่องโต้ตอบเลือกไฟล์จากเหตุการณ์การคลิกของปุ่ม

คำตอบ:


148

หากคุณต้องการมีปุ่มของคุณเองเพื่ออัปโหลดไฟล์แทนที่จะใช้<input type="file" />คุณสามารถทำสิ่งต่อไปนี้

<input id="myInput" type="file" style="visibility:hidden" />
<input type="button" value="Show Dialog" onclick="$('#myInput').click();" />

โปรดทราบว่าฉันใช้visibility: hiddenแทนdisplay: none. คุณไม่สามารถเรียกเหตุการณ์การคลิกบนอินพุตไฟล์ที่ไม่แสดง


ตรงไปตรงมาสำหรับกรณีพื้นฐาน แต่ใช้ไม่ได้กับเบราว์เซอร์จำนวนมาก โปรดทราบว่าเป็นความคิดที่ดีกว่ามากในการรวมโซลูชันนี้เข้ากับการซ้อนทับองค์ประกอบอินพุตไฟล์บนปุ่มที่ทึบ: 0 ตามที่กล่าวไว้ในคำตอบของ Xeon06
SquareCat

11
อัปเดต: ในเบราว์เซอร์สมัยใหม่คุณสามารถคลิกอินพุตที่ไม่ได้อยู่ใน DOM สุดยอด!
Adria

7
ฉันพยายามclick()ในdisplay:noneการป้อนข้อมูลและการทำงาน
แดเนียล Cheung

16
ใช่ที่นี่ในปี 2015 click()มีองค์ประกอบที่มีdisplay: noneผลงาน! ;) สิ่งต่าง ๆ เปลี่ยนแปลงไปอย่างไรในช่วงสี่ปีที่ผ่านมา
ffxsam

1
คุณสามารถใช้hiddenแอตทริบิวต์แทนstyle="visibility:hidden": <input id="myInput" type="file" hidden>( w3schools.com/tags/att_global_hidden.asp )
cespon

117

คำตอบส่วนใหญ่ขาดข้อมูลที่เป็นประโยชน์:

ได้คุณสามารถคลิกองค์ประกอบอินพุตโดยใช้โปรแกรม jQuery / JavaScript แต่ถ้าคุณทำในตัวจัดการเหตุการณ์ที่เป็นของเหตุการณ์ที่เริ่มโดยผู้ใช้!

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

ปล. debugger;คีย์เวิร์ดจะรบกวนหน้าต่างเบราส์หากอยู่ก่อนการคลิกแบบโปรแกรม ... อย่างน้อยใน chrome 33 ...


ตามที่ @LouisBataillard กล่าวถึงอย่างถูกต้อง: ไม่เพียง แต่ผู้ใช้จะต้องเริ่มต้นตัวจัดการเหตุการณ์ดั้งเดิมเท่านั้น ต้องเป็นเหตุการณ์การคลิกโดยเฉพาะ นี่คือซอที่เขาให้ไว้เพื่อสาธิตสิ่งนี้: ลิงค์
Souhaieb Besbes

1
คุณสามารถคลิกสิ่งที่สร้างขึ้นแบบไดนามิก ใน jquery นั่นคือ$(staticElementParent).on("click", "dynamicChild", function(){})
Daniel Cheung

1
ขอบคุณ!!!! ฉันได้ทดสอบคำตอบเหล่านี้ทั้งหมดในคอนโซลจาวาสคริปต์แล้วและฉันก็บ้าไปแล้ว!
jdkealy

8
ฉันดิ้นรนมาครึ่งชั่วโมงด้วยการแจ้งให้หน้าต่างป้อนไฟล์ทางโปรแกรม NOBODY ELSE ระบุว่าเป็นไปไม่ได้เลยหากผู้ใช้ไม่ได้เริ่มกิจกรรม ... คุณสมควรได้รับ +1 เป็นจำนวนมาก
Umagon

1
ใน Chrome 62 debugger;คำหลักจะไม่รบกวนการคลิกแบบเป็นโปรแกรมอีกต่อไป
Chris W.

64

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

คุณต้อง<label>มีforแอตทริบิวต์ที่เหมาะสม(ชี้ไปที่อินพุต) ตัวเลือกสไตล์เหมือนปุ่ม (พร้อม bootstrap ใช้btn btn-default) เมื่อผู้ใช้คลิกที่ป้ายข้อความกล่องโต้ตอบจะเปิดขึ้นเช่น:

<!-- optionnal, to add a bit of style -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>

<!-- minimal setup -->
<label for="exampleInput" class="btn btn-default">
  Click me
</label>
<input type="file" id="exampleInput" style="display: none" />


2
ฉันชอบอันนี้ไม่ต้องการรวม jQuery แบบเต็มในโครงการ Angular ของฉันใช้งานได้ดี :)
Starscream1984

1
พฤติกรรมนี้เชื่อถือได้ในเบราว์เซอร์สมัยใหม่ทั้งหมดหรือไม่
JoshuaDavid

วิธีนี้ใช้งานได้โดยไม่มี JS ใด ๆ โดยใช้พฤติกรรมเบราว์เซอร์ดั้งเดิม จับคู่กับกิจกรรม onDrop การใช้ฟีเจอร์อัปโหลดไฟล์ที่สมบูรณ์จะทำงานได้ดี
Yanick Rochon

ฉันต้องใช้ CSS แต่มันก็ใช้งานได้นั่นคือการมองเห็นการป้อนไฟล์ที่มี "display: none" ไม่เป็นที่ยอมรับในทุกเบราว์เซอร์ (แต่ความทึบของ 0 ฯลฯ สามารถใช้ได้)
driftcatcher

14

ฉันไม่แน่ใจว่าเบราว์เซอร์จัดการกับการคลิกtype="file"องค์ประกอบอย่างไร (ข้อกังวลด้านความปลอดภัยและทั้งหมด) แต่ควรได้ผล:

$('input[type="file"]').click();

ฉันได้ทดสอบJSFiddle นี้ใน Chrome, Firefox และ Opera แล้วพวกเขาทั้งหมดแสดงกล่องโต้ตอบการเรียกดูไฟล์


5
ดูเหมือนว่าจะใช้ได้ผลก็ต่อเมื่อเหตุการณ์ "การโทร" เป็นเหตุการณ์การคลิกเท่านั้น ตัวอย่างเช่นดูเหมือนว่าจะเป็นไปไม่ได้ที่จะเปิดกล่องโต้ตอบไฟล์โดยอิงตามhoverเหตุการณ์: jsfiddle.net/UQfaZ/1
Louis B.

คุณรู้หรือไม่ว่าสิ่งนี้สามารถทดสอบกับซีลีเนียมได้อย่างไรหากอินพุตไม่อยู่ใน DOM
Sebastien Lorber

4

ฉันห่อinput[type=file]ป้ายกำกับจากนั้นจัดรูปแบบตามlabelที่คุณต้องการและซ่อนไฟล์input.

<label class="btn btn-default fileLabel" data-toggle="tooltip" data-placement="top" title="Upload">
    <input type="file">
    <span><i class="fa fa-upload"></i></span>
</label>

<style>
    .fileLabel input[type="file"] {
        position: fixed;
        top: -1000px;
    }
</style>

โซลูชัน CSS ล้วนๆ


เพียงตั้งค่า<input type="file" hidden>เพื่อลบความจำเป็นในการใช้สไตล์ CSS
Sylvain Lesage

3

วิธีเดียวคือการสร้างไฟล์ <input type="file">องค์ประกอบจากนั้นจำลองการคลิก แต่น่าเสียดาย

มีปลั๊กอินเล็ก ๆ (ปลั๊กไร้ยางอาย) ซึ่งจะช่วยลดความเจ็บปวดจากการต้องทำสิ่งนี้ตลอดเวลา: ไฟล์โต้ตอบ

fileDialog()
    .then(file => {
        const data = new FormData()
        data.append('file', file[0])
        data.append('imageName', 'flower')

        // Post to server
        fetch('/uploadImage', {
            method: 'POST',
            body: data
        })
    })

3

ทางออกที่ดีที่สุดใช้งานได้ในทุกเบราว์เซอร์ ... แม้กระทั่งบนมือถือ

<div class="btn" id="s_photo">Upload</div>

<input type="file" name="s_file" id="s_file" style="opacity: 0;">';

<!--jquery-->

<script>
    $("#s_photo").click(function() {
        $("#s_file").trigger("click");
    });
</script>

การซ่อนประเภทไฟล์อินพุตทำให้เกิดปัญหากับเบราว์เซอร์ความทึบเป็นวิธีแก้ปัญหาที่ดีที่สุดเพราะไม่ได้ซ่อน แต่ไม่แสดง :)


1
คุณควรระบุว่าสิ่งนี้ต้องการการอ้างอิง jquery
Brino

ความทึบเกี่ยวข้องกับแนวคิดที่ไม่เกี่ยวข้องกันโดยสิ้นเชิงคุณจะโชคดีแค่ไหนถ้ามันไม่ส่งผลกระทบต่อการจัดวางของคุณด้วยองค์ประกอบ "ดูทะลุ" องค์ประกอบควรอยู่ที่นั่น แต่มองไม่เห็นดังนั้นvisibility:hiddenควรเป็นทางเลือกที่ดีกว่า
conny

visibility: hiddenยังคงมีผลต่อเค้าโครง display: noneคือสิ่งที่คุณต้องการ
stommestack

1

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


2
สหกรณ์มีการพูดคุยเกี่ยวกับการไม่ได้<input type="file"> <select>
Bojangles

ไม่ใช่ปัญหา. ฉันเคยทำด้วยตัวเองมาก่อน ในการตอบสนองต่อการแก้ไขของคุณมีคือวิธีที่จะทำมัน; โดยเรียกเหตุการณ์คลิกองค์ประกอบของกับ $.click()jQuery
Bojangles

1
@JamWaffles โอเคมันแปลก ฉันจำได้ชัดเจนว่าใช้เวลาทั้งวันในช่วงสองสามสัปดาห์หลังนี้ มันไม่ทำงานใน Firefox และ IE ในระยะไกล ฉันสงสัยว่าข้อตกลงคืออะไร ...
Alex Turpin

อยากรู้อยากเห็น. ฉันมี JSFiddle ในคำตอบที่ใช้ได้กับ FF ฉันไม่สามารถทดสอบใน IE (ฉันใช้ Linux) ดังนั้นฉันจึงไม่รู้ว่าจะยังคงเกิดขึ้นหรือไม่
Bojangles

2
มีความพยายามในการวิจัยที่ดี! ถ้าฉันเสียเงินทุกครั้งที่นักพัฒนาเว็บต้องแฮ็คพฤติกรรมปกติธรรมดา ๆ ให้กลายเป็นบางสิ่งฉันก็จะเป็นคนรวยที่สกปรก
Bojangles

1

ตรวจสอบให้แน่ใจว่าคุณใช้การผูกเพื่อรับอุปกรณ์ประกอบฉากในปฏิกิริยา

class FileUploader extends Component {
  constructor (props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
   onChange=(e,props)=>{
    const files = e.target.files;
    const selectedFile = files[0];
    ProcessFileUpload(selectedFile,props.ProgressCallBack,props.ErrorCallBack,props.CompleatedCallBack,props.BaseURL,props.Location,props.FilesAllowed);
  }
   handleClick = () => {
    this.refs.fileUploader.click();
  }
  render()
  {
  return(
      <div>
        <button type="button" onClick={this.handleClick}>Select File</button>  
        <input type='file' onChange={(e)=>this.onChange(e,this.props)} ref="fileUploader" style={{display:"none"}} />
      </div>)
  }
}



0

สำหรับผู้ที่ต้องการแบบเดียวกัน แต่ใช้ React

openFileInput = () => {
    this.fileInput.click()
}

<a href="#" onClick={this.openFileInput}>
    <p>Carregue sua foto de perfil</p>
    <img src={img} />
</a>
<input style={{display:'none'}} ref={(input) => { this.fileInput = input; }} type="file"/>

0
<div id="uploadButton">UPLOAD</div>
<form action="[FILE_HANDLER_URL]" style="display:none">
     <input id="myInput" type="file" />
</form>
<script>
  const uploadButton = document.getElementById('uploadButton');
  const myInput = document.getElementById('myInput');

  uploadButton.addEventListener('click', () => {
    myInput.click();
  });
</script>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.