2017-11-05 8 views
17

<input type="file"> तत्व FileList पर तत्व .files संपत्ति या DataTransfer.files संपत्ति से .files संपत्ति सेट करना संभव है। Make .files settable #2866, What happens between uploading a file to an HTML form and submitting it? देखें।फ़ाइल ऑब्जेक्ट्स पर फ़ाइल ऑब्जेक्ट्स और लम्बाई प्रॉपर्टी कैसे सेट करें, जहां फाइल फॉर्मडाटा ऑब्जेक्ट पर भी दिखाई देती है?

FileList वस्तु एक Symbol.iterator संपत्ति है जो हम एक File वस्तु जो iterable है, तथापि .files.length अभी भी 0 पर सेट है स्थापित करने के लिए उपयोग कर सकते हैं और गुजर एक <form><input type="file"> सेट जहां .files ऊपर दृष्टिकोण का उपयोग कर एक पैदावार होने के लिए निर्धारित है File ऑब्जेक्ट .size0 पर सेट है।

कैसे FileList पर File सेट और सेट फ़ाइलों की संख्या, जहां फाइलों FormData() वस्तु पर सेट कर रहे हैं करने के लिए FileList की .length स्थापित करने के लिए?

const input = document.createElement("input"); 
 

 
const form = document.createElement("form"); 
 

 
const [...data] = [ 
 
    new File(["a"], "a.txt") 
 
, new File(["b"], "b.txt") 
 
]; 
 

 
input.type = "file"; 
 

 
input.name = "files"; 
 

 
input.multiple = true; 
 
// set `File` objects at `FileList` 
 
input.files[Symbol.iterator] = function*() { 
 
    for (const file of data) { 
 
    yield file 
 
    }; 
 
}; 
 

 
form.appendChild(input); 
 

 
const fd = new FormData(form); 
 

 
for (const file of input.files) { 
 
    console.log(file); // `File` objects set at `data` 
 
} 
 

 
for (const [key, prop] of fd) { 
 
    // `"files"`, single `File` object having `lastModified` property 
 
    // set to a time greater than last `File` object within `data` 
 
    // at Chromium 61, only `"files"` at Firefox 57 
 
    console.log(key, prop); 
 
} 
 

 
console.log(input.files.length); // 0

+0

FF57 में तय किया गया है को देखने के https://developer.mozilla.org/en-US/Firefox/Releases/57#DOM –

उत्तर

11

संपादित करें:

ओपी द्वारा सिद्ध के रूप में, their gist में से एक में, वहाँ वास्तव में यह करने के लिए एक रास्ता है ...

DataTransfer constructor (वर्तमान में केवल ब्लिंक द्वारा समर्थित), एक म्यूटेबल फ़ाइललिस्ट बनाना चाहिए (क्रोम वर्तमान में हमेशा एक नई फ़ाइलसूची लौटाता है, लेकिन यह वास्तव में नहीं है हमारे लिए एटर), DataTransferItemList के माध्यम से सुलभ।

यदि मुझे गलत नहीं है, तो यह वर्तमान में ऐसा करने का एकमात्र चश्मा-वार तरीका है, लेकिन फ़ायरफ़ॉक्स को ClipboardEvent constructor के कार्यान्वयन में भी एक बग दिखाई देता है, जहां वही डेटाट्रांसफरइटम लिस्ट सुलभ है और मोड पर सेट है पढ़ें/लिखें। मुझे चश्मे की मेरी व्याख्या के बारे में निश्चित नहीं है, लेकिन मेरा मानना ​​है कि इसे सामान्य रूप से सुलभ नहीं किया जाना चाहिए)।

const dT = new ClipboardEvent('').clipboardData || // Firefox bug? 
 
    new DataTransfer();        // specs compliant 
 
dT.items.add(new File(['foo'], 'programmatically_created.txt')); 
 
inp.files = dT.files;
<input type="file" id="inp">

इस खोज इस new Proposal करने के लिए नेतृत्व किया है FileList बनाने के लिए डिफ़ॉल्ट रूप से परिवर्तनशील वस्तुओं:

तो रास्ता guest271314 एक FileList पर मनमाने ढंग से फ़ाइलें स्थापित करने के लिए मिल गया इस प्रकार है , क्योंकि ऐसा करने के लिए अब कोई मुद्दा नहीं है।


पिछला (पुराना) जवाब

आप नहीं कर सकते। फाइललिस्ट ऑब्जेक्ट्स स्क्रिप्ट द्वारा संशोधित नहीं किया जा सकता *।

आप केवल एक इनपुट फ़ाइल फ़ाइल को किसी अन्य फ़ाइललिस्ट में बदल सकते हैं, लेकिन आप इसे संशोधित नहीं कर सकते *।
(* input.value = null के साथ खाली करने के अलावा)।

और आप या तो स्क्रॉल से फ़ाइललिस्ट नहीं बना सकते हैं, केवल DataTransfer ऑब्जेक्ट्स जिन्हें बनाया नहीं जा सकता है, और input[type=file] ऐसी ऑब्जेक्ट्स बनाएगा।

आप को दिखाने के लिए है कि एक अन्य इनपुट के एक करने के लिए एक input[type=file] FileList की स्थापना तब भी जब कोई नया FileList बनाई गई है:

var off = inp.cloneNode(); // an offscreen input 
 

 
inp.onchange = e => { 
 
    console.log('is same before', inp.files === off.files); 
 
    off.files = inp.files; // now 'off' does have the same FileList as 'inp' 
 
    console.log('is same after', inp.files === off.files); 
 
    console.log('offscreen input FileList', off.files); 
 
    console.log('resetting the offscreen input'); 
 
    off.value = null; 
 
    console.log('offscreen input FileList', off.files);   
 
    console.log('inscreen input FileList', inp.files); 
 
}
<input type="file" id="inp">

ओह और मैं लगभग, FormData हिस्सा भूल गया कि मैं डॉन सच में सच नहीं कहता ...

तो अगर मुझे यह ठीक हो गया, तो आपको बस FormData.append():

var fd = new FormData(); 
 

 
fd.append("files[]", new Blob(['a']), 'a.txt'); 
 
fd.append("files[]", new Blob(['b']), 'b.txt'); 
 

 
for(let pair of fd.entries()) { 
 
    console.log(pair[0], pair[1]); 
 
}

+0

बेहतर नहीं होगा पिछली बाहर संपादित करने के लिए उत्तर (जिसे अभी भी संपादन इतिहास द्वारा संदर्भित किया जा सकता है), ताकि उत्तर अधिक संक्षिप्त हो सके? –

+0

@ सैमुएल देखें नया हिस्सा अभी भी * मुख्य रूप से एक हैक * है। नए चश्मे (आज के रूप में केवल ब्लिंक में लागू) इसे अनुमति देते हैं, लेकिन यह वास्तव में डिजाइन द्वारा नहीं है, यह एक संयोग है। एफएफ फॉलबैक उनके कार्यान्वयन में मामूली बग का दुरुपयोग है। तो यह एक दिलचस्प हैक है, जो शायद [वास्तविक एपीआई की ओर ले जाएगा] (https://github.com/whatwg/html/issues/3269), समय के लिए, मुझे विश्वास है कि इस उत्तर का दूसरा भाग है अभी भी जरूरी है, इसके अलावा, यह अभी भी वैध होगा, यहां तक ​​कि एक फ़ाइललिस्ट कन्स्ट्रक्टर के साथ: आप एक फ़ाइललिस्ट को संशोधित करने में सक्षम नहीं होंगे, केवल नए बनाएं। – Kaiido

संबंधित मुद्दे