我100%确定此代码有效,但在一个特殊情况下失败 - 花了一个小时来找到错误(无法在JSFiddle上重现它)。最后我找到了原因,但我不知道为什么会这样。它只在我隐藏文件输入时才会发生,结果是:无论选择和更改我更改第一个标签的文件,请看一下:
var activateFileSelection = function( container ) {
var container = container || $('body');
container.find(':file').each(function(i) {
var thisInput = $(this);
var thisLabel = thisInput.siblings('label');
if (thisLabel.length > 0 && !thisLabel.hasClass('file-input-label')) {
var thisLabelDefaultText = thisLabel.html();
thisLabel.addClass('file-input-label');
thisInput.on('change', function(e) {
if (thisInput.val()) {
thisLabel.html(thisInput.val());
} else {
thisLabel.html(thisLabelDefaultText);
};
});
};
});
};
activateFileSelection();
input {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<label for="myfile">select 1</label>
<input id="myfile" type="file" />
</div>
<div>
<label for="myfile">select 2</label>
<input id="myfile" type="file" />
</div>
<div>
<label for="myfile">select 3</label>
<input id="myfile" type="file" />
</div>
同样在JSFiddle。
如果输入未被隐藏,一切正常:fiddle。
如下面提到的nevermind,重复的输入ID可能会出现问题,仍然在脚本中我没有解决和ID。此外,每个文件输入的更改会触发标签文本的更改,但错误的更改。
答案 0 :(得分:6)
HTML代码的布局可能表明每个标签都链接到它旁边的输入字段,但事实并非如此。由于三个标签的for
属性为"myfile"
,因此所有三个标签实际上都链接到第一个输入字段,即document.getElementById("myfile")
找到的字段。
因此,当您单击任何标签时,将使用第一个输入字段。然后,在文件选择后更新代码中使用thisInput.siblings('label')
获得的相邻标签。即使3个输入字段可见,也是如此。
另一方面,如果直接在输入字段上单击,则使用该输入字段并更新相应的标签。
以下代码段向控制台发送消息,指示使用了哪个文件输入。
var activateFileSelection = function (container) {
var container = container || $('body');
container.find(':file').each(function (i) {
var thisInput = $(this);
var thisLabel = thisInput.siblings('label');
if (thisLabel.length > 0 && !thisLabel.hasClass('file-input-label')) {
var thisLabelDefaultText = thisLabel.html();
thisLabel.addClass('file-input-label');
thisInput.on('change', function (e) {
console.log("Input used: " + thisInput.data("field"));
if (thisInput.val()) {
thisLabel.html(thisInput.val());
} else {
thisLabel.html(thisLabelDefaultText);
};
});
};
});
};
activateFileSelection();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Test by clicking on label 3 vs clicking on input field 3:</p>
<div>
<label for="myfile">select 1</label>
<input id="myfile" type="file" data-field="input1" />
</div>
<div>
<label for="myfile">select 2</label>
<input id="myfile" type="file" data-field="input2" />
</div>
<div>
<label for="myfile">select 3</label>
<input id="myfile" type="file" data-field="input3" />
</div>
答案 1 :(得分:0)
我替换了标签
的事件根据我们的需要触发。
var activateFileSelection = function (container) {
var container = container || $('body');
container.find(':file').each(function (i) {
var thisInput = $(this);
var thisLabel = thisInput.siblings('label');
if (thisLabel.length > 0 && !thisLabel.hasClass('file-input-label')) {
var thisLabelDefaultText = thisLabel.html();
thisLabel.addClass('file-input-label');
thisLabel.on("click", function (e) {
thisInput.trigger("click");
e.preventDefault()
});
thisInput.on('change',thisLabel, function () {
console.log("Input used: " + thisInput.data("field"));
if (thisInput.val()) {
thisLabel.html(thisInput.val());
} else {
thisLabel.html(thisLabelDefaultText);
};
});
};
});
};
activateFileSelection();