在没有表单输入的情况下对 FileList 数据进行排序

Posted

技术标签:

【中文标题】在没有表单输入的情况下对 FileList 数据进行排序【英文标题】:Sorting FileList data without form inputs 【发布时间】:2021-04-16 20:51:26 【问题描述】:

我对 javascript、Jquery 和 php 的理解还比较陌生。在这一点上,我已经花了将近 80 个小时来理解这个修复,我希望能获得一些见解。我正在使用this 拖放图像上传功能,我需要根据它们的本地文件名按字母数字对 FileList 对象中的图像项进行排序,以与照片数据库的组织系统相一致。我知道 FileList 对象是只读的,所以我假设这是通过将这些项目添加到它们自己的数组中进行排序或比较来实现的。

使用此代码,

files = e.dataTransfer.files;
newFiles = Array.from(files).map((name) => name);
            newFiles.sort();
    console.log(files);
    console.log(newFiles);

我能够将文件名插入到它们自己的数组中,但我不确定如何继续将这个新的项目列表与它们原来的 FileList 对应项进行比较以进行排序。 Output.(注意FileList 对象(文件)的最后三项如何返回未排序的,newFiles,虽然已排序,但仅包含名称数据。)

我尝试过使用这种.slice 方法:

files = [].slice.call(files);

但我似乎无法触发代码。图片上传正常,无需排序。

这个方法也一样:

files = [...e.dataTransfer.files].sort();

我也尝试过使用MDN's推荐的代码:

files.sort((a, b) => a.localeCompare(b, navigator.languages[0] || navigator.language, numeric: true, ignorePunctuation: true));

但是当我尝试实施此修复时,控制台会返回 LocaleCompare is not a function。

我也研究过使用 Lauri Rooden 的 natural compare lite 和 Boris Moore 的 jsrender,但我不明白如何实现这些插件。

我开始编写一个迭代器来确定两个数组是否可以这样比较和排序,老实说,我只是想知道我是否走在正确的轨道上?

for (i=0; i < files.length; i++) 
                      if (files.name[i] === newFiles[i]) 
                 files.splice(i, 1, newFiles[i]) 
             elsei++;
       

我在 PHP 中的内部服务器 error 遇到了一些问题,但如果常规代码可以处理该错误,这是否会妨碍对 FileList 对象进行排序?

Here's 修改代码。 PHP 在 html 下方被注释掉,因此代码根本无法运行,并且 Javascript iframe 被分成由 cmets 分隔的 3 个部分。我知道这篇文章很长,并且有很多外部资源,但我想确保我的解释是彻底的。如果您对有抱负的网络开发人员有任何建议(除了退出 ^_^;),我将不胜感激!先感谢您! :)

【问题讨论】:

“我需要对 FileList 对象中的图像项进行排序”。为什么? 我希望图像文件按名称按字母数字顺序排序。本项目仅供本地使用,不面向公众。上传到当前版本的文件结合了字母、数字和文件扩展名。我知道如果不先将其对象提交到新数组,我无法对 FileList 本身进行排序 这没有回答“为什么?”的问题。您可能不知道,因为没有必要对该列表进行排序。 不,您只需对名称列表进行排序,然后按该顺序从 FileList 中检索文件。 不过,我还是会在服务器端订购列表。想象一个用户分几批加载他的文件。您不想对他/她的所有文件进行排序吗? 【参考方案1】:

感谢您的建议,杰拉德!一旦照片被放入,我最终选择了一个按钮,通过基于 id 的多维数组对照片进行排序:

HTML:

<div class="dontprint">
            <input TYPE="button" onclick="sortFunction()" id="sortButton" class="sortButton" value=" Sort ">
            <input TYPE="button" value=" Shortcut to Print! " onclick="printpage()" />
            <INPUT TYPE="button" onclick="history.go(0)" value=" Clear ">
        </div>

Javascript:

/* ---------------------------Added to index.html as script tag------------------------ */
//Called on Button Click
function sortFunction() 

//Grab images, array them
const pulled = document.getElementsByClassName("postedImage");
imageObjects = Array.prototype.slice.call(pulled);
    
//Store current image ID & Image Source in their own Arrays
var imageIdArray = [];
var imageSrcArray = [];
   for (let i = 0; i < imageObjects.length; i++) 
        imageSrcArray.push(imageObjects[i].currentSrc);
        imageIdArray.push(imageObjects[i].id);
          

//Adopt a multidimensional Array to associate Image ID with Image Source 
var multiArray = [];
   for (var i=0; i<imageIdArray.length && i<imageSrcArray.length; i++)
       multiArray[i] = [imageIdArray[i], imageSrcArray[i]];
            

//Sort imageObjects (multiArray) alphanumerically
    multiArray.sort(function(a, b) 
        if(a[0] > b[0]) return 1;
        if (a[0] < b[0]) return -1;
            );

//Sort Image ID's
imageIdArray.sort();

//Change image name on page
   var currentName = document.getElementsByClassName('name');
   var currentLink = document.getElementsByClassName('postedImage');
       for (let i = 0; i < currentName.length; i++) 
           var newerName = imageIdArray[i];
           currentName[i].innerHTML = newerName;
           

//Change image on page
//(Caution: Shuffles image sources when button is clicked more than once. Unsure why.)
   for (let i = 0; i < currentLink.length; i++) 
        var newLink = multiArray[i][1];
        currentLink[i].src = newLink;
        


/*-----------------------------Update these parts in script.js--------------------------*/
uploadStarted:function(i, file, len)
            createImage(file);
            $.data(file).find('.name').text(file.name);
            //Give each file an ID representative of its name
            document.getElementById('sortId').id = file.name;
        ,

        progressUpdated: function(i, file, progress) 
            $.data(file).find('.progress').width(progress);
            
        
         
    );

//Gave the image an ID and a Class for easy grabbing
    var template = '<div class="preview">'+
                        '<span class="imageHolder">'+
                            '<img / id="sortId" class="postedImage">'+
                            '<span class="uploaded"></span>'+
                        '</span>'+
                        
                            '<div class="name"></div>'+
                            
                        '</div>'+
                    '</div>';
;

如果有人知道如何解决有关排序多维数组的问题,我不希望每次按下按钮时都打乱数据 url。每次按下排序按钮时,数组都会使用来自页面的不同图像 URL 进行更新。我也很想知道 Tif 文件是否可以被这样的东西支持,但我会继续深入了解信息!

【讨论】:

以上是关于在没有表单输入的情况下对 FileList 数据进行排序的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JavaScript 中将 File 对象添加到 FileList 集合中?

如何在没有操作的情况下对 Pandas 数据框进行分组或聚合

如何在没有重复数据的情况下对两个具有连接的表进行求和?

可以在没有运行任何 Map/Reduce (/Yarn) 的情况下对 Hive 表执行 Spark SQL 吗?

在没有浏览器的情况下对WSO2 Identity Server进行身份验证,并获取SAML2断言消息

我如何在没有重复数据的情况下对两个具有连接的表求和?