Nhập tệp kích hoạt jQuery


163

Đang cố gắng kích hoạt hộp tải lên (nút duyệt) bằng jQuery.
Phương pháp tôi đã thử bây giờ là:

$('#fileinput').trigger('click');   

Nhưng nó dường như không hoạt động. Xin vui lòng giúp đỡ. Cảm ơn bạn.


Bạn có thể thử một cái gì đó như thế này thay thế.
Kirtan

19
Không có cách nào để làm điều này? Thật là chán nản.
Marcus Downing

Thực sự chán nản, và nó được kích hoạt bởi 'nhấp chuột', nghiêm túc chứ? Tôi rất thích Flash / AS3, với API chặt chẽ và mô hình bảo mật mạnh mẽ chỉ cho phép FileReference.browse được gọi từ trình xử lý sự kiện đầu vào do người dùng khởi tạo. Hơn nữa, đầu vào tệp HTML xấu và không thể tạo kiểu (nó chỉ là thẻ đầu vào, rất nhiều để phân tách nội dung và kiểu), vì vậy bạn phải tạo nút 'duyệt' mới, cũng được kích hoạt bởi một sự kiện nhấp chuột ... mà bạn phải chuyển tiếp đến đầu vào tệp dưới dạng nhấp chuột ... điều này có thể dẫn đến đệ quy vô hạn tùy thuộc vào vị trí phần tử và độ đặc hiệu của ủy nhiệm sự kiện.
Triynko

Thật không may, việc sử dụng Flash đang ngày càng trở nên kém khả thi hơn, do các vấn đề bảo mật liên tục của nó và sự gia tăng của các trình chặn nội dung.
Tim

Câu trả lời:


195

Điều này là do một hạn chế bảo mật.

Tôi phát hiện ra rằng hạn chế bảo mật chỉ khi <input type="file"/>được đặt thành display:none;hoặc là visbilty:hidden.

Vì vậy, tôi đã cố gắng đặt nó bên ngoài khung nhìn bằng cách thiết lập position:absolutetop:-100px;và thì đấy nó hoạt động.

xem http://jsfiddle.net/DSARd/1/

gọi nó là hack.

Hy vọng rằng sẽ làm việc cho bạn.


4
không hoạt động trong ff 3.6. hoạt động trong chrome và thậm chí là 8, mặc dù vậy :)
AyKarsi

4
Có tài liệu nào trên msdn về hạn chế bảo mật không?
eomeoff

2
Công trình tuyệt vời. Trong mọi trường hợp tôi nghĩ là an toàn hơn thiết lập a left: -100px;. Bạn không bao giờ biết một trang có thể dài bao nhiêu
Alter Lagos

+1 Đây là câu trả lời thực sự (& một giải pháp tốt). Bất cứ ai cũng có một liên kết đến tài liệu mà điều này được nêu rõ ràng?
kontur

9
bạn cũng có thể đặt độ mờ thành 0
Stuart

109

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

JS:

$('#fileinput').trigger('click'); 

HTML:

<div class="hiddenfile">
  <input name="upload" type="file" id="fileinput"/>
</div>

CSS:

.hiddenfile {
 width: 0px;
 height: 0px;
 overflow: hidden;
}

>>> Một cái khác hoạt động đa trình duyệt: <<<

Ý tưởng là bạn phủ một nút "Duyệt" khổng lồ vô hình lên nút tùy chỉnh của bạn. Vì vậy, khi người dùng nhấp vào nút tùy chỉnh của bạn, anh ta thực sự nhấp vào nút "Duyệt" của trường nhập liệu gốc.

Câu đố về JS: http://jsfiddle.net/5Rh7b/

HTML:

<div id="mybutton">
  <input type="file" id="myfile" name="upload"/>
  Click Me!
</div>

CSS:

div#mybutton {

  /* IMPORTANT STUFF */
  overflow: hidden;
  position: relative;   

  /* SOME STYLING */
  width:  50px;
  height: 28px;
  border: 1px solid green;
  font-weight: bold
  background: red;
}

div#mybutton:hover {
  background: green;
}

input#myfile {
  height: 30px;
  cursor: pointer;
  position: absolute;
  top: 0px;
  right: 0px;
  font-size: 100px;
  z-index: 2;

  opacity: 0.0; /* Standard: FF gt 1.5, Opera, Safari */
  filter: alpha(opacity=0); /* IE lt 8 */
  -ms-filter: "alpha(opacity=0)"; /* IE 8 */
  -khtml-opacity: 0.0; /* Safari 1.x */
  -moz-opacity: 0.0; /* FF lt 1.5, Netscape */
}

JavaScript:

$(document).ready(function() {
    $('#myfile').change(function(evt) {
        alert($(this).val());
    });
});

Có một lỗ hổng, nếu bạn làm cho nút rộng hơn, thì trong IE9 / 10, nút tải lên vô hình được làm bằng nút bên phải và trường văn bản bên trái. Về điều này, bạn phải nhấp đúp chuột. Trong trường hợp này, hãy cố gắng đặt kích thước phông chữ thậm chí lớn hơn 100px;
yunzen

Điều này hoạt động ngay cả trong Chrome 53. Tuy nhiên, heightđề xuất thay đổi thànhheight: 100%
Raptor

Cái thứ hai thậm chí hoạt động trong Safari trên iOS. Rất đẹp!
Jannis

71

Bạn có thể sử dụng phần tử LABEL cũ.

<div>
    <label for="browse">Click Me</label>
    <input type="file" id="browse" name="browse" style="display: none">//
</div>

Điều này sẽ kích hoạt các tập tin đầu vào


5
Tại sao đây không phải là câu trả lời được chấp nhận? Đó là cách đơn giản nhất không yêu cầu javascript thú vị.
tomitrescak

@tomitrescak OP không chờ đợi câu trả lời tốt nhất.
Mahi

9
Hãy ghi nhớ câu trả lời đã được đăng 7 năm sau khi câu hỏi được gửi.

1
Câu trả lời hay nhất năm 2018 cũng vậy.
masoomyf

1
Câu trả lời hay nhất cho năm 2019 cũng vậy;)
guillaumepotier

17

Tôi có nó hoạt động (= đã kiểm tra) trong IE8 +, FF và chrome gần đây:

$('#uploadInput').focus().trigger('click');

Chìa khóa đang tập trung trước khi bắn nhấp chuột (nếu không thì chrome bỏ qua nó).

Lưu ý: bạn CẦN phải hiển thị đầu vào và hiển thị (như trong, không display:nonevà không visibility:hidden). Tôi đề nghị (như nhiều người khác có trước đây) hoàn toàn định vị đầu vào và ném nó ra khỏi màn hình.

#uploadInput {
    position: absolute;
    left: -9999px;
}

1
+1 cho điều đó. Tôi cũng nhận thấy rằng bạn có thể ẩn phần tử xung quanh nhưng không phải nút nhập tệp, sau đó hiển thị phần tử xung quanh, tập trung nút, kích hoạt nó, sau đó ẩn nút.
Stevo

10

Kiểm tra fiddle của tôi.

http://jsfiddle.net/mohany2712/vaw8k/

.uploadFile {
  visibility: hidden;
}

#uploadIcon {
  cursor: pointer;
}
<body>
  <div class="uploadBox">
    <label for="uploadFile" id="uploadIcon">
      <img src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/34/Icon_-_upload_photo_2.svg/512px-Icon_-_upload_photo_2.svg.png"  width="20px" height="20px"/>
    </label>
    <input type="file" value="upload" id="uploadFile" class="uploadFile" />
  </div>
</body>


9

adardesign đóng đinh nó liên quan đến yếu tố đầu vào tập tin bị bỏ qua khi nó bị ẩn. Tôi cũng nhận thấy nhiều người thay đổi kích thước phần tử thành 0 hoặc đẩy nó ra khỏi giới hạn với các điều chỉnh định vị và tràn. Đây là tất cả những ý tưởng tuyệt vời.
Một cách khác có vẻ cũng hoạt động hoàn hảo là chỉ đặt độ mờ thành 0 . Sau đó, bạn luôn có thể chỉ cần đặt vị trí để giữ cho nó không bù đắp các yếu tố khác như ẩn. Có vẻ như không cần thiết phải dịch chuyển một yếu tố gần 10K pixel theo bất kỳ hướng nào.

Đây là một ví dụ nhỏ cho những ai muốn một:

input[type='file']{
    position:absolute;
    opacity:0;
    /* For IE8 "Keep the IE opacity settings in this order for max compatibility" */
    -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
    /* For IE5 - 7 */
    filter: alpha(opacity=0);
}

7

Chỉ vì tò mò, bạn có thể làm điều gì đó bạn muốn bằng cách tự động tạo một biểu mẫu tải lên và tệp đầu vào, mà không cần thêm nó vào cây DOM:

$('.your-button').on('click', function() {
    var uploadForm = document.createElement('form');
    var fileInput = uploadForm.appendChild(document.createElement('input'));

    fileInput.type = 'file';
    fileInput.name = 'images';
    fileInput.multiple = true;

    fileInput.click();
});

Không cần thêm uploadForm vào DOM.


1
CẢM ƠN BẠN! Tôi đã tìm kiếm điều này trong 20 phút!
Labo

5

Mã chính xác:

<style>
    .upload input[type='file']{
        position: absolute;
        float: left;
        opacity: 0; /* For IE8 "Keep the IE opacity settings in this order for max compatibility" */
        -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; /* For IE5 - 7 */
        filter: alpha(opacity=0);
        width: 100px; height: 30px; z-index: 51
    }
    .upload input[type='button']{
        width: 100px;
        height: 30px;
        z-index: 50;
    }
    .upload input[type='submit']{
        display: none;
    }
    .upload{
        width: 100px; height: 30px
    }
</style>
<div class="upload">
    <input type='file' ID="flArquivo" onchange="upload();" />
    <input type="button" value="Selecionar" onchange="open();" />
    <input type='submit' ID="btnEnviarImagem"  />
</div>

<script type="text/javascript">
    function open() {
        $('#flArquivo').click();
    }
    function upload() {
        $('#btnEnviarImagem').click();
    }
</script>

4

Đó là về mục đích và thiết kế. Đây là một vấn đề bảo mật.


4

Trên thực tế, tôi đã tìm ra một phương pháp thực sự dễ dàng cho việc này, đó là:

$('#fileinput').show().trigger('click').hide();   

Bằng cách này, lĩnh vực đầu vào tập tin của bạn có thể có thuộc tính css hiển thị trên không và vẫn giành chiến thắng trong thương mại :)


nó có thể nhấp vào màn hình trên máy chậm hơn. Không phải là một giải pháp tối ưu
Dmitry Efimenko

4

Vẫn còn quá muộn để trả lời nhưng tôi nghĩ thiết lập tối thiểu này hoạt động tốt nhất. Tôi cũng đang tìm kiếm tương tự.

  <div class="btn-file">
     <input type="file" class="hidden-input">
     Select your new picture
  </div>

// css

.btn-file {
  display: inline-block;
  padding: 8px 12px;
  cursor: pointer;
  background: #89f;
  color: #345;
  position: relative;
  overflow: hidden;
}

.btn-file input[type=file] {
  position: absolute;
  top: 0;
  right: 0;
  min-width: 100%;
  min-height: 100%;
  filter: alpha(opacity=0);
  opacity: 0;
  cursor: inherit;
  display: block;
}

jsbin

nút khởi động tập tin bootstrap demo


không bao giờ là muộn để trả lời;)
AGuyCalledGerald

Vài năm sau vẫn trả lời tốt nhất IMO
DimmuR

4

Đây là một câu hỏi rất cũ, nhưng thật không may vấn đề này vẫn còn liên quan và cần một giải pháp.

Giải pháp (cực kỳ đơn giản) mà tôi đã đưa ra là "ẩn" trường nhập tệp thực tế và bọc nó bằng thẻ LABEL (có thể dựa trên Bootstrap và HTML5, để tăng cường).

See here:Mã ví dụ ở đây

Theo cách này, trường nhập tệp thực là vô hình và tất cả những gì bạn thấy là "nút" tùy chỉnh thực sự là một phần tử LABEL đã sửa đổi. Khi bạn bấm vào phần tử LABEL này, cửa sổ chọn tệp sẽ xuất hiện và tệp bạn chọn sẽ đi vào trường nhập tệp thực.

Trên hết, bạn có thể thao tác giao diện và hành vi theo ý muốn (ví dụ: lấy tên của tệp đã chọn từ tệp nhập tệp, sau khi được chọn và hiển thị ở đâu đó. Phần tử LABEL không tự động làm điều đó, tất nhiên. Tôi thường chỉ đặt nó bên trong LABEL, như nội dung văn bản của nó).

Hãy coi chừng! Thao tác của cái nhìn và hành vi của điều này được giới hạn trong bất cứ điều gì bạn có thể tưởng tượng và nghĩ về. ;-) ;-)


3

Tôi đã quản lý với $ (...). Click (); với JQuery 1.6.1


1
Hmm tò mò về cách bạn đã làm điều đó, trên trang web của tôi (www.iscriptdesign.com) đang thực hiện $ ('file: input'). Click () không làm gì cả, cũng không làm $ ('file: input'). nhấp chuột');
dr jerry

Dưới đây là ví dụ đầy đủ: <input type = "file" id = "picBrowse" ... và sau đó $ ('# picBrowse'). Click ();
Valentin Galea

Tôi đã thử nghiệm trên cr (không chắc là phiên bản nào) trên mac os, hoạt động trên FF 4 trên XP. Cảm ơn!
dr jerry

3

hoặc đơn giản hơn

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

2

tôi gặp vấn đề với xác thực phía máy khách tùy chỉnh <input type="file"/>trong khi sử dụng nút giả để kích hoạt nó và giải pháp @Guillaume Bodi's hoạt động với tôi (cũng với opacity: 0;chrome)

$("#MyForm").on("click", "#fake-button", function () {
        $("#uploadInput").focus().trigger("click");
    });

và kiểu css để tải lên đầu vào

#uploadInput {
opacity: 0.0; 
filter: alpha(opacity=0); /* IE lt 8 */
-ms-filter: "alpha(opacity=0)"; /* IE 8 */
-khtml-opacity: 0.0; /* Safari 1.x */
-moz-opacity: 0.0;
}

1

Hãy thử điều này, nó là một hack. Vị trí: tuyệt đối dành cho Chrome và kích hoạt ('thay đổi') dành cho IE.

var hiddenFile = $("<input type=\"file\" name=\"file\" id=\"file1\" style=\"position:absolute;left:-9999px\" />");
$('body').append(hiddenFile);

$('#aPhotoUpload').click(function () {
    hiddenFile.trigger('click');
    if ($.browser.msie)
        hiddenFile.trigger('change');
});

hiddenFile.change(function (e) {
    alert('TODO');
});

Lưu ý rằng $.browserkhông được dùng trong các phiên bản mới hơn của jQuery
Kevin Beal

1

Vấn đề của tôi có một chút khác biệt trên iOS 7. Hóa ra FastClick đã gây ra sự cố. Tất cả tôi phải làm là thêm class="needsclick"vào nút của tôi.


0

Đây có lẽ là câu trả lời tốt nhất, ghi nhớ các vấn đề trình duyệt chéo.

CSS:

#file {
  opacity: 0;
  width: 1px;
  height: 1px;
}

JS:

$(".file-upload").on('click',function(){
   $("[name='file']").click();
});

HTML:

<a class="file-upload">Upload</a>
<input type="file" name="file">

0

Tôi nghĩ rằng tôi hiểu vấn đề của bạn, bởi vì tôi có một tương tự. Vì vậy, thẻ <label>có thuộc tính cho, bạn có thể sử dụng thuộc tính này để liên kết đầu vào của bạn với type = "file". Nhưng nếu bạn không muốn kích hoạt điều này bằng nhãn này vì một số quy tắc bố cục của bạn, bạn có thể làm như thế này.

$(document).ready(function(){
  var reference = $(document).find("#main");
  reference.find(".js-btn-upload").attr({
     formenctype: 'multipart/form-data'
  });
  
  reference.find(".js-btn-upload").click(function(){
    reference.find("label").trigger("click");
  });
  
});
.hide{
  overflow: hidden;
  visibility: hidden;
  /*Style for hide the elements, don't put the element "out" of the screen*/
}

.btn{
  /*button style*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<div id="main">
<form enctype"multipart/formdata" id="form-id" class="hide" method="post" action="your-action">
  <label for="input-id" class="hide"></label>
  <input type="file" id="input-id" class="hide"/>
</form>

<button class="btn js-btn-upload">click me</button>
</div>

Tất nhiên bạn sẽ điều chỉnh nó cho mục đích và bố cục của riêng bạn, nhưng đó là cách tôi biết dễ dàng hơn để làm cho nó hoạt động !!


-1

Dựa trên câu trả lời của Guillaume Bodi, tôi đã làm điều này:

$('.fileinputbar-button').on('click', function() {
    $('article.project_files > header, article.upload').show();
    $('article.project_files > header, article.upload header').addClass('active');
    $('.file_content, article.upload .content').show();
    $('.fileinput-button input').focus().click();
    $('.fileinput-button').hide();
});

có nghĩa là nó bị ẩn để bắt đầu và sau đó hiển thị cho trình kích hoạt, sau đó ẩn lại ngay lập tức.

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.