js控制文件拖拽并获取拖拽内容实现代码
js能够监听到拖拽的事件有drag、dragend、dragenter、dragexit(没有浏览器实现)、dragleave、dragover、dragstart、drop,详细的内容可以看MDN。其中,与拖拽文件相关的事件有dragenter(文件拖拽进)、dragover(文件拖拽在悬浮)、dragleave(文件拖拽离开)、drop(文件拖拽放下)。
拖拽事件可以绑定到指定的DOM元素上,可以绑定到整个页面中。
var dropEle = document.querySelector('#dropZone'); dropEle.addEventListener('drop', function (e) { // }, false); document.addEventListener('drop', function (e) { // }, false);
阻止默认行为
一般来说,我们只需要把处理拖拽文件的业务逻辑写到drop事件中就可以了,为什么还要绑定dragenter、dragover、dragleave这三个事件呢?
因为当你拖拽一个文件到没有对拖拽事件进行处理的浏览器中的时候,浏览器会打开这个文件,比如拖拽一张图片浏览器会打开这个图片,在没有PDF阅读器的时候也可以拖拽一个PDF到浏览器中,浏览器就会打开这个PDF文件。
如果浏览器打开了拖拽的文件,页面就跳走了,我们希望得到拖拽的文件,而不是让页面跳走。上面说到浏览器会打开拖拽的文件是浏览器的默认行为,我们需要阻止这个默认行为,就需要再上述的事件中进行阻止。
dropZone.addEventListener("dragenter", function (e) { e.preventDefault(); e.stopPropagation(); }, false); dropZone.addEventListener("dragover", function (e) { e.preventDefault(); e.stopPropagation(); }, false); dropZone.addEventListener("dragleave", function (e) { e.preventDefault(); e.stopPropagation(); }, false); dropZone.addEventListener("drop", function (e) { e.preventDefault(); e.stopPropagation(); // 处理拖拽文件的逻辑 }
实际上dragenter不阻止默认行为也不会触发浏览器打开文件,为了防止某些浏览器可能有的兼容性问题,把拖拽周期中的所有的事件都阻止默认行为并且阻止了事件冒泡。
获得拖拽的文件
我们会在drop这个事件的回调中的事件对象能够得到文件对象。
在事件对象中,一个e.dataTransfer这样的属性,它是一个DataTransfer类型的数据,有如下的属性
属性 | 类型 | 说明 |
---|---|---|
dropEffect | String | 用来hack某些兼容性问题 |
effectAllowed | String | 暂时不用 |
files | FileList | 拖拽的文件列表 |
items | DataTransferItemList | 拖拽的数据(有可能是字符串) |
types | Array | 拖拽的数据类型 该属性在Safari下比较混乱 |
在Chrome中我们用items对象获得文件,其他浏览器用files获得文件,主要是为了处理拖拽文件夹的问题,最好不允许用户拖拽文件夹,因为文件夹内可能还有文件夹,递归上传文件会很久,如果不递归查找,只上传目录第一层级的文件,用户可能以为上传功能了,但是没有上传子目录文件,所以还是禁止上传文件夹比较好,后面我会说要怎么处理。
Chrome获取文件
dropZone.addEventListener("drop", function (e) { e.preventDefault(); e.stopPropagation(); var df = e.dataTransfer; var dropFiles = []; // 存放拖拽的文件对象 if(df.items !== undefined) { // Chrome有items属性,对Chrome的单独处理 for(var i = 0; i < df.items.length; i++) { var item = df.items[i]; // 用webkitGetAsEntry禁止上传目录 if(item.kind === "file" && item.webkitGetAsEntry().isFile) { var file = item.getAsFile(); dropFiles.push(file); } } } }
其他浏览器获取文件
这里只测试了Safari,其他浏览器并没有测试,不过看完本文一定也有思路处理其他浏览器的兼容情况。
dropZone.addEventListener("drop", function (e) { e.preventDefault(); e.stopPropagation(); var df = e.dataTransfer; var dropFiles = []; // 存放拖拽的文件对象 if(df.items !== undefined) { // Chrome拖拽文件逻辑 } else { for(var i = 0; i < df.files.length; i++) { dropFiles.push(df.files[i]); } } }
由于Safari没有item,自然也没有webkitGetAsEntry,所以在Safari无法确定拖拽的是否是文件还是文件夹。
非Chrome内核浏览器判断目录的方法
浏览器获取到的每个file对象有四个属性:lastModified、name、size、type,其中type是文件的MIME Type,文件夹的type是空的,但是有些文件没有MIME Type,如果按照type是否为空判断是不是拖拽的文件夹的话,会误伤一部分文件,所以这个方法行。
那么还有什么方法可以判断呢,思路大概是这样子的,用户拖拽的文件和文件夹应该是不一样的东西,用File API操作的时候应该会有区别,比如进行某些操作的时候,文件就能够正常操作,但是文件夹就会报错,通过错误的捕获就能够判断是文件还是文件夹了,好我们根据这个思路来写一下。
dropZone.addEventListener("drop", function (e) { e.preventDefault(); e.stopPropagation(); var df = e.dataTransfer; var dropFiles = []; if(df.items !== undefined){ // Chrome拖拽文件逻辑 } else { for(var i = 0; i < df.files.length; i++){ var dropFile = df.files[i]; if ( dropFile.type ) { // 如果type不是空串,一定是文件 dropFiles.push(dropFile); } else { try { var fileReader = new FileReader(); fileReader.readAsDataURL(dropFile.slice(0, 3)); fileReader.addEventListener('load', function (e) { console.log(e, 'load'); dropFiles.push(dropFile); }, false); fileReader.addEventListener('error', function (e) { console.log(e, 'error,不可以上传文件夹'); }, false); } catch (e) { console.log(e, 'catch error,不可以上传文件夹'); } } } } }, false);
上面代码创建了一个FileReader实例,通过这个实例对文件进行读取,我测试读取一个1G多的文件要3S多,时间有点长,就用slice截取了前3个字符,为什么是前3个不是前2个或者前4个呢,因为代码是我写的,我开心这么写呗~
如果load事件触发了,就说明拖拽过来的东西是文件,如果error事件触发了,就说明是文件夹,为了防止其他可能的潜在错误,用try包起来这段代码。
三方应用的一点点小hack
经过测试发现通过Mac的Finder拖拽文件没有问题,但是有时候文件并不一定在Finder中,也可能在某些应用中,有一个应用叫做圈点,这个应用的用户反馈文件拖拽失效,去看了其他开源文件上传的源码,发现了这样一行代码:
dropZone.addEventListener("dragover", function (e) { e.dataTransfer.dropEffect = 'copy'; // 兼容某些三方应用,如圈点 e.preventDefault(); e.stopPropagation(); }, false);
需要把dropEffect置为copy,上网搜了下这个问题,源码文档中也没有说为什么要加这个,有兴趣的同学可以找一下为什么。
可以拿来就用的代码
由于用了FileReader去读取文件,这是一个异步IO操作,为了记录当前处理了多少个文件,以及什么时候触发拖拽结束的回调,写了一个checkDropFinish的方法一直去比较处理的文件数量和文件总数,确定所有文件处理完了后就去调用完成的回调。
另外,我在最后调试异步处理的时候,用的断点调试,发现断点调试在Safari中会导致异步回调不触发,需要自己调试定制功能的同学注意下。
// 获得拖拽文件的回调函数 function getDropFileCallBack (dropFiles) { console.log(dropFiles, dropFiles.length); } var dropZone = document.querySelector("#dropZone"); dropZone.addEventListener("dragenter", function (e) { e.preventDefault(); e.stopPropagation(); }, false); dropZone.addEventListener("dragover", function (e) { e.dataTransfer.dropEffect = 'copy'; // 兼容某些三方应用,如圈点 e.preventDefault(); e.stopPropagation(); }, false); dropZone.addEventListener("dragleave", function (e) { e.preventDefault(); e.stopPropagation(); }, false); dropZone.addEventListener("drop", function (e) { e.preventDefault(); e.stopPropagation(); var df = e.dataTransfer; var dropFiles = []; // 拖拽的文件,会放到这里 var dealFileCnt = 0; // 读取文件是个异步的过程,需要记录处理了多少个文件了 var allFileLen = df.files.length; // 所有的文件的数量,给非Chrome浏览器使用的变量 // 检测是否已经把所有的文件都遍历过了 function checkDropFinish () { if ( dealFileCnt === allFileLen-1 ) { getDropFileCallBack(dropFiles); } dealFileCnt++; } if(df.items !== undefined){ // Chrome拖拽文件逻辑 for(var i = 0; i < df.items.length; i++) { var item = df.items[i]; if(item.kind === "file" && item.webkitGetAsEntry().isFile) { var file = item.getAsFile(); dropFiles.push(file); console.log(file); } } } else { // 非Chrome拖拽文件逻辑 for(var i = 0; i < allFileLen; i++) { var dropFile = df.files[i]; if ( dropFile.type ) { dropFiles.push(dropFile); checkDropFinish(); } else { try { var fileReader = new FileReader(); fileReader.readAsDataURL(dropFile.slice(0, 3)); fileReader.addEventListener('load', function (e) { console.log(e, 'load'); dropFiles.push(dropFile); checkDropFinish(); }, false); fileReader.addEventListener('error', function (e) { console.log(e, 'error,不可以上传文件夹'); checkDropFinish(); }, false); } catch (e) { console.log(e, 'catch error,不可以上传文件夹'); checkDropFinish(); } } } } }, false);
相关推荐:
Atas ialah kandungan terperinci js控制文件拖拽并获取拖拽内容实现代码. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Bagaimana untuk melaksanakan log masuk WeChat dwi pada telefon mudah alih Huawei? Dengan kebangkitan media sosial, WeChat telah menjadi salah satu alat komunikasi yang sangat diperlukan dalam kehidupan seharian orang ramai. Walau bagaimanapun, ramai orang mungkin menghadapi masalah: log masuk ke beberapa akaun WeChat pada masa yang sama pada telefon mudah alih yang sama. Bagi pengguna telefon mudah alih Huawei, tidak sukar untuk mencapai log masuk WeChat dwi Artikel ini akan memperkenalkan cara mencapai log masuk WeChat dwi pada telefon mudah alih Huawei. Pertama sekali, sistem EMUI yang disertakan dengan telefon mudah alih Huawei menyediakan fungsi yang sangat mudah - pembukaan dua aplikasi. Melalui fungsi pembukaan dwi aplikasi, pengguna boleh serentak

Bagaimana untuk menukar halaman yang membuka pelayar Microsoft Edge kepada navigasi 360 Ia sebenarnya sangat mudah, jadi sekarang saya akan berkongsi dengan anda kaedah menukar halaman yang membuka pelayar Microsoft Edge kepada 360 navigasi Rakan-rakan yang memerlukan lihat. Saya harap dapat membantu semua orang. Buka penyemak imbas Microsoft Edge. Kami melihat halaman seperti di bawah. Klik pada ikon tiga titik di sudut kanan atas. Klik "Tetapan." Klik "Pada permulaan" dalam lajur kiri halaman tetapan. Klik pada tiga titik yang ditunjukkan dalam gambar di lajur kanan (jangan klik "Buka Tab Baharu"), kemudian klik Edit dan tukar URL kepada "0" (atau nombor lain yang tidak bermakna). Kemudian klik "Simpan". Seterusnya, pilih "

Bahasa pengaturcaraan PHP ialah alat yang berkuasa untuk pembangunan web, yang mampu menyokong pelbagai logik dan algoritma pengaturcaraan yang berbeza. Antaranya, melaksanakan jujukan Fibonacci adalah masalah pengaturcaraan biasa dan klasik. Dalam artikel ini, kami akan memperkenalkan cara menggunakan bahasa pengaturcaraan PHP untuk melaksanakan jujukan Fibonacci, dan melampirkan contoh kod tertentu. Jujukan Fibonacci ialah jujukan matematik yang ditakrifkan seperti berikut: unsur pertama dan kedua bagi jujukan ialah 1, dan bermula dari unsur ketiga, nilai setiap unsur adalah sama dengan jumlah dua unsur sebelumnya. Beberapa elemen pertama urutan

Bagaimana untuk melaksanakan fungsi klon WeChat pada telefon mudah alih Huawei Dengan populariti perisian sosial dan penekanan yang semakin meningkat terhadap privasi dan keselamatan orang ramai, fungsi klon WeChat telah beransur-ansur menjadi tumpuan perhatian. Fungsi klon WeChat boleh membantu pengguna log masuk ke berbilang akaun WeChat pada telefon mudah alih yang sama pada masa yang sama, menjadikannya lebih mudah untuk diurus dan digunakan. Tidak sukar untuk melaksanakan fungsi klon WeChat pada telefon mudah alih Huawei Anda hanya perlu mengikuti langkah berikut. Langkah 1: Pastikan versi sistem telefon mudah alih dan versi WeChat memenuhi keperluan Pertama, pastikan versi sistem telefon mudah alih Huawei anda telah dikemas kini kepada versi terkini, serta Apl WeChat.

CheatEngine ialah editor permainan yang boleh mengedit dan mengubah suai memori permainan. Walau bagaimanapun, bahasa lalainya adalah bukan bahasa Cina, yang menyusahkan ramai rakan Jadi bagaimana untuk menetapkan bahasa Cina dalam CheatEngine? Hari ini, editor akan memberi anda pengenalan terperinci tentang cara menyediakan bahasa Cina dalam CheatEngine saya harap ia dapat membantu anda. Kaedah tetapan satu: 1. Klik dua kali untuk membuka perisian dan klik "edit" di sudut kiri atas. 2. Kemudian klik "tetapan" dalam senarai pilihan di bawah. 3. Dalam tetingkap yang terbuka, klik "bahasa" dalam lajur kiri

Dalam bidang pembangunan perisian hari ini, Golang (bahasa Go), sebagai bahasa pengaturcaraan yang cekap, ringkas dan sangat bersesuaian, semakin digemari oleh pembangun. Perpustakaan standardnya yang kaya dan ciri-ciri konkurensi yang cekap menjadikannya pilihan berprofil tinggi dalam bidang pembangunan permainan. Artikel ini akan meneroka cara menggunakan Golang untuk pembangunan permainan dan menunjukkan kemungkinan besarnya melalui contoh kod tertentu. 1. Kelebihan Golang dalam pembangunan permainan Sebagai bahasa yang ditaip secara statik, Golang digunakan dalam membina sistem permainan berskala besar.

Panduan Pelaksanaan Keperluan Permainan PHP Dengan populariti dan perkembangan Internet, pasaran permainan web menjadi semakin popular. Ramai pembangun berharap untuk menggunakan bahasa PHP untuk membangunkan permainan web mereka sendiri, dan melaksanakan keperluan permainan adalah langkah utama. Artikel ini akan memperkenalkan cara menggunakan bahasa PHP untuk melaksanakan keperluan permainan biasa dan menyediakan contoh kod khusus. 1. Cipta watak permainan Dalam permainan web, watak permainan adalah elemen yang sangat penting. Kita perlu mentakrifkan atribut watak permainan, seperti nama, tahap, nilai pengalaman, dll., dan menyediakan kaedah untuk mengendalikannya

Adakah anda tahu di mana Microsoft Edge ditetapkan untuk memaparkan butang muat turun di bawah, editor akan membawakan anda kaedah menetapkan butang muat turun untuk dipaparkan dalam Microsoft Edge Saya harap ia akan membantu anda tentangnya! Langkah 1: Mula-mula buka Pelayar Microsoft Edge, klik logo [...] di sudut kanan atas, seperti yang ditunjukkan dalam rajah di bawah. Langkah 2: Kemudian klik [Settings] dalam menu pop timbul, seperti yang ditunjukkan dalam rajah di bawah. Langkah 3: Kemudian klik [Penampilan] di sebelah kiri antara muka, seperti yang ditunjukkan dalam rajah di bawah. Langkah 4: Akhir sekali, klik butang di sebelah kanan [Tunjukkan Butang Muat Turun] dan ia akan bertukar daripada kelabu kepada biru, seperti yang ditunjukkan dalam rajah di bawah. Di atas ialah tempat editor membawa anda cara menyediakan butang muat turun dalam Microsoft Edge.
