Kullanıcının yerel cihazındaki dosyaları seçmek ve bu dosyalarla etkileşimde bulunmak, web'de en sık kullanılan özelliklerden biridir. Kullanıcıların dosya seçmesine ve örneğin fotoğraf paylaşırken veya vergi belgelerini gönderirken bir sunucuya yüklemesine olanak tanır. Ayrıca, sitelerin verileri ağ genelinde aktarmak zorunda kalmadan bunları okumasına ve değiştirmesine de olanak tanır. Bu sayfada, dosyalarla etkileşimde bulunmak için JavaScript'in nasıl kullanılacağı ayrıntılı bir şekilde açıklanmaktadır.
Modern File System Access API
File System Access API, kullanıcının yerel sistemindeki dosyalardan ve dizinlere okuma ve yazma yöntemi sunar. Chrome ve Edge gibi Chromium tabanlı tarayıcıların çoğunda mevcut. Bu özellik hakkında daha fazla bilgi edinmek için File System Access API'yi inceleyin.
File System Access API tüm tarayıcılarla uyumlu olmadığından, kullanılabilir olduğu her yerde yeni API'yi kullanan ve kullanılamadığında eski yaklaşımlara geri dönen bir yardımcı kitaplık olan browser-fs-access'i kullanmanızı öneririz.
Klasik yöntemle dosyalarla çalışın
Bu kılavuzda, eski JavaScript yöntemlerini kullanarak dosyalarla nasıl etkileşimde bulunulacağı gösterilmektedir.
Dosyaları seçin
Dosyaları seçmek için iki temel yöntem vardır: HTML giriş öğesini kullanma ve sürükle ve bırak bölgesi kullanma.
HTML giriş öğesi
Kullanıcıların dosya seçmesinin en kolay yolu, yaygın olarak kullanılan tüm tarayıcılarda desteklenen <input type="file">
öğesini kullanmaktır. Bu özellik tıklandığında kullanıcının, işletim sisteminin yerleşik dosya seçimi kullanıcı arayüzünü kullanarak bir veya multiple
özelliği eklenmişse birden fazla dosya seçmesine olanak tanır. Kullanıcı bir dosya veya dosyayı seçmeyi bitirdiğinde, öğenin change
etkinliği tetiklenir. Bir FileList
nesnesi olan event.target.files
alanındaki dosya listesine erişebilirsiniz.
FileList
içindeki her öğe bir File
nesnesidir.
<!-- The `multiple` attribute lets users select multiple files. -->
<input type="file" id="file-selector" multiple>
<script>
const fileSelector = document.getElementById('file-selector');
fileSelector.addEventListener('change', (event) => {
const fileList = event.target.files;
console.log(fileList);
});
</script>
Aşağıdaki örnek, kullanıcının işletim sistemlerinin yerleşik dosya seçimi kullanıcı arayüzünü kullanarak birden fazla dosya seçmesine ve ardından seçilen her dosyayı konsola kaydetmesine olanak tanır.
Kullanıcıların seçebileceği dosya türlerini sınırlayın
Bazı durumlarda, kullanıcıların seçebileceği dosya türlerini sınırlamak isteyebilirsiniz. Örneğin, bir resim düzenleme uygulaması yalnızca resimleri kabul etmelidir, metin dosyalarını kabul etmemelidir. Dosya türü kısıtlamaları ayarlamak için giriş öğesine bir accept
özelliği ekleyerek hangi dosya türlerinin kabul edildiğini belirtin:
<input type="file" id="file-selector" accept=".jpg, .jpeg, .png">
Özel sürükle ve bırak
Bazı tarayıcılarda <input type="file">
öğesi aynı zamanda bir bırakma hedefidir ve kullanıcıların uygulamanıza dosya sürükleyip bırakmasına olanak tanır. Ancak bu bırakma hedefi küçüktür ve kullanımı zor olabilir. Bunun yerine, <input type="file">
öğesi kullanarak temel özellikleri sağladıktan sonra büyük, özel bir sürükle ve bırak yüzeyi sağlayabilirsiniz.
Lansman bölgenizi seçin
Damla yüzeyiniz, uygulamanızın tasarımına bağlıdır. Pencerenin yalnızca bir bölümünün düşme yüzeyi olmasını isteyebilirsiniz, ancak tüm pencereyi kullanabilirsiniz.
Resim sıkıştırma uygulaması Squoosh, kullanıcının pencerenin herhangi bir yerine resim sürüklemesini ve <input type="file">
öğesini çağırmak için bir resim seç'i tıklamasını sağlar. Açılır bölgeniz olarak ne seçerseniz seçin, kullanıcının dosyaları bu yüzeye sürükleyebileceklerinin açıkça anlaşıldığından emin olun.
Bırakma bölgesini tanımlama
Bir öğeyi sürükleyip bırakma bölgesi olarak etkinleştirmek için iki etkinlik için işleyiciler oluşturun: dragover
ve drop
.
dragover
etkinliği, sürükle ve bırak işleminin dosyanın bir kopyasını oluşturmakta olduğunu görsel olarak belirtmek için tarayıcı kullanıcı arayüzünü günceller. Kullanıcı dosyaları yüzeye bıraktıktan sonra drop
etkinliği tetiklenir. Giriş öğesinde olduğu gibi, bir FileList
nesnesi olan event.dataTransfer.files
nesnesindeki dosya listesine de erişebilirsiniz. FileList
içindeki her öğe bir File
nesnesidir.
const dropArea = document.getElementById('drop-area');
dropArea.addEventListener('dragover', (event) => {
event.stopPropagation();
event.preventDefault();
// Style the drag-and-drop as a "copy file" operation.
event.dataTransfer.dropEffect = 'copy';
});
dropArea.addEventListener('drop', (event) => {
event.stopPropagation();
event.preventDefault();
const fileList = event.dataTransfer.files;
console.log(fileList);
});
event.stopPropagation()
ve event.preventDefault()
tarayıcının varsayılan davranışını durdurun ve bunun yerine kodunuzun çalışmasına izin verin. Aksi halde, tarayıcı sayfanızdan ayrılır ve kullanıcının tarayıcı penceresine bıraktığı dosyaları açar.
Canlı demo için Özel sürükle ve bırak bölümüne bakın.
Peki ya dizinler?
Maalesef, JavaScript kullanarak bir dizine erişmenin iyi bir yolu yoktur.
<input type="file">
öğesindeki webkitdirectory
özelliği, kullanıcının bir dizin veya dizin seçebilmesini sağlar. Android için Firefox ve iOS için Safari dışındaki çoğu büyük tarayıcıda desteklenir.
Sürükle ve bırak özelliği etkinse bir kullanıcı, bir dizini bırakma bölgesine sürüklemeyi deneyebilir. Bırakma etkinliği etkinleştiğinde, dizin için bir File
nesnesi içerir ancak dizindeki hiçbir dosyaya erişim sağlamaz.
Dosya meta verilerini okuma
File
nesnesi dosyayla ilgili meta verileri içerir. Çoğu tarayıcı dosya adını, dosyanın boyutunu ve MIME türünü sağlar. Bununla birlikte, platforma bağlı olarak farklı tarayıcılar farklı veya ek bilgiler sağlayabilir.
function getMetadataForFileList(fileList) {
for (const file of fileList) {
// Not supported in Safari for iOS.
const name = file.name ? file.name : 'NOT SUPPORTED';
// Not supported in Firefox for Android or Opera for Android.
const type = file.type ? file.type : 'NOT SUPPORTED';
// Unknown cross-browser support.
const size = file.size ? file.size : 'NOT SUPPORTED';
console.log({file, name, type, size});
}
}
input-type-file
demosunda bunu uygulamalı olarak görebilirsiniz.
Dosya içeriğini okuma
Bir File
nesnesinin içeriğini belleğe okumak için FileReader
kullanın. FileReader
adlı kullanıcıya bir dosyayı dizi arabelleği, veri URL'si veya metin olarak okumasını söyleyebilirsiniz:
function readImage(file) {
// Check if the file is an image.
if (file.type && !file.type.startsWith('image/')) {
console.log('File is not an image.', file.type, file);
return;
}
const reader = new FileReader();
reader.addEventListener('load', (event) => {
img.src = event.target.result;
});
reader.readAsDataURL(file);
}
Bu örnekte, kullanıcı tarafından sağlanan bir File
okunur, ardından bunu bir veri URL'sine dönüştürür ve resmi bir img
öğesinde göstermek için bu veri URL'sini kullanır.
Kullanıcının bir resim dosyası seçtiğini nasıl doğrulayacağınızı öğrenmek için read-image-file
demosuna bakın.
Dosya okuma işleminin ilerlemesini izleme
Büyük dosyaları okurken, kullanıcıya okumanın ne kadar ilerlediğini bildirmek için birtakım kullanıcı deneyimi sunmak yararlı olabilir. Bunun için, FileReader
tarafından sağlanan progress
etkinliğini kullanın. progress
etkinliğinin iki özelliği vardır:
loaded
(okunan miktar) ve total
(okunacak miktar).
function readFile(file) {
const reader = new FileReader();
reader.addEventListener('load', (event) => {
const result = event.target.result;
// Do something with result
});
reader.addEventListener('progress', (event) => {
if (event.loaded && event.total) {
const percent = (event.loaded / event.total) * 100;
console.log(`Progress: ${Math.round(percent)}`);
}
});
reader.readAsDataURL(file);
}
Unsplash'tan Vincent Botta'nın hero resmi