javascript - 删除和重建文件输入时清除文件列表

标签 javascript jquery forms file file-io

在使用多个文件类型输入时控制我的文件列表时遇到一些麻烦。需要明确的是,我没有使用具有多个文件输入的文件输入,而是多个单个文件输入。场景是用户可以选择 1 到 5 个文件,如果需要,可以将它们全部清除,但仍然必须至少发送 1 个文件。所以我最多有五个文件输入,我将在表单上使用。对于初学者,我有两个我已经放入了一个 Fiddle 和一个 CodePen(出于某种原因,它们不像在我本地的那样工作)。用户选择一个文件,该文件和大小被添加到一个单独的列表中,该列表显示名称和大小,并有一个按钮附加到调用 clearfileInput 函数的按钮。 clearFileInput 函数删除该文件输入(因为这似乎是真正删除文件的唯一方法,所以它不会被发送)我也需要它来清除列表。

CODEPEN HERE JS FIDDLE HERE

这是 HTML:

  <input type="file" name="filesToUpload" id="filesToUpload" onChange="makeFileList();" />
  <input type="file" name="filesToUpload" id="filesToUpload2" onChange="makeFileList2();" />

 <ul id="fileList"><li>No Files Selected</li></ul>
 <ul id="fileList2"><li>No Files Selected</li></ul>

我使用的脚本很长,因为我必须复制所有内容,但这是其中一个的完整脚本:

function makeFileList() {
    var input = document.getElementById("filesToUpload");
    var ul = document.getElementById("fileList");
    while (ul.hasChildNodes()) {
        ul.removeChild(ul.firstChild);
    }
    for (var i = 0; i < input.files.length; i++) {
        var li = document.createElement("li");
        var fileSize = input.files[i].size;
        li.innerHTML = input.files[i].name +"&nbsp;"+ "<span id=\"lblSize\"></span><input onclick=\"clearFileInput()\" type=\"button\" value=\"Clear\" \/>";
        ul.appendChild(li);
    }
    if(!ul.hasChildNodes()) {
        var li = document.createElement("li");
        li.innerHTML = 'No Files Selected';
        ul.appendChild(li);
    }
};
function makeFileList2() {
    var input = document.getElementById("filesToUpload2");
    var ul = document.getElementById("fileList2");
    while (ul.hasChildNodes()) {
        ul.removeChild(ul.firstChild);
    }
    for (var i = 0; i < input.files.length; i++) {
        var li = document.createElement("li");
        var fileSize = input.files[i].size;
        li.innerHTML = input.files[i].name +"&nbsp;"+"<span id=\"lblSize2\"></span><input onclick=\"clearFileInput2()\" type=\"button\" value=\"Clear\" \/>";
        ul.appendChild(li);
    }
    if(!ul.hasChildNodes()) {
        var li = document.createElement("li");
        li.innerHTML = 'No Files Selected';
        ul.appendChild(li);
    }
};
//Code Starts
$(document).ready(function() {
    $("#filesToUpload").change(function ()
    {
        var iSize = 0;
        if($.browser.msie)
        {
            var objFSO = new ActiveXObject("Scripting.FileSystemObject");
            var sPath = $("#filesToUpload")[0].value;
            var objFile = objFSO.getFile(sPath);
            var iSize = objFile.size;
            iSize = iSize/ 1024;
        }
        else
            iSize = ($("#filesToUpload")[0].files[0].size / 1024);

        if (iSize / 1024 > 1)
        {
            if (((iSize / 1024) / 1024) > 1)
            {
                iSize = (Math.round(((iSize / 1024) / 1024) * 100) / 100);
                $("#lblSize").html( iSize + "Gb");
            }
            else
            {
                iSize = (Math.round((iSize / 1024) * 100) / 100)
                $("#lblSize").html( iSize + "Mb");
            }
        }
        else
        {
            iSize = (Math.round(iSize * 100) / 100)
            $("#lblSize").html( iSize  + "kb");
        }
    });
    $("#filesToUpload2").change(function ()
    {
        var iSize2 = 0;
        if($.browser.msie)
        {
            var objFSO = new ActiveXObject("Scripting.FileSystemObject");
            var sPath = $("#filesToUpload2")[0].value;
            var objFile = objFSO.getFile(sPath);
            var iSize2 = objFile.size;
            iSize = iSize/ 1024;
        }
        else
            iSize2 = ($("#filesToUpload2")[0].files[0].size / 1024);

        if (iSize2 / 1024 > 1)
        {
            if (((iSize2 / 1024) / 1024) > 1)
            {
                iSize2 = (Math.round(((iSize2 / 1024) / 1024) * 100) / 100);
                $("#lblSize2").html( iSize2 + "Gb");
            }
            else
            {
                iSize2 = (Math.round((iSize2 / 1024) * 100) / 100)
                $("#lblSize2").html( iSize2 + "Mb");
            }
        }
        else
        {
            iSize2 = (Math.round(iSize2 * 100) / 100)
            $("#lblSize2").html( iSize2  + "kb");
        }
    });
});
function clearFileInput(){
    var oldInput = document.getElementById("filesToUpload");
    var newInput = document.createElement("input");
    newInput.type = "file";
    newInput.id = oldInput.id;
    newInput.name = oldInput.name;
    newInput.className = oldInput.className;
    newInput.style.cssText = oldInput.style.cssText;
    newInput.setAttribute("onclick", "makeFileList()");
    oldInput.parentNode.replaceChild(newInput, oldInput);
};
function clearFileInput2(){
    var oldInput = document.getElementById("filesToUpload2");
    var newInput = document.createElement("input");
    newInput.type = "file";
    newInput.id = oldInput.id;
    newInput.name = oldInput.name;
    newInput.className = oldInput.className;
    newInput.style.cssText = oldInput.style.cssText;
    newInput.setAttribute("onclick", "makeFileList2()");
    oldInput.parentNode.replaceChild(newInput, oldInput);
}

最佳答案

好的,我们先解决比较简单的问题。删除/重新创建文件输入。这是从深入到 SO 的存档问题中得到的...

不要手动复制输入,而是使用 jquery 的本地克隆功能,因为它也可以选择保留所有事件处理程序。如下...

var upload1 = $('#fileUpload');
upload1.replaceWith( upload1 = upload1.clone( true ) );
//passing true to .clone persists all event handlers

至于其余部分,您可能可以通过在 html 中添加一些非标准属性并以它们为目标而不是通过 id 来进一步简化它(并且必须复制您的 JS 5 次。)

<input type="file" name="filesToUpload" id="filesToUpload" onChange="makeFileList();" />
<input type="file" name="filesToUpload" id="filesToUpload2" onChange="makeFileList2();" />

<ul class="fileList" fileUploadId="filesToUpload"><li>No Files Selected</li></ul>
<ul class="fileList" fileUploadId="filesToUpload2"><li>No Files Selected</li></ul>

这里我们使用精简的 JS

$(document).ready(function() {
    $('[name="filesToUpload"]').change(function() {
        var activeInput = $(this); //grabs the jq object of whatever is sending the click event
        //Do all your file handling here, I'm going to skip to the li tinkering.

        var ul = $('ul[fileUploadId="' + activeInput.attr('id') + '"]');
        ul.empty(); //performs the same action as your loop clearing out children
        //The rest of this is pretty straight forward to figure out, so I'll leave that
        //for you, and skip ahead to using the 'clear' button. just use the 'ul' var
        //and it will target the correct ul for what you are trying to do.

        //After you have added the button and actually attached it to the DOM, in this same function, we will give it its click listener. 
        //Give the button the 'clearFile' class
        $('.clearFile').off('click'); //remove the click listeners so we don't have them multiple times.
        $('.clearFile').click(function(){
            var buttonClicked = $(this);
            var parentUl = buttonClicked.closest('ul');
            //the following two lines replace that entire oldInput newInput process you were doing.
            var fileUpload = $('#' + parentUl.attr('fileUploadId'));
            fileUpload .replaceWith( fileUpload = fileUpload .clone( true ) );
            parentUl.empty();
    )};
)};

您还可以创建一个 ul,并在 li 级别上执行所有操作,方法是将“fileUploadId”属性向下移动到 li,而不是......可能会使代码更整洁。

我意识到为了以类似的速度编写这篇文章,我已经遗漏了一些 block ,所以如果您需要澄清,请询问。

关于javascript - 删除和重建文件输入时清除文件列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26278639/

相关文章:

javascript - 基于数组数据创建 dom 元素的干净方法?

python - 程序化表单提交

时间:2019-03-17 标签:c#windowsforms/basicdatagrid

c# - 在中心绘制文本

php - 函数适用于 jquery 1.4.2,但不适用于 jquery 1.9.1

javascript - 使用 React 进行多个 AJAX 请求

javascript - 将整个 Object3D/Mesh 层次结构合并在一起

javascript - 使用jquery从文档的其他部分写入信息

JavaScript 悬停问题

javascript - jquery从中选择选项