Lập trình kích hoạt hộp thoại “chọn tệp”


99

Tôi có một phần tử đầu vào tệp ẩn. Có thể kích hoạt hộp thoại tệp đã chọn của nó từ sự kiện nhấp vào nút không?

Câu trả lời:


146

Nếu bạn đang muốn có nút của riêng mình để tải tệp lên thay vì sử dụng <input type="file" />, bạn có thể làm như sau:

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

Lưu ý rằng tôi đã sử dụng visibility: hidden, thay vì display: none. Bạn không thể gọi sự kiện nhấp chuột trên đầu vào tệp không được hiển thị.


Đơn giản cho các trường hợp cơ bản, nhưng không tương thích với nhiều trình duyệt. Xin lưu ý rằng tốt hơn nhiều là kết hợp giải pháp này với việc phủ phần tử đầu vào tệp lên một nút ở opacity: 0, như nó đã được đề cập trong câu trả lời của Xeon06.
SquareCat

10
Cập nhật: Trong các trình duyệt hiện đại, bạn có thể nhấp vào một đầu vào thậm chí không có trong DOM. Tuyệt vời!
Adria

7
tôi chỉ cố gắng click()trên display:noneđầu vào và nó làm việc
Daniel Cheung

15
Vâng, đây là năm 2015, nhập click()vào một yếu tố với display: nonecác tác phẩm! ;) Mọi thứ đã thay đổi như thế nào trong bốn năm qua.
ffxsam

hiddenThay vào đó, bạn có thể sử dụng thuộc tính style="visibility:hidden": <input id="myInput" type="file" hidden>( w3schools.com/tags/att_global_hiested.asp )
cespon

113

Hầu hết các câu trả lời ở đây đều thiếu thông tin hữu ích:

Có, bạn có thể lập trình nhấp vào phần tử đầu vào bằng jQuery / JavaScript, nhưng chỉ khi bạn thực hiện việc đó trong trình xử lý sự kiện thuộc một sự kiện ĐƯỢC NGƯỜI DÙNG BẮT ĐẦU!

Vì vậy, chẳng hạn, sẽ không có gì xảy ra nếu bạn, tập lệnh, nhấp vào nút theo chương trình trong lệnh gọi lại ajax, nhưng nếu bạn đặt cùng một dòng mã trong trình xử lý sự kiện do người dùng đưa ra, nó sẽ hoạt động.

PS debugger;Từ khóa làm gián đoạn cửa sổ duyệt nếu nó ở trước khi nhấp chuột có lập trình ... ít nhất là trong chrome 33 ...


như @LouisBataillard đã đề cập một cách chính đáng: không chỉ trình xử lý sự kiện ban đầu cần được khởi tạo bởi người dùng; nó phải là một sự kiện nhấp chuột cụ thể. Đây là một fiddle ông cung cấp chứng minh điều này: link
Souhaieb Besbes

1
bạn có thể nhấp vào thứ gì đó được tạo động. trong jquery, đó là$(staticElementParent).on("click", "dynamicChild", function(){})
Daniel Cheung

1
CẢM ƠN BẠN!!!! Tôi đã thử nghiệm tất cả các câu trả lời này trong bảng điều khiển javascript và tôi đã phát điên lên!
jdkealy

8
Tôi đã vật lộn trong nửa giờ với việc lập trình nhắc cửa sổ nhập tệp. NOBODY ELSE đã tuyên bố rằng không thể xảy ra nếu sự kiện không được bắt đầu bởi người dùng ... bạn xứng đáng nhận được nhiều +1.
Umagon

1
Kể từ Chrome 62, debugger;từ khóa không còn làm gián đoạn nhấp chuột có lập trình nữa
Chris W.

62

Chỉ đối với bản ghi, có một giải pháp thay thế không yêu cầu javascript. Đó là một chút hack, khai thác thực tế là việc nhấp vào một nhãn đặt trọng tâm vào đầu vào liên quan.

Bạn cần một thuộc tính <label>thích hợp for(trỏ tới đầu vào), phân tích tùy chọn theo kiểu một nút (với bootstrap, sử dụng btn btn-default). Khi người dùng nhấp vào nhãn, hộp thoại sẽ mở ra, ví dụ:

<!-- 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
Tôi như thế này, không muốn để bao gồm đầy đủ jQuery trong dự án kiễu góc của tôi, làm việc thoải mái :)
Starscream1984

1
hành vi này có đáng tin cậy trong tất cả các trình duyệt hiện đại không?
JoshuaDavid

Điều này hoạt động mà không cần bất kỳ JS nào, sử dụng hành vi của trình duyệt gốc. Được kết hợp với các sự kiện onDrop, việc triển khai tải lên tệp nhiều tính năng hoạt động tuyệt vời!
Yanick Rochon

Tôi đã phải loay hoay với CSS nhưng sau đó nó hoạt động - cụ thể là khả năng hiển thị đầu vào tệp có "display: none" không ổn trong tất cả các trình duyệt. (Tuy nhiên, độ mờ đục của 0, vv, có thể được sử dụng)
driftcatcher

13

Tôi không chắc cách trình duyệt xử lý các nhấp chuột vào type="file"các phần tử (các mối quan tâm về bảo mật và tất cả), nhưng điều này sẽ hoạt động:

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

Tôi đã thử nghiệm JSFiddle này trong Chrome, Firefox và Opera và tất cả chúng đều hiển thị hộp thoại duyệt tệp.


5
Điều này dường như chỉ hoạt động khi bản thân sự kiện "đang gọi" là một sự kiện nhấp chuột. Ví dụ: dường như không thể mở hộp thoại tệp dựa trên hoversự kiện: jsfiddle.net/UQfaZ/1
Louis B.

Bạn có biết làm cách nào để kiểm tra điều này với Selenium nếu đầu vào không có trong DOM không?
Sebastien Lorber

4

Tôi bọc thẻ input[type=file]trong một thẻ nhãn, sau đó tạo kiểu labeltheo ý thích của bạn và ẩn 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>

Giải pháp hoàn toàn CSS.


Chỉ cần đặt <input type="file" hidden>để loại bỏ nhu cầu áp dụng kiểu CSS.
Sylvain Lesage

3

<input type="file">Thật không may, cách duy nhất là tạo một phần tử và sau đó mô phỏng một cú nhấp chuột.

Có một plugin nhỏ (plugin không biết xấu hổ) sẽ giúp bạn không phải làm điều này mọi lúc: tệp-hộp thoại

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

Giải pháp tốt nhất, hoạt động trên tất cả các trình duyệt .. ngay cả trên thiết bị di động.

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

Ẩn loại tệp đầu vào gây ra sự cố với trình duyệt, độ mờ là giải pháp tốt nhất vì nó không ẩn, chỉ không hiển thị. :)


1
bạn nên đề cập rằng điều này yêu cầu một tham chiếu jquery.
Brino

Độ mờ bao gồm một khái niệm hoàn toàn không liên quan - bạn chỉ may mắn nếu nó không ảnh hưởng đến bố cục của bạn với phần tử "nhìn xuyên qua". Phần tử nên ở đó, nhưng không thể nhìn thấy, vì vậy visibility:hiddensẽ là một lựa chọn tốt hơn.
conny

visibility: hiddenvẫn ảnh hưởng đến bố cục. display: nonelà những gì bạn muốn.
stommestack

1

Không có trình duyệt chéo nào để làm điều đó, vì lý do bảo mật. Những gì mọi người thường làm là phủ tệp đầu vào lên một thứ khác và đặt chế độ hiển thị của nó thành ẩn để nó tự kích hoạt. Thêm thông tin ở đây.


2
OP đang nói về <input type="file">, không phải <select>.
Bojangle

Không thành vấn đề. Tôi đã tự mình làm điều đó trước đây. Để đối phó với chỉnh sửa của bạn, có một cách để làm điều đó; bằng cách kích hoạt sự kiện nhấp chuột của phần tử với jQuery $.click().
Bojangles

1
@JamWaffles không sao, điều đó thật kỳ lạ. Tôi nhớ rõ ràng tôi đã dành cả ngày cho việc này vài tuần trước. Nó không hoạt động trên Firefox và IE sau. Tôi tự hỏi những gì thỏa thuận này là ...
Alex Turpin

Tò mò. Tôi có một JSFiddle trong câu trả lời của mình hoạt động với FF. Tôi không thể kiểm tra trong IE (tôi đang sử dụng Linux), vì vậy tôi không biết liệu điều đó có còn xảy ra hay không.
tam giác

2
Tốt nỗ lực nghiên cứu ở đó! Nếu tôi mất một xu cho mỗi lần các nhà phát triển web phải hack một số hành vi khá bình thường vào một thứ gì đó, tôi sẽ giàu có một cách bẩn thỉu.
tam giác

1

Đảm bảo rằng bạn đang sử dụng ràng buộc để nhận các đạo cụ thành phần trong REACT

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

Sử dụng jQuery, bạn có thể gọi click()để mô phỏng một cú nhấp chuột.


0

Điều này đã làm việc cho tôi:

$('#fileInput').val('');

0

Đối với những người muốn tương tự nhưng đang sử dụng 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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.