В настоящее время я работаю над небольшой вспомогательной утилитой. Этот подход представляет собой веб-приложение на странице, которое обычно загружается из локальной файловой системы. Это все работает. Внутри этого приложения мне нужно иметь возможность загружать и обрабатывать локальные файлы (сохранение и перезагрузка профиля). Это работает до сих пор, но у меня возникла проблема, когда я хотел бы попросить о помощи:
Я использую оболочку filereader.js вокруг API-интерфейса чтения файлов html5. Пока что все работает, я могу выбирать, читать и обрабатывать файл на странице. Большой! Я даже могу обрабатывать несколько файлов один за другим. Однако есть одна проблема, когда я не знаю, как начать ее отладку: я не могу прочитать конкретный файл во второй раз. Я могу выбрать его, конечно, но он не читается, поэтому не обрабатывается. Похоже, что API-интерфейс чтения файлов не генерируется вообще. Это может быть связано как с кешированием, так и с предыдущим использованием файла, который не был правильно закончен, я понятия не имею.
Вот соответствующий код:
Моя функция JS FileReader:
function FileReader( selector, options ) {
var options = $.extend({
clicked: function(){},
payload: function(){},
selected: function(){}
}, options||{} );
var widget = convert( selector );
var selector = widget.find( 'input:file');
function clicked( event ) {
event.stopPropagation();
// highlight button as user feedback
highlight();
// raise the file selection dialog
selector.click();
// signal action to element
options.clicked();
}
function convert( selector ) {
var widget = $( selector );
// create new content for widget
var hotspot = $( '<a class="hotspot">' + widget.html() + '</a>' ).bind( 'click', clicked );
var selector = $( '<input type="file" style="display:none;" />' );
// replace initial content of widget
widget.empty().append( $('<form />').append(selector).append(hotspot) );
widget.find( 'input:file' ).fileReaderJS( { accept: false,
readAsDefault: 'BinaryString',
on: { load: selected } } );
return widget;
}
function highlight() {
// flash button by changing the background color for 100 msecs
widget.css( 'background-color', 'whitesmoke' );
setTimeout( function(){ widget.css( 'background-color', 'transparent' ); }, 100 );
}
function selected( event, file ) {
// process payload
options.payload( event.target.result );
// signal event to controlling element
options.selected();
}
return {}
} // FileReader
Этот метод вызывается с '#wProfileImport'
как значением selector
аргументов, который фактически работает и преобразует разметку ниже
<span id="wProfileImport" class="control button">
<img src="assets/img/profile-import.png">
</span>
так что он содержит (скрытый) входной тег файла, который используется для запуска диалога выбора файла (который отлично работает):
<span id="wProfileImport" class="control button">
<form>
<input type="file" style="display:none">
</form>
<a class="hotspot">
<img src="assets/img/profile-import.png">
</a>
</span>
Теперь, когда вы нажимаете на изображение, вы выбираете локальный файл, и его содержимое передается на обратный вызов options.payload
. Как сказано все прекрасно и работает также для более чем одного файла один за другим. Единственная проблема, которая остается: возможность читать в том же файле снова. Никакое событие не запускается, содержимое не читается, ничего.
Поэтому мой вопрос: что мне нужно сделать процесс файла во второй раз, если он выбран пользователем?
Это связано с тем, как событие onchange
работает в JavaScript.
Если у вас есть ввод текста, и вы вводите слово, скажем, "bird"
. Вы не фокусируете поле, это вызовет событие onchange
. Если вы затем вернетесь в поле и измените слово, то без лишнего изменения его снова верните в "bird"
а затем не onchange
событие onchange
которое не будет срабатывать, потому что значение не изменилось.
Однако другие события, такие как onkeydown
и onfocus
будут срабатывать.
Посмотрите, можете ли вы найти другое событие, которое вы можете использовать. Может быть, onclick
или onfocus
. Я боюсь, что этот огонь слишком рано.
Обходной путь для уничтожения input
после того, как вы прочитаете файл и сделаете новый в нем. Таким образом, если пользователь выбирает один и тот же файл, он снова будет считаться в качестве onchange
.
Другая возможность - не использовать событие onchange
но выполнить этот процесс после нажатия кнопки отправки. Вы можете получить ссылку на файл с помощью:
var file = document.getElementById("#the_file_input").files[0];
A.ext
, ваш JavaScript выполняет некоторую обработку. Пользователь снова выбирает файлA.ext
и ничего не происходит. Это верно?