Tạo kiểu cho kiểu nhập liệu


734

Làm thế nào để bạn phong cách một type="file"nút đầu vào ?


Tôi sẽ bổ sung câu trả lời của riêng tôi để làm điều đó theo cách tôi đã làm ... nhưng đây là một ví dụ dựa trên bootstrap mà có thể giúp đỡ .. geniuscarrier.com/...
Vishnu Narang

Câu trả lời:


235

Đầu vào tập tin kiểu dáng rất khó khăn, vì hầu hết các trình duyệt sẽ không thay đổi giao diện từ CSS hoặc javascript.

Ngay cả kích thước của đầu vào cũng sẽ không đáp ứng với lượt thích:

<input type="file" style="width:200px">

Thay vào đó, bạn sẽ cần sử dụng thuộc tính kích thước:

<input type="file" size="60" />

Đối với bất kỳ kiểu dáng nào phức tạp hơn thế (ví dụ: thay đổi giao diện của nút duyệt), bạn sẽ cần xem xét cách tiếp cận khéo léo của việc phủ một nút được tạo kiểu và hộp nhập liệu ở trên đầu vào tệp gốc. Bài viết đã được rm đề cập tại www.quirksmode.org/dom/inputfile.html là bài viết hay nhất tôi từng thấy.

CẬP NHẬT

Mặc dù rất khó để tạo kiểu <input>thẻ trực tiếp, nhưng điều này có thể dễ dàng với sự trợ giúp của <label>thẻ. Xem câu trả lời dưới đây từ @JoshCrozier: https://stackoverflow.com/a/25825731/10128619


7
Chỉ cần tìm một giải pháp jquery dựa trên kịch bản này tại đây: blog.vworld.at/2008/08/21/ trên
mtness

1
@TLK Câu trả lời của Ryan sẽ không hoạt động trong IE khi cố gắng tải lên iframe. Nó cung cấp cho bạn một lỗi từ chối truy cập. Đối với tải lên bình thường, tôi đồng ý rằng nó là dễ nhất mặc dù!
sương giá

3
Một giải pháp đơn giản hơn nhiều so với quirksmode được giải thích ở đây . Chỉ cần đặt liên kết đó ở đây, vì câu trả lời này về cơ bản là một câu trả lời chỉ liên kết.
Joeytje50

10
Đối với bất kỳ ai quan tâm đến một cách tiếp cận hiện đại, tôi khuyên bạn nên xem câu trả lời này . Nó cũng không yêu cầu JavaScript như một số câu trả lời khác.
Josh Crozier

3
@JoshCrozier đăng một giải pháp cực kỳ tốt hơn nhiều. Thậm chí còn đánh bại các giải pháp giả mạo giả mạo :)
Lodewijk

1017

Bạn không cần JavaScript cho việc này! Đây là một giải pháp đa trình duyệt:

Xem ví dụ này! - Nó hoạt động trong Chrome / FF / IE - (IE10 / 9/8/7)

Cách tiếp cận tốt nhất là có một phần tử nhãn tùy chỉnh với forthuộc tính được gắn vào phần tử nhập tệp ẩn . ( forThuộc tính của nhãn phải khớp với phần tử tệp idđể làm việc này).

<label for="file-upload" class="custom-file-upload">
    Custom Upload
</label>
<input id="file-upload" type="file"/>

Thay vào đó, bạn cũng có thể chỉ cần bọc phần tử nhập tệp bằng nhãn trực tiếp: (ví dụ)

<label class="custom-file-upload">
    <input type="file"/>
    Custom Upload
</label>

Về kiểu dáng, chỉ cần ẩn 1 phần tử đầu vào bằng cách sử dụng bộ chọn thuộc tính .

input[type="file"] {
    display: none;
}

Sau đó, tất cả những gì bạn cần làm là phong cách các labelyếu tố tùy chỉnh . (ví dụ) .

.custom-file-upload {
    border: 1px solid #ccc;
    display: inline-block;
    padding: 6px 12px;
    cursor: pointer;
}

1 - Điều đáng chú ý là nếu bạn ẩn phần tử bằng cách sử dụng display: none, nó sẽ không hoạt động trong IE8 trở xuống. Ngoài ra, hãy lưu ý rằng mặc định xác thực jQuery không xác thực các trường ẩn theo mặc định. Nếu một trong những điều đó là một vấn đề đối với bạn, thì đây là hai phương pháp khác nhau để ẩn đầu vào ( 1 , 2 ) hoạt động trong những trường hợp này.


43
Tôi có một câu hỏi với câu hỏi này, khi chọn một tệp, làm thế nào chúng ta sẽ đi về sau đó hiển thị tên tệp?
Richlewis

17
Làm cách nào để hiển thị tên của tệp đã chọn nếu display: noneđược đặt cho input[type=file]?
Sarthak Singhal

38
Giải pháp tuyệt vời, nhưng bạn thực sự cần javascript. Nếu bạn muốn hiển thị tên tệp, như những người khác đã hỏi, bạn cần thêm một khoảng giữa nhãn và đầu vào ẩn: <span id = "tệp được chọn"> </ span>. Sau đó cập nhật khoảng trên sự kiện thay đổi: $ ('# file-upload'). Bind ('thay đổi', function () {var fileName = ''; fileName = $ (this) .val (); $ ('# tệp được chọn '). html (tên tệp);})
Sam

9
Bạn nên sử dụng position: absolute; left: -99999remthay vì display: nonelý do tiếp cận. Hầu hết thời gian, trình đọc màn hình sẽ không đọc các phần tử nếu chúng bị ẩn bằng display: nonephương thức.
Viên nang

10
Tôi rất ngạc nhiên khi thấy không ai có vẻ đã xem xét khả năng truy cập bàn phím. labelcác phần tử không thể truy cập bàn phím, không giống như buttons và inputs. Thêm tabindexkhông phải là một giải pháp vì ý labelchí vẫn không được thực hiện khi nó có tiêu điểm và người dùng nhấn enter. Tôi đã giải quyết vấn đề này bằng cách ẩn trực quan đầu vào, để nó vẫn có thể được tập trung, và sau đó sử dụng :focus-withintrên labelcha mẹ: jsbin.com/fokexoc/2/edit?html,css,output
Oliver Joseph Ash

195

làm theo các bước sau đó bạn có thể tạo kiểu tùy chỉnh cho biểu mẫu tải lên tệp của mình:

  1. đây là mẫu HTML đơn giản (vui lòng đọc các nhận xét HTML tôi đã viết ở đây bên dưới)

    <form action="#type your action here" method="POST" enctype="multipart/form-data">
      <div id="yourBtn" style="height: 50px; width: 100px;border: 1px dashed #BBB; cursor:pointer;" onclick="getFile()">Click to upload!</div>
      <!-- this is your file input tag, so i hide it!-->
      <div style='height: 0px;width:0px; overflow:hidden;'><input id="upfile" type="file" value="upload"/></div>
      <!-- here you can have file submit button or you can write a simple script to upload the file automatically-->
      <input type="submit" value='submit' >
    </form>
  2. sau đó sử dụng tập lệnh đơn giản này để chuyển sự kiện nhấp vào thẻ đầu vào.

    function getFile(){
         document.getElementById("upfile").click();
    }

    Bây giờ bạn có thể sử dụng bất kỳ loại kiểu dáng nào mà không phải lo lắng về cách thay đổi kiểu mặc định.

Tôi biết điều này rất rõ vì tôi đã cố gắng thay đổi các kiểu mặc định trong một tháng rưỡi. tin tôi đi, rất khó vì các trình duyệt khác nhau có thẻ đầu vào tải lên khác nhau. Vì vậy, sử dụng cái này để xây dựng các hình thức tải lên tập tin tùy chỉnh của bạn. Dưới đây là mã UPLOAD TỰ ĐỘNG đầy đủ.

function getFile() {
  document.getElementById("upfile").click();
}

function sub(obj) {
  var file = obj.value;
  var fileName = file.split("\\");
  document.getElementById("yourBtn").innerHTML = fileName[fileName.length - 1];
  document.myForm.submit();
  event.preventDefault();
}
#yourBtn {
  position: relative;
  top: 150px;
  font-family: calibri;
  width: 150px;
  padding: 10px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border: 1px dashed #BBB;
  text-align: center;
  background-color: #DDD;
  cursor: pointer;
}
<form action="#type your action here" method="POST" enctype="multipart/form-data" name="myForm">
  <div id="yourBtn" onclick="getFile()">click to upload a file</div>
  <!-- this is your file input tag, so i hide it!-->
  <!-- i used the onchange event to fire the form submission-->
  <div style='height: 0px;width: 0px; overflow:hidden;'><input id="upfile" type="file" value="upload" onchange="sub(this)" /></div>
  <!-- here you can have file submit button or you can write a simple script to upload the file automatically-->
  <!-- <input type="submit" value='submit' > -->
</form>


6
@ user1053263 -> Cảm ơn bạn đã giới thiệu .. ở đây tôi đã sử dụng một tập lệnh java rất đơn giản, không cần sử dụng các khung như Jquery hoặc PrototypeJS.
teshguru

7
Tôi gặp sự cố khi gửi biểu mẫu trong IE9. Tôi đang gặp lỗi 'Truy cập bị từ chối' khi cố gửi biểu mẫu qua javascript. Nếu tôi nhấp vào nút gửi qua giao diện người dùng, nó hoạt động. Có một cách giải quyết cho điều này?
Kevin

1
@kevin -> Vui lòng thử event.preventDefault () sau document.myForm.submit (), tôi đã thực hiện thay đổi mã trên.
teshguru

1
Hoạt động tốt trong Chrome, Firefox, Safari & Opera - nhưng không có trong IE9. Trong IE9, tôi gặp lỗi 'Truy cập bị từ chối' giống như @Kevin - và đôi khi chỉ là một lỗi im lặng không có lỗi.
daveywc

10
Trong IE10 (và có thể cả IE9, v.v.), bạn sẽ nhận được "Truy cập bị từ chối" (hoặc không có phản hồi từ jQuery) nếu bạn thử và tự động gửi biểu mẫu sau khi nhấp vào nút nhập tệp qua javascript. Vì vậy, phương pháp này hoạt động để tạo kiểu cho nút nhập tệp miễn là người dùng vẫn là người gửi biểu mẫu. Mất một lúc tôi mới thấy điều này và tôi thấy những người khác cũng có vấn đề tương tự. Xem phần này để biết thêm thông tin stackoverflow.com/a/4335390/21579 .
Jeff Widmer

76

Ẩn nó bằng css và sử dụng nút tùy chỉnh với $ (bộ chọn) .click () để kích hoạt nút duyệt. sau đó đặt một khoảng để kiểm tra giá trị của kiểu nhập tệp. khoảng thời gian có thể hiển thị giá trị cho người dùng để người dùng có thể thấy những gì đang được tải lên. khoảng thời gian sẽ xóa khi biểu mẫu được gửi [EDIT] Xin lỗi tôi đã rất bận rộn để cập nhật bài đăng này, đây là một ví dụ

<form action="uploadScript.php" method="post" enctype="multipart/form-data">
<div>
    <!-- filename to display to the user -->
    <p id="file-name" class="margin-10 bold-10"></p>

    <!-- Hide this from the users view with css display:none; -->
    <input class="display-none" id="file-type" type="file" size="4" name="file"/>

    <!-- Style this button with type image or css whatever you wish -->
    <input id="browse-click" type="button" class="button" value="Browse for files"/>

    <!-- submit button -->
    <input type="submit" class="button" value="Change"/>
</div>

$(window).load(function () {
    var intervalFunc = function () {
        $('#file-name').html($('#file-type').val());
    };
    $('#browse-click').on('click', function () { // use .live() for older versions of jQuery
        $('#file-type').click();
        setInterval(intervalFunc, 1);
        return false;
    });
});

7
Lưu ý rằng nếu bạn sử dụng theo cách này, nó sẽ bị
hỏng

1
cảm ơn tiền boa Khi tôi sử dụng IE, nó thường có bố cục riêng cho mọi thứ khác. Ghét IE. nhưng tôi đơn giản hóa mọi thứ trong IE.
Ryan

1
Với FF20, $ ('# loại tệp'). Click () dường như không hiển thị quay số "Chọn tệp" - thực tế không có gì xảy ra. Có ý kiến ​​gì không?
andig

2
Hãy thử sử dụng phương thức kích hoạt trong jquery. Ngoài ra .live đã đổi thành .on () trong jquery mới
Ryan

1
một khi bạn đã đặt khoảng thời gian đó vào thời điểm nào tôi có thể xóa nó? nếu không nó sẽ liên tục bắn
Dave Haigh

60

HTML

<div class="new_Btn">SelectPicture</div><br>
<input id="html_btn" type='file'" /><br>

CSS

.new_Btn {
// your css propterties
}

#html_btn {
 display:none;
}

jQuery

$('.new_Btn').bind("click" , function () {
        $('#html_btn').click();
    });
//edit: 6/20/2014: Be sure to use ".on" not ".bind" for newer versions of jQuery

Câu đố : http://jsfiddle.net/M7BXC/

Bạn cũng có thể đạt được mục tiêu của mình mà không cần jQuery với JavaScript thông thường.

Bây giờ newBtn được liên kết với html_btn và bạn có thể tạo kiểu btn mới của mình như bạn muốn: D


1
Chỉ tò mò, nó có hoạt động trong mọi trình duyệt thuộc thế hệ mới như Firefox, IE, Opera, Safari, Chrome, v.v. không?
Wh1T3h4Ck5

Đây là giải pháp đơn giản nhất cho tôi! Ít nhất là trong IE 9, Chrome 23 và FF 16 với jQuery 1.7.2, vì vậy với các phiên bản cập nhật, nó sẽ hoạt động.
Dani bISHOP

Có ai biết cách thay đổi .new_Btn trong trường hợp người dùng đã chọn một hình ảnh. Bây giờ nó chỉ hiển thị cùng một lớp. Bất cứ ai cũng biết làm thế nào để theo dõi điều đó? Cảm ơn
Ando

2
@MehdiKaramosly nó hoạt động ngay cả trên IE 6 - nhưng điều đó chỉ đúng với jQuery 1.x , jQuery 2.x + không hỗ trợ các IE cũ
jave.web

1
@Ando qua Javascript / jQuery => giá trị của đầu vào tệp trống hoặc chứa đường dẫn tệp cục bộ => sử dụng sự kiện onchange và kiểm tra val () :) xem jsfiddle.net/ZrBPF
jave.web

55

Tất cả các công cụ kết xuất tự động tạo một nút khi một <input type="file"> tạo. Trong lịch sử, nút đó đã hoàn toàn không thể tạo kiểu. Tuy nhiên, Trident và WebKit đã thêm móc thông qua các yếu tố giả.

Cây đinh ba

Kể từ IE10, nút nhập tệp có thể được tạo kiểu bằng ::-ms-browsephần tử giả. Về cơ bản, bất kỳ quy tắc CSS nào bạn áp dụng cho một nút thông thường đều có thể được áp dụng cho phần tử giả. Ví dụ:

::-ms-browse {
  background: black;
  color: red;
  padding: 1em;
}
<input type="file">

Điều này sẽ hiển thị như sau trong IE10 trên Windows 8:

Điều này sẽ hiển thị như sau trong IE10 trên Windows 8:

WebKit

WebKit cung cấp một hook cho nút nhập tệp của nó với ::-webkit-file-upload-buttonphần tử giả. Một lần nữa, khá nhiều quy tắc CSS có thể được áp dụng, do đó, ví dụ Trident cũng sẽ hoạt động ở đây:

::-webkit-file-upload-button {
  background: black;
  color: red;
  padding: 1em;
}
<input type="file">

Điều này sẽ hiển thị như sau trong Chrome 26 trên OS X:

Điều này sẽ hiển thị như sau trong Chrome 26 trên OS X:


Không có khả năng tạo kiểu đặc biệt cho các chương trình dựa trên Gecko như Firefox.
Anselm

2
Trong câu trả lời của bạn, bằng cách sử dụng css, cách ẩn từ "Không chọn tệp" trong thẻ <input type = file>. Vui lòng nhận xét tôi.
user2086641

Tôi không biết, xin lỗi
Anselm


1
Trong trường hợp bất cứ ai muốn chơi với các phong cách, tôi đã thêm một jsfidde tại đây: jsfiddle.net/peter_drinnan/r0gq6kw2
Peter Drinnan

26

Nếu bạn đang sử dụng Bootstrap 3, điều này có hiệu quả với tôi:

Xem http://www.abeautitablesite.net/whipping-file-inputs-into-shape-with-bootstrap-3/

.btn-file {
  position: relative;
  overflow: hidden;
}
.btn-file input[type=file] {
  position: absolute;
  top: 0;
  right: 0;
  min-width: 100%;
  min-height: 100%;
  font-size: 100px;
  text-align: right;
  filter: alpha(opacity=0);
  opacity: 0;
  outline: none;
  background: white;
  cursor: inherit;
  display: block;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />

<span class="btn btn-primary btn-file">
    Browse...<input type="file">
</span>

Cái nào tạo ra nút nhập tệp sau:

Nút ví dụ

Nghiêm túc, hãy kiểm tra http://www.abeautitablesite.net/whipping-file-inputs-into-shape-with-bootstrap-3/


2
Điều này bảo tồn chức năng kéo và thả rất tuyệt :), hầu hết câu trả lời không chấp nhận các tập tin bị rơi.
A1rPun

25

Ví dụ hoạt động ở đây với hỗ trợ Kéo và thả tự nhiên: https://jsfiddle.net/j40xvkb3/

Khi tạo kiểu đầu vào tệp, bạn không nên phá vỡ bất kỳ tương tác gốc nào mà đầu vào cung cấp .

Các display: none tiếp cận phá vỡ hỗ trợ kéo và thả bản địa.

Để không phá vỡ bất cứ điều gì, bạn nên sử dụng opacity: 0cách tiếp cận cho đầu vào và định vị nó bằng cách sử dụng mẫu tương đối / tuyệt đối trong một trình bao bọc.

Sử dụng kỹ thuật này, bạn có thể dễ dàng tạo kiểu vùng nhấp / thả cho người dùng và thêm lớp tùy chỉnh trong javascript vào dragentersự kiện để cập nhật kiểu và cung cấp cho người dùng phản hồi để cho anh ta thấy rằng anh ta có thể thả tệp.

HTML:

<label for="test">
  <div>Click or drop something here</div>
  <input type="file" id="test">
</label>

CSS:

input[type="file"] {
  position: absolute;
  left: 0;
  opacity: 0;
  top: 0;
  bottom: 0;
  width: 100%;
}

div {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #ccc;
  border: 3px dotted #bebebe;
  border-radius: 10px;
}

label {
  display: inline-block;
  position: relative;
  height: 100px;
  width: 400px;
}

Dưới đây là một ví dụ hoạt động (có thêm JS để xử lý các dragoversự kiện và các tệp bị bỏ).

https://jsfiddle.net/j40xvkb3/

Hy vọng điều này sẽ giúp!


cảm ơn vì bài đăng, nó hoạt động như thế nào nếu thuộc tính nhiều = "nhiều" được thêm vào, tôi đã kéo 2 hình ảnh nhưng chỉ thấy đường dẫn cho cái đầu tiên
PirateApp

Bạn đã bỏ lỡ mã ở đây. Có nhiều hơn về fiddle. Thư viện gì?
ctrl-alt-delor

Chỉ có một số javascript trên fiddle với jQuery để hiển thị các tệp đã bị loại bỏ. Đó là tất cả
kevcha

Đã triển khai giải pháp này và thử nghiệm thêm, có vẻ như nó không hoạt động trong Edge.
ChrisA

1
À ok, tôi đã bỏ lỡ trình bao bọc với vị trí tương đối trong câu trả lời của bạn - My bad. Nếu đầu vào nằm dưới kích thước màn hình, trình duyệt sẽ cố gắng cuộn đến nó và làm như vậy, di chuyển thùng chứa cuộn lên trang. Dưới đây là một minh chứng: stackblitz.com/edit/input-file-overflow?file=style.css (chỉ không thể hiện chính xác vị trí tuyệt đối là nguyên nhân của hành vi)
Tom

23

Tôi có thể làm điều đó với CSS thuần bằng cách sử dụng mã dưới đây. Tôi đã sử dụng bootstrap và font-awesome.

<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet" />

<label class="btn btn-default btn-sm center-block btn-file">
  <i class="fa fa-upload fa-2x" aria-hidden="true"></i>
  <input type="file" style="display: none;">
</label>



12

Đây là một giải pháp không thực sự tạo kiểu cho <input type="file" />phần tử mà thay vào đó sử dụng một <input type="file" />phần tử bên trên các phần tử khác (có thể được tạo kiểu). Do đó, <input type="file" />phần tử không thực sự hiển thị, ảo ảnh tổng thể là một điều khiển tải lên tệp được tạo kiểu độc đáo.

Tôi đã gặp vấn đề này gần đây và mặc dù có rất nhiều câu trả lời trên Stack Overflow, nhưng không có gì thực sự phù hợp với dự luật. Cuối cùng, tôi đã kết thúc việc tùy chỉnh nó để có một giải pháp đơn giản và thanh lịch.

Tôi cũng đã thử nghiệm điều này trên Firefox, IE (11, 10 & 9), Chrome và Opera, iPad và một vài thiết bị Android.

Đây là liên kết JSFiddle -> http://jsfiddle.net/umhva747/

$('input[type=file]').change(function(e) {
    $in = $(this);
    $in.next().html($in.val());
    
});

$('.uploadButton').click(function() {
    var fileName = $("#fileUpload").val();
    if (fileName) {
        alert(fileName + " can be uploaded.");
    }
    else {
        alert("Please select a file to upload");
    }
});
body {
    background-color:Black;
}

div.upload {
    background-color:#fff;
    border: 1px solid #ddd;
    border-radius:5px;
    display:inline-block;
    height: 30px;
    padding:3px 40px 3px 3px;
    position:relative;
    width: auto;
}

div.upload:hover {
    opacity:0.95;
}

div.upload input[type="file"] {
    display: input-block;
    width: 100%;
    height: 30px;
    opacity: 0;
    cursor:pointer;
    position:absolute;
    left:0;
}
.uploadButton {
    background-color: #425F9C;
    border: none;
    border-radius: 3px;
    color: #FFF;
    cursor:pointer;
    display: inline-block;
    height: 30px;
    margin-right:15px;
    width: auto;
    padding:0 20px;
    box-sizing: content-box;
}

.fileName {
    font-family: Arial;
    font-size:14px;
}

.upload + .uploadButton {
    height:38px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form action="" method="post" enctype="multipart/form-data">
    <div class="upload">
        <input type="button" class="uploadButton" value="Browse" />
        <input type="file" name="upload" accept="image/*" id="fileUpload" />
        <span class="fileName">Select file..</span>
    </div>
    <input type="button" class="uploadButton" value="Upload File" />
</form>

Hi vọng điêu nay co ich!!!


2
Một giải pháp khéo léo thông minh cho các shenanigans tải lên tập tin bất chính này.
rmcsharry

Tốt nhất trong tất cả. Hoàn hảo!!
Karra

11

Điều này là đơn giản với jquery. Để đưa ra một ví dụ mã về đề xuất của Ryan với một sửa đổi nhỏ.

Html cơ bản:

<div id="image_icon"></div>
<div id="filename"></div>
<input id="the_real_file_input" name="foobar" type="file">

Đảm bảo đặt kiểu dáng trên đầu vào khi bạn sẵn sàng: opacity: 0 Bạn không thể đặt display: nonevì nó cần phải có thể nhấp được. Nhưng bạn có thể đặt nó dưới nút "mới" hoặc nhét vào bên dưới thứ khác bằng chỉ số z nếu bạn thích.

Thiết lập một số jquery để nhấp vào đầu vào thực khi bạn nhấp vào hình ảnh.

$('#image_icon').click(function() {
    $('#the_real_file_input').click();
});

Bây giờ nút của bạn đang hoạt động. Chỉ cần cắt và dán giá trị khi thay đổi.

$('input[type=file]').bind('change', function() {
    var str = "";
    str = $(this).val();
    $("#filename").text(str);
}).change();

Ta đa! Bạn có thể cần phân tích val () thành một cái gì đó có ý nghĩa hơn nhưng bạn nên thiết lập tất cả.


1
điều này sẽ thất bại với FF11 - lý do: vì bạn không thể ảnh hưởng chính xác đến kích thước của trường đầu vào (chỉ bằng cách sử dụng kích thước html) và nút (bạn có thể đặt chiều cao bằng css), nếu trường đầu vào hiển thị của bạn lớn hơn FF ban đầu cung cấp cho chúng tôi, bạn bị bỏ lại với một vùng mù rất lớn - quan điểm của người dùng: trong hầu hết các trường hợp, anh ta sẽ phàn nàn rằng tải lên không hoạt động, khi được nhấp
Jeffz

2
Ý tưởng tốt nhưng điều này sẽ không hoạt động trên IE. $ ('# the_real_file_input'). click () sẽ kích hoạt hộp thoại mở nhưng tệp sẽ không được chọn vào một biểu mẫu và tải lên sẽ thất bại.
Tomas

11

Đặt nút tải lên trên nút hoặc phần tử đẹp của bạn và ẩn nó.

Rất đơn giản và sẽ hoạt động trên mọi trình duyệt

<div class="upload-wrap">
    <button type="button" class="nice-button">upload_file</button>
    <input type="file" name="file" class="upload-btn">
</div>

Kiểu dáng

.upload-wrap {
    position: relative;
}

.upload-btn {
    position: absolute;
    left: 0;
    opacity: 0;
}

8

TẦM NHÌN: TRICK ẩn

Tôi thường đi visibility:hiddenlừa

đây là nút theo kiểu của tôi

<div id="uploadbutton" class="btn btn-success btn-block">Upload</div>

đây là kiểu đầu vào = nút tập tin. Lưu ý visibility:hiddenquy tắc

<input type="file" id="upload" style="visibility:hidden;">

đây là bit JavaScript để dán chúng lại với nhau. Nó hoạt động

<script>
 $('#uploadbutton').click(function(){
    $('input[type=file]').click();
 });
 </script>

1
bạn không thể sử dụng phương thức click () để kích hoạt sự kiện cho tệp loại đầu vào. hầu hết các trình duyệt không cho phép vì lý do bảo mật
Mahi

thậm chí sử dụng jquery? đúng không? thay vào đó bạn sẽ làm thế nào?
Gianluca Ghettini


style="visibility:hidden"quá dài, chỉ cần sử dụng hidden. Ngoài ra, click()không hoạt động cho bất kỳ trình duyệt nào và hiện tại không có lý do bảo mật rất khả thi nào và trên mọi thiết bị, đó là cách hợp pháp và @Gianluca cho việc sử dụng jQuery cổ điểntrigger()
Thielicy

1
Đây chính xác là giải pháp tôi sẽ thêm vào đây! Nó hoạt động và bạn có thể hiển thị chính xác như bạn muốn. Hoạt động với Chrome, sẽ thử người khác.
markthewizard1234

7

cách duy nhất tôi có thể nghĩ đến là tìm nút bằng javascript sau khi nó được hiển thị và gán kiểu cho nó

bạn cũng có thể nhìn vào bài viết này


CSS thuần túy, không có JavaScript, hoạt động trong tất cả các trình duyệt cho đến eg7 - tuyệt vời!
Simon Steinberger

7
<input type="file" name="media" style="display-none" onchange="document.media.submit()">

Tôi thường sử dụng javascript đơn giản để tùy chỉnh thẻ nhập tệp. Trường nhập ẩn, khi nhấp vào nút, javascript gọi trường ẩn, giải pháp đơn giản với bất kỳ css hoặc bó jquery nào.

<button id="file" onclick="$('#file').click()">Upload File</button>

1
bạn không thể sử dụng click()phương thức để kích hoạt sự kiện cho tệp loại đầu vào. hầu hết các trình duyệt không cho phép vì lý do bảo mật.
Mahi

6

Ở đây chúng tôi sử dụng một khoảng để kích hoạt đầu vào của loại tệp và chúng tôi chỉ cần tùy chỉnh khoảng đó , vì vậy chúng tôi có thể thêm bất kỳ kiểu dáng nào bằng cách này.

Lưu ý rằng chúng tôi sử dụng thẻ đầu vào với khả năng hiển thị: tùy chọn ẩn và kích hoạt nó trong khoảng.

.attachFileSpan{
color:#2b6dad;
cursor:pointer;
}
.attachFileSpan:hover{
text-decoration: underline;
}
<h3> Customized input of type file </h3>
<input id="myInput" type="file" style="visibility:hidden"/>

        <span title="attach file" class="attachFileSpan" onclick="document.getElementById('myInput').click()">
        Attach file
        </span>

Tài liệu tham khảo


5

Đây là một cách hay để làm điều đó với tải lên tập tin vật liệu / góc. Bạn có thể làm tương tự với nút bootstrap.

Lưu ý tôi đã sử dụng <a>thay vì <button>điều này cho phép các sự kiện nhấp vào bong bóng.

<label>
    <input type="file" (change)="setFile($event)" style="display:none" />

    <a mat-raised-button color="primary">
      <mat-icon>file_upload</mat-icon>
      Upload Document
    </a>

  </label>

1
Điều này hoạt động tuyệt vời trong góc 2+. Không chắc chắn tại sao nó xuống bình chọn. Nếu bạn đang sử dụng góc cạnh thì đây là giải pháp đơn giản nhất hiện có.
AndrewWhalan

4

CHỈ CSS

Sử dụng rất đơn giảnDỄ DÀNG

Html:

<label>Attach your screenshort</label>
                <input type="file" multiple class="choose">

Css:

.choose::-webkit-file-upload-button {
    color: white;
    display: inline-block;
    background: #1CB6E0;
    border: none;
    padding: 7px 15px;
    font-weight: 700;
    border-radius: 3px;
    white-space: nowrap;
    cursor: pointer;
    font-size: 10pt;
}

4

Có lẽ rất nhiều điều đáng sợ. Nhưng tôi thích điều này trong CSS thuần với các nút fa:

.divs {
    position: relative;
    display: inline-block;
    background-color: #fcc;
}

.inputs {
    position:absolute;
    left: 0px;
    height: 100%;
    width: 100%;
    opacity: 0;
    background: #00f;
    z-index:999;
}

.icons {
    position:relative;
}
<div class="divs">
<input type='file' id='image' class="inputs">
<i class="fa fa-image fa-2x icons"></i>
</div>

<div class="divs">
<input type='file' id='book' class="inputs">
<i class="fa fa-book fa-5x icons"></i>
</div>
<br><br><br>
<div class="divs">
<input type='file' id='data' class="inputs">
<i class="fa fa-id-card fa-3x icons"></i>
</div>





<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>

Fiddle: https://jsfiddle.net/zoutepopcorn/v2zkbpay/1/


4

Đừng để bị lừa bởi các giải pháp CSS "tuyệt vời" thực sự rất dành riêng cho trình duyệt hoặc lớp phủ nút được tạo kiểu trên đầu nút thực hoặc buộc bạn phải sử dụng <label>thay vì một<button> hoặc bất kỳ hack nào khác . JavaScript IS cần thiết để làm cho nó hoạt động để sử dụng chung. Vui lòng nghiên cứu cách gmail và DropZone làm điều đó nếu bạn không tin tôi.

Chỉ cần tạo kiểu cho một nút bình thường theo cách bạn muốn, sau đó gọi một hàm JS đơn giản để tạo và liên kết một phần tử đầu vào ẩn với nút được tạo kiểu của bạn.

<!DOCTYPE html>
<meta charset="utf-8">

<style>
    button {
        width            : 160px;
        height           : 30px;
        font-size        : 13px;
        border           : none;
        text-align       : center;
        background-color : #444;
        color            : #6f0;
    }
    button:active {
        background-color : #779;
    }
</style>

<button id="upload">Styled upload button!</button>

<script>

function Upload_On_Click(id, handler) {
    var hidden_input = null;
    document.getElementById(id).onclick = function() {hidden_input.click();}
    function setup_hidden_input() {
        hidden_input && hidden_input.parentNode.removeChild(hidden_input);
        hidden_input = document.createElement("input");
        hidden_input.setAttribute("type", "file");
        hidden_input.style.visibility = "hidden";
        document.querySelector("body").appendChild(hidden_input);
        hidden_input.onchange = function() {
            handler(hidden_input.files[0]);
            setup_hidden_input();
        };
    }
    setup_hidden_input();
}

Upload_On_Click("upload", function(file) {
    console.log("GOT FILE: " + file.name);
});

</script>

Lưu ý cách mã trên liên kết lại nó sau mỗi lần người dùng chọn một tệp. Điều này rất quan trọng vì "onchange" chỉ được gọi nếu người dùng thay đổi tên tệp. Nhưng bạn có thể muốn nhận tệp mỗi khi người dùng cung cấp.


1
Chính xác, labelcách tiếp cận không hoạt động, ngoại trừ nó không thể hiển thị tên hoặc đường dẫn tệp đã chọn. Vì vậy, nhất thiết phải nói, đó là vấn đề duy nhất người ta cần giải quyết.
Hassan Baig

4

Nhiều giải pháp tập tin với tên tệp được chuyển đổi

VÍ DỤ Bootstrap

HTML:

<div>
  <label class="btn btn-primary search-file-btn">
    <input name="file1" type="file" style="display:None;"> <span>Choose file</span>
  </label>
  <span>No file selected</span>
</div>

<div>
  <label class="btn btn-primary search-file-btn">
    <input name="file2" type="file" style="display:None;"> <span>Choose file</span>
  </label>
  <span>No file selected</span>
</div>

1. JS với jQuery:

$().ready(function($){
    $('.search-file-btn').children("input").bind('change', function() {
    var fileName = '';
    fileName = $(this).val().split("\\").slice(-1)[0];
    $(this).parent().next("span").html(fileName);
  })
});

2. JS không có jQuery

Array.prototype.forEach.call(document.getElementsByTagName('input'), function(item) {
  item.addEventListener("change", function() {
    var fileName = '';
    fileName = this.value.split("\\").slice(-1)[0];
    this.parentNode.nextElementSibling.innerHTML = fileName;
  });
});

3

Đây là một giải pháp, cũng hiển thị tên tệp đã chọn: http://jsfiddle.net/raft9pg0/1/

HTML:

<label for="file-upload" class="custom-file-upload">Chose file</label>
<input id="file-upload" type="file"/>
File: <span id="file-upload-value">-</span>

JS:

$(function() {
    $("input:file[id=file-upload]").change(function() {
        $("#file-upload-value").html( $(this).val() );
    });
});

CSS:

input[type="file"] {
    display: none;
}

.custom-file-upload {
      background: #ddd;
      border: 1px solid #aaa;
      border-top: 1px solid #ccc;
      border-left: 1px solid #ccc;
      -moz-border-radius: 3px;
      -webkit-border-radius: 3px;
      border-radius: 3px;
      color: #444;
      display: inline-block;
      font-size: 11px;
      font-weight: bold;
      text-decoration: none;
      text-shadow: 0 1px rgba(255, 255, 255, .75);
      cursor: pointer;
      margin-bottom: 20px;
      line-height: normal;
      padding: 8px 10px; }

Làm thế nào để chỉ hiển thị tên tệp chứ không phải fakepathđường dẫn?
Hassan Baig

3

Tuần này tôi cũng cần tùy chỉnh nút và hiển thị tên tệp đã chọn sang một bên, vì vậy sau khi đọc một số câu trả lời ở trên (Cảm ơn BTW) tôi đã đưa ra cách thực hiện sau:

HTML:

<div class="browse">
<label id="uploadBtn" class="custom-file-upload">Choose file
<input type="file" name="fileInput" id="fileInput" accept=".yaml" ngf-select ngf-change="onFileSelect($files)" />
</label>
<span>{{fileName}}</span>
</div>

CSS

   input[type='file'] {
    color: #a1bbd5;
    display: none;

}

.custom-file-upload {
    border: 1px solid #a1bbd5;
    display: inline-block;
    padding: 2px 8px;
    cursor: pointer;
}

label{
    color: #a1bbd5;
    border-radius: 3px;
}

Javascript (góc cạnh)

app.controller('MainCtrl', function($scope) {

        $scope.fileName = 'No file chosen';

          $scope.onFileSelect = function ($files) {
          $scope.selectedFile = $files;
          $scope.fileName = $files[0].name;
    };
});

Về cơ bản, tôi đang làm việc với lib tải lên tập tin, Angular-khôn ngoan Tôi ràng buộc tên tệp với phạm vi $ của tôi và đặt cho nó giá trị ban đầu là 'Không có tệp nào được chọn', tôi cũng liên kết hàm onFileSelect () với phạm vi của tôi vì vậy khi một tệp được chọn, tôi nhận được tên tệp bằng cách sử dụng API ng-upload và gán nó cho $ scope.filename.


3

Đơn giản chỉ cần mô phỏng một lần nhấp vào <input>bằng cách sử dụng trigger()chức năng khi nhấp vào một kiểu <div>. Tôi đã tạo nút riêng của mình trong số a <div>và sau đó kích hoạt nhấp chuột inputkhi nhấp vào <div>. Điều này cho phép bạn tạo nút của mình theo bất kỳ cách nào bạn muốn bởi vì đó là <div>và mô phỏng một lần nhấp vào tệp của bạn <input>. Sau đó sử dụng display: nonetrên của bạn <input>.

// div styled as my load file button
<div id="simClick">Load from backup</div>

<input type="file" id="readFile" />

// Click function for input
$("#readFile").click(function() {
    readFile();
});

// Simulate click on the input when clicking div
$("#simClick").click(function() {
    $("#readFile").trigger("click");
});

3

Cách tốt nhất là sử dụng phần tử giả: after hoặc: before như một phần tử vượt qua đầu vào de. Sau đó, phong cách mà yếu tố giả như bạn muốn. Tôi khuyên bạn nên làm theo kiểu chung cho tất cả các tệp đầu vào như sau:

input {
  height: 0px;
  outline: none;
}

input[type="file"]:before {
  content: "Browse";
  background: #fff;
  width: 100%;
  height: 35px;
  display: block;
  text-align: left;
  position: relative;
  margin: 0;
  margin: 0 5px;
  left: -6px;
  border: 1px solid #e0e0e0;
  top: -1px;
  line-height: 35px;
  color: #b6b6b6;
  padding-left: 5px;
  display: block;
}

3

Cách tốt nhất tôi đã tìm thấy là có một input type: filethiết lập sau đó display: none. Cho nó một cái id. Tạo một nút hoặc bất kỳ yếu tố nào khác mà bạn muốn mở đầu vào tệp.

Sau đó thêm một trình lắng nghe sự kiện vào nó (nút) mà khi nhấp vào sẽ mô phỏng một lần nhấp vào đầu vào tệp gốc. Giống như nhấp vào một nút có tên hello nhưng nó sẽ mở ra một cửa sổ tập tin.

Mã ví dụ

//i am using semantic ui

<button class="ui circular icon button purple send-button" id="send-btn">
      <i class="paper plane icon"></i>
    </button>
  <input type="file" id="file" class="input-file" />

javascript

var attachButton=document.querySelector('.attach-button');
    attachButton.addEventListener('click', e=>{
        $('#file').trigger("click")
    })

2

Css có thể làm rất nhiều ở đây ... với một chút mánh khóe ...

<div id='wrapper'>
  <input type='file' id='browse'>
</div>

#wrapper {
     width: 93px; /*play with this value */
     height: 28px; /*play with this value */
     background: url('browseBtn.png') 0 0 no-repeat;
     border:none;
     overflow:hidden;
}

#browse{
     margin-left:-145px; /*play with this value */
     opacity:0; /* set to .5 or something so you can better position it as an overlay then back to zero again after you're done */
     -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
     filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
}

:: tham khảo :: http://site-o-matic.net/?viewpost=19

-beyey


2

Tôi đã tìm thấy một phương pháp rất dễ dàng để chuyển nút tập tin thành hình ảnh. Bạn chỉ cần gắn nhãn một hình ảnh và đặt nó trên đầu nút tập tin.

<html>
<div id="File button">
    <div style="position:absolute;">
        <!--This is your labeled image-->
        <label for="fileButton"><img src="ImageURL"></label>
    </div>
    <div>
        <input type="file" id="fileButton"/>
    </div>
</div>
</html>

Khi nhấp vào hình ảnh được dán nhãn, bạn chọn nút tập tin.


2

Chỉ có cách tiếp cận này cung cấp cho bạn toàn bộ sự linh hoạt! ES6 / VanillaJS!

html:

<input type="file" style="display:none;"></input>
<button>Upload file</button>

javascript:

document.querySelector('button').addEventListener('click', () => {
  document.querySelector('input[type="file"]').click();
});

Điều này ẩn nút tập tin đầu vào, nhưng dưới mui xe nhấp vào nó từ một nút bình thường khác, rõ ràng bạn có thể tạo kiểu như bất kỳ nút nào khác. Đây là giải pháp duy nhất không có nhược điểm nào ngoài nút DOM vô dụng. Nhờ display:none;, nút đầu vào không dành bất kỳ không gian hiển thị nào trong DOM.

(Tôi không biết ai sẽ tặng đạo cụ cho việc này nữa. Nhưng tôi đã có ý tưởng đó từ đâu đó trên Stackoverflow.)

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.