programing

파일 목록에서 파일을 제거하는 방법

newsource 2023. 11. 6. 21:52

파일 목록에서 파일을 제거하는 방법

HTML5를 사용하여 드래그 앤 드롭 투 업 로드 웹 애플리케이션을 구축하고 있으며, 파일을 디브에 떨어뜨리고 당연히 파일 목록을 제공하는 dataTransfer 개체를 가져옵니다.

지금은 파일 몇 개를 제거하고 싶은데 방법이나 가능한지 모르겠습니다.

파일 목록에서 삭제하는 것이 좋습니다. 아무 소용이 없습니다.하지만 그것이 불가능하다면 대신에 파일리스트와 상호 작용하는 코드에 수표를 써야 합니까?번거롭겠네요.

선택한 파일 중 몇 개만 삭제하려면 삭제할 수 없습니다.연결한 File API Working Draft(파일 API 작업 초안)에는 다음과 같은 참고 사항이 포함되어 있습니다.

HTMLInputElement[HTML5] 인터페이스에 읽기 전용이 있습니다. FileList속성, […]
[emphasis마이]

HTML 5 작업 초안을 조금 읽다가 공통 요소 API를 발견했습니다.파일 목록 전체를 삭제하려면 다음을 설정해야 합니다.value소유물input빈 문자열에 대한 오브젝트는 다음과 같습니다.

document.getElementById('multifile').value = "";

그건 그렇고, 웹 애플리케이션의 파일을 사용한다는 기사도 흥미로울 것 같습니다.

자바스크립트 파일리스트는 읽기 전용이며 직접 조작할 수 없기 때문에,

베스트 메소드

당신은 당신이 순환해야 할 것입니다.input.files그것과 비교하면서index제거할 파일을 저장합니다.그와 동시에, 당신은 다음을 사용할 것입니다.new DataTransfer()파일 목록에서 제거할 파일을 제외한 새 파일 목록을 설정합니다.

이 접근법을 사용할 경우,input.files그 자체가 바뀝니다.

removeFileFromFileList(index) {
  const dt = new DataTransfer()
  const input = document.getElementById('files')
  const { files } = input
  
  for (let i = 0; i < files.length; i++) {
    const file = files[i]
    if (index !== i)
      dt.items.add(file) // here you exclude the file. thus removing it.
  }
  
  input.files = dt.files // Assign the updates list
}

대체 방법

또 다른 간단한 방법은 FileList를 배열로 변환한 다음 이를 연결하는 것입니다.

그러나 이러한 접근 방식은 변화하지 않을 것입니다.input.files

const input = document.getElementById('files')
// as an array, u have more freedom to transform the file list using array functions.
const fileListArr = Array.from(input.files)
fileListArr.splice(index, 1) // here u remove the file
console.log(fileListArr)

이 질문에는 이미 답변이 표시되어 있지만, 다른 사용자가 파일 목록을 사용하는 데 도움이 될 수 있는 몇 가지 정보를 공유하고자 합니다.

파일 목록을 배열로 취급하는 것이 편리하겠지만 정렬, 쉬프트, 팝, 슬라이스와 같은 방법은 작동하지 않습니다.다른 사용자가 제안한 대로 배열에 파일 목록을 복사할 수 있습니다.그러나 루프를 사용하는 것이 아니라 이러한 변환을 처리하는 간단한 한 줄 솔루션이 있습니다.

 // fileDialog.files is a FileList 

 var fileBuffer=[];

 // append the file list to an array
 Array.prototype.push.apply( fileBuffer, fileDialog.files ); // <-- here

 // And now you may manipulated the result as required

 // shift an item off the array
 var file = fileBuffer.shift(0,1);  // <-- works as expected
 console.info( file.name + ", " + file.size + ", " + file.type );

 // sort files by size
 fileBuffer.sort(function(a,b) {
    return a.size > b.size ? 1 : a.size < b.size ? -1 : 0;
 });

FF, Chrome 및 IE10+에서 정상 테스트됨

Evergreen 브라우저(Chrome, Firefox, Edge)를 대상으로 하거나 Safari 9+에서도 작동하는 경우 또는 Polyfill을 사용할 수 있는 여유가 있는 경우 다음을 사용하여 FileList를 배열로 변경할 수 있습니다.Array.from()다음과 같이:

let fileArray = Array.from(fileList);

이를 통해 다양한 제품군을 손쉽게 처리할 수 있습니다.File다른 배열처럼 말입니다.

우리가 HTML5 영역에 있기 때문에 이것이 제 해결책입니다.파일을 파일 목록에 두지 않고 배열에 밀어 넣은 다음 XHR2를 사용하여 FormData 개체에 파일을 밀어넣는 것이 핵심입니다.아래 예시.

Node.prototype.replaceWith = function(node)
{
    this.parentNode.replaceChild(node, this);
};
if(window.File && window.FileList)
{
    var topicForm = document.getElementById("yourForm");
    topicForm.fileZone = document.getElementById("fileDropZoneElement");
    topicForm.fileZone.files = new Array();
    topicForm.fileZone.inputWindow = document.createElement("input");
    topicForm.fileZone.inputWindow.setAttribute("type", "file");
    topicForm.fileZone.inputWindow.setAttribute("multiple", "multiple");
    topicForm.onsubmit = function(event)
    {
        var request = new XMLHttpRequest();
        if(request.upload)
        {
            event.preventDefault();
            topicForm.ajax.value = "true";
            request.upload.onprogress = function(event)
            {
                var progress = event.loaded.toString() + " bytes transfered.";
                if(event.lengthComputable)
                progress = Math.round(event.loaded / event.total * 100).toString() + "%";
                topicForm.fileZone.innerHTML = progress.toString();
            };
            request.onload = function(event)
            {
                response = JSON.parse(request.responseText);
                // Handle the response here.
            };
            request.open(topicForm.method, topicForm.getAttribute("action"), true);
            var data = new FormData(topicForm);
            for(var i = 0, file; file = topicForm.fileZone.files[i]; i++)
                data.append("file" + i.toString(), file);
            request.send(data);
        }
    };
    topicForm.fileZone.firstChild.replaceWith(document.createTextNode("Drop files or click here."));
    var handleFiles = function(files)
    {
        for(var i = 0, file; file = files[i]; i++)
            topicForm.fileZone.files.push(file);
    };
    topicForm.fileZone.ondrop = function(event)
    {
        event.stopPropagation();
        event.preventDefault();
        handleFiles(event.dataTransfer.files);
    };
    topicForm.fileZone.inputWindow.onchange = function(event)
    {
        handleFiles(topicForm.fileZone.inputWindow.files);
    };
    topicForm.fileZone.ondragover = function(event)
    {
        event.stopPropagation();
        event.preventDefault();
    };
    topicForm.fileZone.onclick = function()
    {
        topicForm.fileZone.inputWindow.focus();
        topicForm.fileZone.inputWindow.click();
    };
}
else
    topicForm.fileZone.firstChild.replaceWith(document.createTextNode("It's time to update your browser."));

저는 이에 대한 매우 신속하고 짧은 해결책을 찾았습니다.많은 인기 브라우저(Chrome, Firefox, Safari)에서 테스트되었습니다.

먼저 FileList를 Array로 변환해야 합니다.

var newFileList = Array.from(event.target.files);

특정 요소를 삭제하려면 다음을 사용합니다.

newFileList.splice(index,1);

이것이 오래된 질문이라는 것을 알고 있지만 이 문제와 관련하여 검색 엔진에서 높은 순위를 차지하고 있습니다.

FileList 개체의 속성은 삭제할 수 없지만 최소한 Firefox에서는 변경할 수 있습니다.이 문제에 대한 내 작업은 속성을 추가하는 것이었습니다.IsValid=true확인을 통과한 파일들과IsValid=false그렇지 않은 사람들에게.

그 다음에 목록을 뒤적여 그 안에 있는 것 뿐입니다.IsValid=trueFormData에 추가됩니다.

@Nicholas Anderson 간단하고 직설적으로 감사드립니다. 여기 당신의 코드가 적용되어 jquery를 사용하여 제 코드로 작동하고 있습니다.

HTML.

<input class="rangelog btn border-aero" id="file_fr" name="file_fr[]" multiple type="file" placeholder="{$labels_helpfiles_placeholder_file}">
<span style="cursor: pointer; cursor: hand;" onclick="cleanInputs($('#file_fr'))"><i class="fa fa-trash"></i> Empty chosen files</span>

JS CODE

   function cleanInputs(fileEle){
    $(fileEle).val("");
    var parEle = $(fileEle).parent();
    var newEle = $(fileEle).clone()
    $(fileEle).remove();
    $(parEle).prepend(newEle);
}

이것은 일시적인 것이지만, 저는 제가 이렇게 해결했던 문제가 있었습니다.저의 경우 XMLHtp 요청을 통해 파일을 업로드하고 있었기 때문에 양식 데이터 첨부를 통해 파일 목록 복제 데이터를 게시할 수 있었습니다.여러 파일을 원하는 만큼 끌어서 놓거나 선택할 수 있으며(파일을 다시 선택해도 복제된 파일 목록이 재설정되지 않음), (복제된) 파일 목록에서 원하는 모든 파일을 제거하고 남은 파일은 xmlhttprequest를 통해 제출할 수 있습니다.이게 제가 한 일입니다.제가 여기에 올린 첫 번째 게시물이라 코드가 좀 지저분합니다.미안하다.아, 그리고 줌라 대본처럼 달러가 아닌 jQuery를 써야 했습니다.

// some global variables
var clon = {};  // will be my FileList clone
var removedkeys = 0; // removed keys counter for later processing the request
var NextId = 0; // counter to add entries to the clone and not replace existing ones

jQuery(document).ready(function(){
    jQuery("#form input").change(function () {

    // making the clone
    var curFiles = this.files;
    // temporary object clone before copying info to the clone
    var temparr = jQuery.extend(true, {}, curFiles);
    // delete unnecessary FileList keys that were cloned
    delete temparr["length"];
    delete temparr["item"];

    if (Object.keys(clon).length === 0){
       jQuery.extend(true, clon, temparr);
    }else{
       var keysArr = Object.keys(clon);
       NextId = Math.max.apply(null, keysArr)+1; // FileList keys are numbers
       if (NextId < curFiles.length){ // a bug I found and had to solve for not replacing my temparr keys...
          NextId = curFiles.length;
       }
       for (var key in temparr) { // I have to rename new entries for not overwriting existing keys in clon
          if (temparr.hasOwnProperty(key)) {
             temparr[NextId] = temparr[key];
             delete temparr[key];
                // meter aca los cambios de id en los html tags con el nuevo NextId
                NextId++;
          }
       } 
       jQuery.extend(true, clon, temparr); // copy new entries to clon
    }

// modifying the html file list display

if (NextId === 0){
    jQuery("#filelist").html("");
    for(var i=0; i<curFiles.length; i++) {
        var f = curFiles[i];
        jQuery("#filelist").append("<p id=\"file"+i+"\" style=\'margin-bottom: 3px!important;\'>" + f.name + "<a style=\"float:right;cursor:pointer;\" onclick=\"BorrarFile("+i+")\">x</a></p>"); // the function BorrarFile will handle file deletion from the clone by file id
    }
}else{
    for(var i=0; i<curFiles.length; i++) {
        var f = curFiles[i];
        jQuery("#filelist").append("<p id=\"file"+(i+NextId-curFiles.length)+"\" style=\'margin-bottom: 3px!important;\'>" + f.name + "<a style=\"float:right;cursor:pointer;\" onclick=\"BorrarFile("+(i+NextId-curFiles.length)+")\">x</a></p>"); // yeap, i+NextId-curFiles.length actually gets it right
    }        
}
// update the total files count wherever you want
jQuery("#form p").text(Object.keys(clon).length + " file(s) selected");
    });
});

function BorrarFile(id){ // handling file deletion from clone
    jQuery("#file"+id).remove(); // remove the html filelist element
    delete clon[id]; // delete the entry
    removedkeys++; // add to removed keys counter
    if (Object.keys(clon).length === 0){
        jQuery("#form p").text(Object.keys(clon).length + " file(s) selected");
        jQuery("#fileToUpload").val(""); // I had to reset the form file input for my form check function before submission. Else it would send even though my clone was empty
    }else{
        jQuery("#form p").text(Object.keys(clon).length + " file(s) selected");
    }
}
// now my form check function

function check(){
    if( document.getElementById("fileToUpload").files.length == 0 ){
        alert("No file selected");
        return false;
    }else{
        var _validFileExtensions = [".pdf", ".PDF"]; // I wanted pdf files
        // retrieve input files
        var arrInputs = clon;

       // validating files
       for (var i = 0; i < Object.keys(arrInputs).length+removedkeys; i++) {
         if (typeof arrInputs[i]!="undefined"){
           var oInput = arrInputs[i];
           if (oInput.type == "application/pdf") {
               var sFileName = oInput.name;
               if (sFileName.length > 0) {
                   var blnValid = false;
                   for (var j = 0; j < _validFileExtensions.length; j++) {
                     var sCurExtension = _validFileExtensions[j];
                     if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) {
                       blnValid = true;
                       break;
                     }
                   }
                  if (!blnValid) {
                    alert("Sorry, " + sFileName + " is invalid, allowed extensions are: " + _validFileExtensions.join(", "));
                    return false;
                  }
              }
           }else{
           alert("Sorry, " + arrInputs[0].name + " is invalid, allowed extensions are: " + _validFileExtensions.join(" or "));
           return false;
           }
         }
       }

    // proceed with the data appending and submission
    // here some hidden input values i had previously set. Now retrieving them for submission. My form wasn't actually even a form...
    var fecha = jQuery("#fecha").val();
    var vendor = jQuery("#vendor").val();
    var sku = jQuery("#sku").val();
    // create the formdata object
    var formData = new FormData();
    formData.append("fecha", fecha);
    formData.append("vendor", encodeURI(vendor));
    formData.append("sku", sku);
    // now appending the clone file data (finally!)
    var fila = clon; // i just did this because I had already written the following using the "fila" object, so I copy my clone again
    // the interesting part. As entries in my clone object aren't consecutive numbers I cannot iterate normally, so I came up with the following idea
    for (i = 0; i < Object.keys(fila).length+removedkeys; i++) { 
        if(typeof fila[i]!="undefined"){
            formData.append("fileToUpload[]", fila[i]); // VERY IMPORTANT the formdata key for the files HAS to be an array. It will be later retrieved as $_FILES['fileToUpload']['temp_name'][i]
        }
    }
    jQuery("#submitbtn").fadeOut("slow"); // remove the upload btn so it can't be used again
    jQuery("#drag").html(""); // clearing the output message element
    // start the request
    var xhttp = new XMLHttpRequest();
    xhttp.addEventListener("progress", function(e) {
            var done = e.position || e.loaded, total = e.totalSize || e.total;
        }, false);
        if ( xhttp.upload ) {
            xhttp.upload.onprogress = function(e) {
                var done = e.position || e.loaded, total = e.totalSize || e.total;
                var percent = done / total;
                jQuery("#drag").html(Math.round(percent * 100) + "%");
            };
        }
      xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
         var respuesta = this.responseText;
         jQuery("#drag").html(respuesta);
        }
      };
      xhttp.open("POST", "your_upload_handler.php", true);  
      xhttp.send(formData);
    return true;
    }
};

이제 html과 스타일입니다.저는 꽤 초보자이지만 이 모든 것이 사실은 저에게 효과가 있었고 그것을 알아내는데 시간이 좀 걸렸습니다.

<div id="form" class="formpos">
<!--    Select the pdf to upload:-->
  <input type="file" name="fileToUpload[]" id="fileToUpload" accept="application/pdf" multiple>
  <div><p id="drag">Drop your files here or click to select them</p>
  </div>
  <button id="submitbtn" onclick="return check()" >Upload</button>
// these inputs are passed with different names on the formdata. Be aware of that
// I was echoing this, so that's why I use the single quote for php variables
  <input type="hidden" id="fecha" name="fecha_copy" value="'.$fecha.'" />
  <input type="hidden" id="vendor" name="vendorname" value="'.$vendor.'" />
  <input type="hidden" id="sku" name="sku" value="'.$sku.'"" />
</div>
<h1 style="width: 500px!important;margin:20px auto 0px!important;font-size:24px!important;">File list:</h1>
<div id="filelist" style="width: 500px!important;margin:10px auto 0px!important;">Nothing selected yet</div>

스타일이.주믈라의 행동을 무시하기 위해서는 그들 중 일부를 표시해야 했습니다.

.formpos{
  width: 500px;
  height: 200px;
  border: 4px dashed #999;
  margin: 30px auto 100px;
 }
.formpos  p{
  text-align: center!important;
  padding: 80px 30px 0px;
  color: #000;
}
.formpos  div{
  width: 100%!important;
  height: 100%!important;
  text-align: center!important;
  margin-bottom: 30px!important;
}
.formpos input{
  position: absolute!important;
  margin: 0!important;
  padding: 0!important;
  width: 500px!important;
  height: 200px!important;
  outline: none!important;
  opacity: 0!important;
}
.formpos button{
  margin: 0;
  color: #fff;
  background: #16a085;
  border: none;
  width: 508px;
  height: 35px;
  margin-left: -4px;
  border-radius: 4px;
  transition: all .2s ease;
  outline: none;
}
.formpos button:hover{
  background: #149174;
  color: #0C5645;
}
.formpos button:active{
  border:0;
}

도움이 되었으면 좋겠습니다.

좀 더 우아한 방법이 있겠지만 여기 제 해결책이 있습니다.쥬리와 함께

fileEle.value = "";
var parEle = $(fileEle).parent();
var newEle = $(fileEle).clone()
$(fileEle).remove();
parEle.append(newEle);

기본적으로 입력 값을 지웁니다.복제한 후 이전 복제 대신 복제를 배치합니다.

파일과 함께 데이터베이스에 포스트 요청을 보낼 수 있는 행운이 있고 DOM에 보낼 파일이 있는 경우

파일 목록에 있는 파일이 DOM에 있는지 간단하게 확인할 수 있으며, 그렇지 않은 경우에는 해당 요소를 dDB로 보내지 않습니다.

나는 이것이 꽤 오래된 질문이라는 것을 알지만, 나는 제출하기 전에 사용자 정의 UI에서 선택적으로 제거할 수 있는 파일의 수를 대기열에 넣기 위해 html 다중 파일 선택 업로드를 사용하고 있습니다.

다음과 같은 변수로 파일 저장:

let uploadedFiles = [];

//inside DOM file select "onChange" event
let selected = e.target.files[0] ? e.target.files : [];
uploadedFiles = [...uploadedFiles , ...selected ];
createElements();

"remove a file"로 UI 만들기:

function createElements(){
  uploadedFiles.forEach((f,i) => {

    //remove DOM elements and re-create them here
    /* //you can show an image like this:
    *  let reader = new FileReader();
    *  reader.onload = function (e) {
    *    let url = e.target.result;
    *    // create <img src=url />
    *  };
    *  reader.readAsDataURL(f);
    */

    element.addEventListener("click", function () {
      uploadedFiles.splice(i, 1);
      createElements();
    });

  }
}

서버에 제출:

let fd = new FormData();
uploadedFiles.forEach((f, i) => {
  fd.append("files[]", f);
});
fetch("yourEndpoint", { 
  method: "POST", 
  body: fd, 
  headers: { 
    //do not set Content-Type 
  } 
}).then(...)

나는 많은 개발자들의 솔루션을 혼합하여 이 솔루션에 도달합니다.삭제 후 원래 배열 목록을 변경하므로 이미지를 저장하려면 이렇게 할 수 있습니다.

<script>
    var images = [];
      function image_select() {
          var image = document.getElementById('image').files;
          for (i = 0; i < image.length; i++) {
            images.push({
                "name" : image[i].name,
                "url" : URL.createObjectURL(image[i]),
                "file" : image[i],
            })
          }
          document.getElementById('container').innerHTML = image_show();
      }

      function image_show() {
          var image = "";
          images.forEach((i) => {
             image += `<div class="image_container d-flex justify-content-center position-relative">
                  <img src="`+ i.url +`" alt="Image">
                  <span class="position-absolute" onclick="delete_image(`+ images.indexOf(i) +`)">&times;</span>
              </div>`;
          })
          return image;
      }
      function delete_image(e) {
        images.splice(e, 1);
        document.getElementById('container').innerHTML = image_show();

        const dt = new DataTransfer()
        const input = document.getElementById('image')
        const { files } = input

        for (let i = 0; i < files.length; i++) {
            const file = files[i]
            if (e !== i)
            dt.items.add(file);
        }

        input.files = dt.files;
        console.log(document.getElementById('image').files);
      }
</script>

**********html 코드 ******입니다.

<body>
    <div class="container mt-3 w-100">
        <div class="card shadow-sm w-100">
            <div class="card-header d-flex justify-content-between">
                <h4>Preview Multiple Images</h4>
                <form class="form" action="{{route('store')}}" method="post" id="form" enctype="multipart/form-data">
                    @csrf
                    <input type="file" name="image[]" id="image" multiple onchange="image_select()">
                    <button class="btn btn-sm btn-primary" type="submit">Submit</button>
                </form>
            </div>
            <div class="card-body d-flex flex-wrap justify-content-start" id="container">

            </div>
        </div>
    </div>
</body>

******* CSS 코드 ********입니다.

<style>
        .image_container {
    height: 120px;
    width: 200px;
    border-radius: 6px;
    overflow: hidden;
    margin: 10px;
}
.image_container img {
    height: 100%;
    width: auto;
    object-fit: cover;
}
.image_container span {
    top: -6px;
    right: 8px;
    color: red;
    font-size: 28px;
    font-weight: normal;
    cursor: pointer;
}
    </style>

저는 TypeScript를 사용하고 있는데, Type Checking이 심해서 모든 단계에서 불만이 있었습니다.다음 코드가 스벨테에서 저에게 효과가 있었습니다.스벨테와는 아무 상관이 없습니다.따라서 TS를 사용하는 모든 라이브러리/프레임워크와 함께 작동해야 합니다.

const ele = document.getElementById('file-upload') as HTMLInputElement;
if (ele) {
    ele.value = "";
}

읽기 전용 파일 목록 대신 배열을 만들어 사용할 수도 있습니다.

var myReadWriteList = new Array();
// user selects files later...
// then as soon as convenient... 
myReadWriteList = FileListReadOnly;

그 이후 기본 제공 목록 대신 목록에 대해 업로드를 수행합니다.저는 당신이 작업하고 있는 문맥을 잘 모르지만 제가 찾은 jquery plugin과 함께 작업하고 있으며, 제가 해야 할 일은 plugin의 소스를 가져와서 사용하여 페이지에 넣는 것이었습니다.<script>tags. 그 다음 소스 위에 나의 배열을 추가해서 글로벌 변수로 작용하고 플러그인이 참조할 수 있도록 했습니다.

그 다음에는 참고 자료를 교환하는 문제에 불과했습니다.

이렇게 하면 드래그 앤 드롭도 다시 추가할 수 있을 것 같습니다. 기본 제공 목록이 읽기 전용인 경우 삭제된 파일을 목록에 어떻게 가져올 수 있습니까?

:))

이런 식으로 해결합니다.

 //position  -> the position of the file you need to delete

  this.fileImgs.forEach((item, index, object) => {
     if(item.idColor === idC){
        if(item.imgs.length === 1){
            object.splice(index,1) }
        else{
           const itemFileImgs = [...item.imgs];
           itemFileImgs.splice(position,1)
           item.imgs = [...itemFileImgs] 
            }
        }});
      console.log(this.fileImgs)

enter image description here

인뷰 js:

self.$refs.inputFile.value = ''

텍스트의 입력 유형을 변경하고 파일로 다시 돌아갑니다:D

언급URL : https://stackoverflow.com/questions/3144419/how-do-i-remove-a-file-from-the-filelist