Подія вибору файлу введення HTML не запускається при виборі одного файлу


204

Чи є можливість виявити кожен вибір файлу, який користувач здійснив для елемента inputтипу HTML file?

Про це запитували багато разів, але зазвичай запропонована onchangeподія не спрацьовує, якщо користувач знову вибере той самий файл.


7
Чи повинен ваш код також спрацьовувати, якщо користувач натисне "Скасувати"? Очікується, що натискання кнопки Скасувати нічого не призведе, і я думаю, що більшість користувачів надалі очікують, що повторний вибір того самого файлу матиме такий же ефект, як і Скасувати. Я не знаю, чи можливо це чи ні, але я пропоную вам все-таки переглянути цю конструкцію.
KRyan

1
При скасуванні він не повинен стріляти або робити його інакше помітним. Мається на увазі більше видалення інтерфейсу інтерфейсу користувача: Якщо після вибору файлу викликається деяка дія, користувач зазвичай очікує, що дія повториться, якщо він знову вибере файл.
дрон

Можливо, у нас може бути така поведінка, якщо ми встановимо inputзначення s на '', зробивши щось із файлом. Але це також видалить видиме ім'я файлу. Однак це може бути нормально, оскільки файл насправді обробляється, а результат цієї дії може з’явитися десь в іншому місці.
дрон

Plz Поясніть Que, що ви хочете зробити?
Чемпіль

1
Все, що я хочу, - це імітувати старі шкільні програми поведінки. Якщо я знову "відкрию" той самий файл у додатку для настільних ПК, він зазвичай завантажується, або якщо з файлом робиться якась дія (наприклад, перетворення його в інший формат, наприклад), ця дія робиться знову. Це те, чого користувачі настільних комп'ютерів також можуть очікувати від веб-програми, але подія fileвведення onchangeне нагадує.
дрон

Відповіді:


278

Встановіть значення inputдля nullкожної onclickподії. Це скине значення input's і призведе до запуску onchangeподії, навіть якщо обраний той самий шлях.

input.onclick = function () {
    this.value = null;
};

input.onchange = function () {
    alert(this.value);
};​

Ось DEMO .

Примітка. Це нормально, якщо ваш файл має префікс "C: \ fakepath \". Це функція безпеки, яка не дозволяє JavaScript знати абсолютний шлях файлу. Браузер все ще знає це внутрішньо.


1
Я спробував демонстрацію, але (використовуючи Chrome 21) я продовжую отримувати `C: \ fakepath` +, а потім вибране ім'я файлу (виключаючи шлях). Однак попередження відображається на кожному виборі одного файлу.
Джаспер де Вріс

1
@JasperdeVries Це функція безпеки, яка не дозволяє JavaScript знати абсолютний шлях файлу. Браузер все ще знає шлях внутрішньо.
Брайан Усташ

1
Як і в сторону, null - єдине дозволене значення для <input type = "file">. Тож якщо ви намагаєтесь встановити його на невизначене і отримувати виняток, то це причина.
Ноель Абрахамс

5
Він не працює в IE11, якщо ви не внесете невеликі зміни: демонстрація .

21
Краще поставити його this.value = nullв кінці, onchangeоскільки можна вводити елемент введення, не клацаючи на ньому (за допомогою клавіатури). Ви можете зберігати, input.filesякщо вам потрібно буде посилатися на нього пізніше.
Хелсіон

24
<form enctype='multipart/form-data'>
    <input onchange="alert(this.value); this.value=null; return false;" type='file'>
    <br>
    <input type='submit' value='Upload'>
</form>

this.value=null; потрібен лише для Chrome, Firefox буде добре працювати просто return false;

Ось ПЕРЕДАЧА


2
простий та ефективний щойно перевірений в останніх IE та хромах та працює як шарм. Дякуємо за те, що поділилися ним
Atul Chaudhary

8

У цій статті під заголовком "Використання введення форми для вибору"

http://www.html5rocks.com/en/tutorials/file/dndfiles/

<input type="file" id="files" name="files[]" multiple />

<script>
function handleFileSelect(evt) {

    var files = evt.target.files; // FileList object

    // files is a FileList of File objects. List some properties.
    var output = [];
    for (var i = 0, f; f = files[i]; i++) {
     // Code to execute for every file selected
    }
    // Code to execute after that

}

document.getElementById('files').addEventListener('change', 
                                                  handleFileSelect, 
                                                  false);
</script>

Він додає слухача подій до "зміни", але я перевірив це, і він спрацьовує, навіть якщо ви вибрали той самий файл, а не, якщо ви скасуєте.


Враховуючи потенційно неоднозначне значення "зміни" в цьому випадку, ви спробували це в декількох браузерах? Ви можете вказати, на які саме ви спробували в Інтернеті, але браузери не завжди згодні з цим питанням.
Thor84no

2
Яке середовище ви використовуєте для свого тесту? Мій досвід роботи з Chrome був таким, про який я говорив у запитанні, changeподія запуститься лише при зміні назви файлів.
дрон

7

Використовуйте подію onClick, щоб очистити значення цільового вводу кожного разу, коли користувач клацає на полі. Це гарантує, що подія onChange буде запущена і для того ж файлу. Для мене працювали :)

onInputClick = (event) => {
    event.target.value = ''
}

<input type="file" onChange={onFileChanged} onClick={onInputClick} />

Використання TypeScript

onInputClick = ( event: React.MouseEvent<HTMLInputElement, MouseEvent>) => {
    const element = event.target as HTMLInputElement
    element.value = ''
}

Дякую за рішення.
Deepak Tekchandani

1

Робіть все, що ви хочете зробити після успішного завантаження файлу. Просто після завершення обробки файлу встановіть значення керування файлом на порожній рядок. тому. наприклад, ти можеш зробити цю справу і працював на мене як на шарм

   $('#myFile').change(function () {
       LoadFile("myFile");//function to do processing of file.
       $('#myFile').val('');// set the value to empty of myfile control.
    });

1
handleChange({target}) {
    const files = target.files
    target.value = ''
}

1
Привіт, курс! Відповіді, що стосуються лише коду, можуть вирішити проблему, але вони набагато корисніші, якщо ви поясните, як вони її вирішують. Спільнота вимагає теорії, а також коду, щоб повністю зрозуміти вашу відповідь.
RBT

Хоча цей код може вирішити питання, включаючи пояснення, як і чому це вирішує проблему, справді допоможе покращити якість вашої публікації та, ймовірно, призведе до збільшення кількості голосів. Пам'ятайте, що ви відповідаєте на запитання читачів у майбутньому, а не лише про людину, яка зараз задає питання. Будь ласка, відредагуйте свою відповідь, щоб додати пояснення та вказати, які обмеження та припущення застосовуються. З огляду
подвійний звуковий сигнал

1

Очищення значення 0-го індексу введення працювало для мене . Спробуйте скористатись наведеним нижче кодом, сподівайтеся, що це спрацює (AngularJs).

          scope.onClick = function() {
            input[0].value = "";
                input.click();
            };
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.