Kullanıcının yerel cihazındaki dosyaları seçmek ve dosyalarla etkileşime geçmek, web'in en yaygın olarak kullanılan özelliklerinden biridir. Kullanıcıların, fotoğraf paylaşırken veya vergi belgeleri gönderirken dosyaları seçip bir sunucuya yüklemesine olanak tanır. Ayrıca, sitelerin verileri ağ üzerinden aktarmak zorunda kalmadan okumasına ve değiştirmesine olanak tanır. Bu sayfada, dosyalarla etkileşim kurmak için JavaScript'in nasıl kullanılacağı açıklanmaktadır.
Modern File System Access API
File System Access API, kullanıcının yerel sistemindeki dosya ve dizinleri okumanın ve bu dosyalara yazmanın bir yolunu sağlar. Chrome ve Edge gibi Chromium tabanlı çoğu tarayıcıda kullanılabilir. Bu konu hakkında daha fazla bilgi edinmek için File System Access API başlıklı makaleyi inceleyin.
File System Access API tüm tarayıcılarla uyumlu olmadığından, mevcut olduğu her yerde yeni API'yi kullanan ve mevcut olmadığı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ışma
Bu kılavuzda, eski JavaScript yöntemlerini kullanarak dosyalarla nasıl etkileşime geçeceğiniz gösterilmektedir.
Dosya seç
Dosya seçmenin iki temel yolu vardır: HTML giriş öğesini ve sürükle ve bırak bölgesini kullanmak.
HTML giriş öğesi
Kullanıcıların dosya seçmesinin en kolay yolu, tüm büyük tarayıcılarda desteklenen <input type="file">
öğesini kullanmaktır. Tıklandığında kullanıcının işletim sisteminin yerleşik dosya seçimi kullanıcı arayüzünü kullanarak bir dosya veya multiple
özelliği eklenmişse birden fazla dosya seçmesine olanak tanır. Kullanıcı bir veya daha fazla dosya seçmeyi tamamladığında öğenin change
etkinliği tetiklenir. Dosya listesine FileList
nesnesi olan event.target.files
üzerinden erişebilirsiniz.
FileList
alanındaki 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 örnekte, kullanıcının işletim sisteminin yerleşik dosya seçim kullanıcı arayüzünü kullanarak birden fazla dosya seçmesi ve ardından seçilen her dosyayı konsola kaydetmesi sağlanmaktadır.
Kullanıcıların seçebileceği dosya türlerini sınırlama
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 etmeli, metin dosyalarını kabul etmemelidir. Dosya türü kısıtlamaları belirlemek için hangi dosya türlerinin kabul edildiğini belirtmek üzere giriş öğesine bir accept
özelliği ekleyin:
<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, kullanıcıların dosyalarını uygulamanıza sürükleyip bırakmasına olanak tanıyan bir bırakma hedefidir. Ancak bu bırakma hedefi küçüktür ve kullanımı zor olabilir. Bunun yerine, <input type="file">
öğesini kullanarak temel özellikleri sağladıktan sonra büyük, özel bir sürükle ve bırak yüzeyi sunabilirsiniz.
Bırakma bölgenizi seçin
Düşürme yüzeyiniz, uygulamanızın tasarımına bağlıdır. Pencerenin yalnızca bir kısmının dosya bırakma yüzeyi olmasını isteyebilirsiniz ancak pencerenin tamamını kullanabilirsiniz.
Squoosh resim sıkıştırma uygulaması, kullanıcının pencereye bir resim sürüklemesine ve <input type="file">
öğesini çağırmak için resim seç'i tıklamasına olanak tanır. Dosya bırakma bölgesi olarak neyi seçerseniz seçin, kullanıcının bu yüzeye dosya sürükleyebileceğinden emin olun.
Bırakma bölgesini tanımlama
Bir öğeyi sürükle ve bırak 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şturduğunu görsel olarak belirtmek için tarayıcı kullanıcı arayüzünü günceller. drop
etkinliği, kullanıcı dosyaları yüzeye bıraktıktan sonra tetiklenir. input öğesinde olduğu gibi, FileList
nesnesi olan event.dataTransfer.files
öğesinden dosya listesine 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ı durdurur ve bunun yerine kodunuzun çalışmasını sağlar. Aksi takdirde tarayıcı, sayfanızdan ayrılır ve kullanıcının tarayıcı penceresine bıraktığı dosyaları açar.
Canlı bir gösterim için Özel sürükle ve bırak bölümüne bakın.
Dizinler ne olacak?
Maalesef JavaScript kullanarak bir dizine erişmenin iyi bir yolu yoktur.
<input type="file">
öğesindeki webkitdirectory
özelliği, kullanıcının bir veya daha fazla dizin seçmesine olanak tanır. Android için Firefox ve iOS'teki Safari hariç büyük tarayıcıların çoğunda desteklenir.
Sürükle ve bırak özelliği etkinse kullanıcılar bir dizini bırakma alanına sürüklemeyi deneyebilir. Bırakma etkinliği tetiklendiğinde, dizin için bir File
nesnesi içerir ancak dizindeki dosyalardan hiçbirine erişim sağlamaz.
Dosya meta verilerini okuma
File
nesnesi, dosyayla ilgili meta verileri içerir. Çoğu tarayıcı dosya adını, dosya boyutunu ve MIME türünü sağlar. Ancak 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});
}
}
Bu özelliğin işleyiş şeklini input-type-file
demosunda görebilirsiniz.
Dosya içeriğini okuma
File
nesnesinin içeriğini belleğe okumak için FileReader
özelliğini kullanın. FileReader
'e 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 veri URL'sine dönüştürülür ve resmi bir img
öğesinde görüntülemek için bu veri URL'si kullanılı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 ilerleme durumunu izleme
Büyük dosyalar okunurken kullanıcıya okuma işleminin ne kadar ilerlediğini bildirmek için 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 tarafından oluşturulan hero resim