我的问题有点复杂,因为我正在使用动态用ajax加载内容的窗口上工作。
我正在尝试实现this solution(样式和自定义文件输入)
我有两个带有标签的文件输入(一个简单,另一个是多个)
<form id="my_form" action="/" method="post" enctype="multipart/form-data">
<!-- Elements inside <form> are loaded with ajax -->
<input type="file" id="photos" data-name="photos" name="photos[]" multiple="multiple" style="margin-top:15px;" class="inputfile inputfile-photos" data-multiple-caption="{count} files selected">
<label class="btn btn-sm btn-outline-primary d-block" for="photos" style="max-width: 250px;overflow: hidden;text-overflow: ellipsis;text-transform: initial;"><i class="icon-upload"></i> <span>Choose files…</span></label>
<input type="file" name="file-agrement" id="file-agrement" class="inputfile inputfile-agrement" accept=".pdf, .jpeg, .jpg, .png"/>
<label class="btn btn-sm btn-outline-primary d-block" for="file-agrement" style="max-width: 250px;overflow: hidden;text-overflow: ellipsis;text-transform: initial;"><i class="icon-upload"></i> <span>Choose file…</span></label>
</form>
我有这个JS代码,如果唯一,则将标签文本替换为文件名;如果多个,则选择n个文件
所有js代码都位于ajax中。get函数回调;这就是为什么我不能$input.on( 'change', function( e ) {
而被迫做$(document).on( 'change', $input, function( e ) {
$( '#my_form .inputfile' ).each( function() {
var $input = $( this );
var $label = $input.next( 'label' );
var labelVal = $label.html();
$(document).on( 'change', $input, function( e ) {
/* first issue: these two things give different values */
console.debug({'$input.val()': $input.val()});
console.debug({'e.target.value': e.target.value});
var fileName = '';
if( $input.prop('files') && $input.prop('files').length > 1 ) {
fileName = ( $input.attr( 'data-multiple-caption' ) || '' ).replace( '{count}', $input.prop('files').length );
}
else if( $input.prop('files') ) {
fileName = e.target.value.split( '\\' ).pop();
}
if( fileName ) {
$label.find( 'span' ).html( fileName );
}
else {
$label.html( labelVal );
}
});
/* Firefox bug fix */
$input
.on( 'focus', function(){ $input.addClass( 'has-focus' ); })
.on( 'blur', function(){ $input.removeClass( 'has-focus' ); });
});
这里的问题是两个标签上的标签文本都被替换,并且只有一个更改时,更改事件似乎在每个输入上触发。
我尝试了很多事情,但是每次都“更改”或仅第一个更改,例如以下示例:
var inputs = document.querySelectorAll( '#my_form .inputfile' );
Array.prototype.forEach.call( inputs, function( input )
{
var label = input.nextElementSibling,
labelVal = label.innerHTML;
input.addEventListener( 'change', function( e )
{
var fileName = '';
if( this.files && this.files.length > 1 )
fileName = ( this.getAttribute( 'data-multiple-caption' ) || '' ).replace( '{count}', this.files.length );
else
fileName = e.target.value.split( '\\' ).pop();
if( fileName )
label.querySelector( 'span' ).innerHTML = fileName;
else
label.innerHTML = labelVal;
});
});
在这里,只有#photos输入更改事件被触发,而从没有#file-agrement。
我什至尝试将所有代码移出foreach循环,并尝试在每个输入上“手动”进行操作,但是同样发生了;要么只有第一个“更改”,要么两者都有...
这是我尝试过的其他事情:
$photos = $('#my_form .inputfile#photos');
$agrement = $('#my_form .inputfile#file-agrement');
$(document).on( 'change', $photos, function( e ) {
console.log('change');
var $label = $photos.next( 'label' );
var labelVal = $label.html();
var fileName = '';
if ( $photos.prop('files') && $photos.prop('files').length > 1 ) {
fileName = ( $photos.attr( 'data-multiple-caption' ) || '' ).replace( '{count}',$photos.prop('files').length );
}
else if ( $photos.prop('files') ) {
fileName = e.target.value.split( '\\' ).pop();
}
if( fileName ) {
$label.find( 'span' ).html( fileName );
}
else {
$label.html( labelVal );
}
});
$(document).on( 'change', $agrement, function( e ) {
console.log('change');
var $label = $agrement.next( 'label' );
var labelVal = $label.html();
var fileName = '';
if ( $agrement.prop('files') && $agrement.prop('files').length > 1 ) {
fileName = ( $agrement.attr( 'data-multiple-caption' ) || '' ).replace( '{count}',$agrement.prop('files').length );
}
else if ( $agrement.prop('files') ) {
fileName = e.target.value.split( '\\' ).pop();
}
if( fileName ) {
$label.find( 'span' ).html( fileName );
}
else {
$label.html( labelVal );
}
});