Câu hỏi Làm thế nào để phát hiện khi hủy bỏ được nhấp vào đầu vào tập tin?


Làm thế nào tôi có thể phát hiện khi người dùng hủy bỏ một đầu vào tập tin bằng cách sử dụng một đầu vào tập tin html?

onChange cho phép tôi phát hiện khi họ chọn một tệp, nhưng tôi cũng muốn biết khi nào họ hủy (đóng hộp thoại chọn tệp mà không chọn bất kỳ thứ gì).


76
2018-01-07 17:46


gốc




Các câu trả lời:


Trong khi không phải là giải pháp trực tiếp, và cũng xấu ở chỗ nó chỉ (theo như tôi đã thử nghiệm) làm việc với onfocus (yêu cầu chặn sự kiện khá hạn chế), bạn có thể đạt được điều đó như sau:

document.body.onfocus = function(){ /*rock it*/ }

Điều thú vị về điều này là bạn có thể đính kèm / tháo gỡ nó kịp thời với sự kiện tệp và nó cũng có vẻ hoạt động tốt với các đầu vào bị ẩn (một điều kiện xác định nếu bạn đang sử dụng giải pháp trực quan cho loại đầu vào mặc định crappy = ' tập tin'). Sau đó, bạn chỉ cần tìm ra nếu giá trị đầu vào thay đổi.

Một ví dụ:

var godzilla = document.getElementById('godzilla')

godzilla.onclick = charge

function charge()
{
    document.body.onfocus = roar
    console.log('chargin')
}

function roar()
{
    if(godzilla.value.length) alert('ROAR! FILES!')
    else alert('*empty wheeze*')
    document.body.onfocus = null
    console.log('depleted')
}

Xem nó trong hành động: http://jsfiddle.net/Shiboe/yuK3r/6/

Đáng buồn thay, nó chỉ có vẻ làm việc trên các trình duyệt webkit. Có thể ai đó khác có thể tìm ra giải pháp firefox / IE


32
2018-04-01 05:38



tiếc là điều này dường như không hoạt động trong safari di động - gabriele.genta
Tôi không muốn sự kiện tập trung bắn mỗi lần, vì vậy tôi muốn sử dụng addEventListener("focus",fn,{once: true}). Tuy nhiên tôi không thể làm cho nó cháy hết document.body.addEventListener.. Tôi không biết tại sao. Thay vào đó tôi nhận được kết quả tương tự window.addEventListener. - WoodenKitty
Nó hoạt động trong FF trên Ubuntu, nhưng không hoạt động trên Windows. Lạ thật ... - Piotr Kowalski
Không hoạt động mọi lúc. Đã thử trên Chrome / Windows. - Aviator
Điều này không làm việc trong Firefox và Edge cho tôi. Tuy nhiên, lắng nghe mousemove sự kiện trên window.document  ngoài ra lắng nghe focus trên window dường như làm việc ở khắp mọi nơi (ít nhất là trong các trình duyệt hiện đại, tôi không quan tâm đến những xác tàu trong thập kỷ qua). Về cơ bản, bất kỳ sự kiện tương tác nào cũng có thể được sử dụng cho tác vụ này bị chặn bởi một hộp thoại mở tệp đang mở. - John Weisz


Bạn không thể.

Kết quả của hộp thoại tệp không được hiển thị cho trình duyệt.


17
2018-01-07 17:47



Có thể kiểm tra xem trình chọn tệp có mở không? - Ppp
@ Ppp - Không. Trình duyệt không cho bạn biết điều đó. - Oded
"Kết quả của hộp thoại tập tin không được hiển thị cho trình duyệt." Điều này không đúng nếu hộp thoại bị đóng bằng cách chọn một tệp. - Trevor
Các thay đổi được kích hoạt bằng cách sử dụng hộp thoại tệp được hiển thị với trình duyệt. Hãy xem, nếu không có tệp nào được chọn, và không có tệp nào được chọn sau đó, thì không có gì thay đổi, do đó không có change sự kiện được gửi đi. - John Weisz
Ngoài ra, nếu một tệp đã được chọn và bạn chọn lại cùng một tệp, không change sự kiện được gửi đi cho một trong hai. - Patrick Roberts


/* Tested on Google Chrome */
$("input[type=file]").bind("change", function() {
    var selected_file_name = $(this).val();
    if ( selected_file_name.length > 0 ) {
        /* Some file selected */
    }
    else {
        /* No file selected or cancel/close
           dialog button clicked */
        /* If user has select a file before,
           when they submit, it will treated as
           no file selected */
    }
});

7
2017-10-26 19:01



Bạn đã kiểm tra xem else tuyên bố bao giờ được đánh giá? - jayarjo
theo như tôi nhớ khi tôi viết câu trả lời này, nếu người dùng chọn tệp và sau đó chọn lại tệp (nhưng sau đó hủy), nó sẽ được coi là không có tệp nào được chọn, tôi chỉ sử dụng cảnh báo ở biến selected_file_name để kiểm tra. dù sao, chưa thử nghiệm nó nữa kể từ đó. - Rizky K.
Tôi có thể nói, sau khi kiểm tra trình duyệt chéo, Firefox không kích hoạt sự kiện thay đổi khi hủy, cũng như không xóa các tệp hiện có được chọn nếu mở lại và hủy nhấp lần thứ hai. Lạ thật, eh? - mix3d


Khi bạn chọn một tệp và nhấp vào mở / hủy, input yếu tố nên mất tập trung aka blur. Giả sử ban đầu value của input trống, mọi giá trị không trống trong blur xử lý sẽ chỉ ra một OK, và một giá trị rỗng có nghĩa là một Cancel.

CẬP NHẬT: The blur không được kích hoạt khi input bị ẩn. Vì vậy, không thể sử dụng thủ thuật này với tải lên dựa trên IFRAME, trừ khi bạn muốn tạm thời hiển thị input.


6
2017-12-19 22:13



Trong Firefox 10 beta và Chrome 16, blur không được kích hoạt khi bạn chọn một tệp. Chưa thử trong các trình duyệt khác. - Blaise
Điều đó không hoạt động - làm mờ đầu vào được kích hoạt ngay lập tức sau khi nhấp chuột. Chrome 63.0.3239.84 x64 trên Win7. - Qwertiy


Bạn có thể bị hủy nếu bạn chọn cùng một tệp như trước đây và bạn bấm hủy: trong trường hợp này.

Bạn có thể làm như sau:

<input type="file" id="myinputfile"/>
<script>
document.getElementById('myinputfile').addEventListener('change', myMethod, false);
function myMethod(evt) {
  var files = evt.target.files; 
  f= files[0];
  if (f==undefined) {
     // the user has clicked on cancel
  }
  else if (f.name.match(".*\.jpg")|| f.name.match(".*\.png")) {
     //.... the user has choosen an image file
     var reader = new FileReader();
     reader.onload = function(evt) { 
        try {
        myimage.src=evt.target.result;
            ...
         } catch (err) {
            ...
         }
     };
  }     
  reader.readAsDataURL(f);          
</script>

5
2017-12-15 00:50



Thnkx @loveJs bài đăng này thực sự đã giúp tôi. - VPK
Không chính xác, nếu người dùng chọn cùng một tệp thì đó không phải là hủy = ( - Tiago Peres França
onchange chỉ kích hoạt nếu có thay đổi. Vì vậy, nếu tập tin là cùng một tập tin như trước người nghe onchange sẽ không cháy. - Shane
Bạn có thể xóa lựa chọn đầu vào (input.value = '') sau khi bạn phát hiện thay đổi đầu tiên, do đó lần thay đổi thứ hai sẽ kích hoạt ngay cả khi người dùng chọn lại cùng một tệp. - Chris
@CodeGems nó được phép lập trình input.value thành một chuỗi rỗng. Nhưng bạn có quyền thiết lập nó cho bất kỳ giá trị nào khác không được phép. - Chris


Chỉ cần nghe sự kiện nhấp chuột.

Theo ví dụ của Shiboe, đây là một ví dụ jQuery:

var godzilla = $('#godzilla');
var godzillaBtn = $('#godzilla-btn');

godzillaBtn.on('click', function(){
    godzilla.trigger('click');
});

godzilla.on('change click', function(){

    if (godzilla.val() != '') {
        $('#state').html('You have chosen a Mech!');    
    } else {
        $('#state').html('Choose your Mech!');
    }

});

Bạn có thể thấy nó hoạt động ở đây: http://jsfiddle.net/T3Vwz


5
2018-06-25 16:33



Tôi đã thử nghiệm trên Chrome 51, nó không hoạt động trong lần đầu tiên bạn chọn tệp. Giải pháp là thêm độ trễ: jsfiddle.net/7jfbmunh - Benoit Blanchon
Fiddle của bạn không hoạt động với tôi - bằng Firefox 58.0.2 - barrypicker


Giải pháp của Shiboe sẽ là giải pháp tốt nếu nó hoạt động trên webkit di động, nhưng không. Những gì tôi có thể đưa ra là thêm một trình nghe sự kiện mousemove vào một số đối tượng dom tại thời điểm cửa sổ nhập tệp được mở, như sau:

 $('.upload-progress').mousemove(function() {
        checkForFiles(this);
      });
      checkForFiles = function(me) {
        var filefield = $('#myfileinput');
        var files = filefield.get(0).files;
        if (files == undefined || files[0] == undefined) $(me).remove(); // user cancelled the upload
      };

Sự kiện mousemove bị chặn khỏi trang trong khi hộp thoại tệp đang mở và khi hộp thoại đóng của nó kiểm tra xem có bất kỳ tệp nào trong đầu vào tệp hay không. Trong trường hợp của tôi, tôi muốn một chỉ báo hoạt động chặn mọi thứ cho đến khi tệp được tải lên, vì vậy tôi chỉ muốn xóa chỉ báo của mình khi hủy.

Tuy nhiên điều này không giải quyết cho điện thoại di động, vì không có con chuột để di chuyển. Giải pháp của tôi có ít hơn hoàn hảo, nhưng tôi nghĩ rằng nó đủ tốt.

       $('.upload-progress').bind('touchstart', function() {
        checkForFiles(this);
      });

Bây giờ chúng tôi đang lắng nghe một liên lạc trên màn hình để thực hiện kiểm tra cùng một tệp. Tôi khá tự tin rằng ngón tay của người dùng sẽ được đặt trên màn hình khá nhanh chóng sau khi hủy và loại bỏ chỉ báo hoạt động này.

Người ta cũng có thể thêm chỉ báo hoạt động vào sự kiện thay đổi đầu vào tệp, nhưng trên thiết bị di động thường có độ trễ vài giây giữa việc chọn hình ảnh và kích hoạt sự kiện thay đổi, vì vậy chỉ UX tốt hơn nhiều cho chỉ báo hoạt động được hiển thị tại bắt đầu quá trình.


2
2018-01-17 04:59





Hầu hết các giải pháp này không phù hợp với tôi.

Vấn đề là bạn không bao giờ biết được sự kiện nào sẽ được kích hoạt nắm tay, Là nó click hoặc là nó change? Bạn không thể giả định bất kỳ thứ tự nào, bởi vì nó có thể phụ thuộc vào việc thực hiện của trình duyệt.

Ít nhất là trong Opera và Chrome (cuối năm 2015) click được kích hoạt ngay trước khi nhập 'điền' với các tệp, vì vậy bạn sẽ không bao giờ biết độ dài của files.length != 0 cho đến khi bạn trì hoãn click được kích hoạt sau change.

Đây là mã:

var inputfile = $("#yourid");

inputfile.on("change click", function(ev){
    if (ev.originalEvent != null){
        console.log("OK clicked");
    }
    document.body.onfocus = function(){
        document.body.onfocus = null;
        setTimeout(function(){
            if (inputfile.val().length === 0) console.log("Cancel clicked");
        }, 1000);
    };
});

2
2018-01-07 19:32