javascript - วิธีเปิดหน้าต่างเลือกไฟล์ผ่าน js?
$('#id').click();
มันใช้งานไม่ได้บน Chrome 26 บน Mac OS
ปัญหาจริงๆ คือการสร้างวิดเจ็ต "อัปโหลด" ที่สามารถรวมเข้ากับฟอร์มได้ วิดเจ็ตจะประกอบด้วยสองส่วน ส่วนแรกคือ div ที่มีปุ่มเริ่มต้นและข้อความข้อผิดพลาด/สำเร็จ ผมคิดว่าวิธีคือการใส่ฟอร์มอีกอันเป็นส่วนที่สองพร้อมช่องป้อนไฟล์และส่งไฟล์ไปยัง iframe หลังจากการส่ง เราจะเติมฟิลด์ซ่อนในส่วนแรกของฟอร์มหลักหรือแสดงข้อผิดพลาดในส่วนเดียวกัน
วิธีที่ง่ายคือการเพิ่มฟอร์มไฟล์เข้าไปในฟอร์มหลัก แต่ถูกห้ามไว้
คำตอบ #1
ใช้เฉพาะ JS - ไม่จำเป็นต้องใช้ jquery
เพียงสร้างองค์ประกอบอินพุตแล้วกระตุ้นการคลิก
var input = document.createElement('input');
input.type = 'file';
input.click();
นี่คือพื้นฐานที่สุด เปิดหน้าต่างเลือกไฟล์ แต่ไม่มีประโยชน์อะไรหากไม่จัดการกับไฟล์ที่เลือก...
การจัดการแฟ้ม
การเพิ่มเหตุการณ์ onchange ให้กับอินพุตที่สร้างขึ้นใหม่จะช่วยให้เราสามารถทำสิ่งต่างๆ ได้เมื่อผู้ใช้ได้เลือกไฟล์แล้ว
var input = document.createElement('input');
input.type = 'file';
input.onchange = e => {
var file = e.target.files[0];
}
input.click();
ในขณะนี้เรามีตัวแปรไฟล์ที่เก็บข้อมูลต่าง ๆ :
file.name // the file's name including extension
file.size // the size in bytes
file.type // file type ex. 'application/pdf'
เยี่ยม!
แต่ถ้าเราจำเป็นต้องใช้เนื้อหาของไฟล์ล่ะ?
เพื่อที่จะเข้าถึงเนื้อหาที่แท้จริงของไฟล์ ด้วยเหตุผลหลายประการ เช่น วางภาพ โหลดลงในแคนวาส สร้างหน้าต่างด้วย URL ข้อมูล Base64 เป็นต้น เราจำเป็นต้องใช้ API FileReader
เราจะสร้างอินสแตนซ์ของ FileReader และโหลดไฟล์ที่ผู้ใช้เลือกไปยังมัน
var input = document.createElement('input');
input.type = 'file';
input.onchange = e => {
// getting a hold of the file reference
var file = e.target.files[0];
// setting up the reader
var reader = new FileReader();
reader.readAsText(file,'UTF-8');
// here we tell the reader what to do when it's done reading...
reader.onload = readerEvent => {
var content = readerEvent.target.result; // this is the content!
console.log( content );
}
}
input.click();
ลองวางโค้ดข้างต้นลงในหน้าต่างคอนโซลของเครื่องมือสำหรับนักพัฒนาของคุณ มันควรจะแสดงกล่องโต้ตอบเลือกไฟล์ หลังจากเลือกไฟล์แล้ว คอนโซลควรจะแสดงเนื้อหาของไฟล์นั้น
ตัวอย่าง - "ภาพพื้นหลังใหม่ของ Stackoverflow!"
ลองสร้างกล่องโต้ตอบการเลือกไฟล์เพื่อเปลี่ยนภาพพื้นหลังของ stackoverflow เป็นอะไรที่น่าตื่นเต้นมากขึ้น...
var input = document.createElement('input');
input.type = 'file';
input.onchange = e => {
// getting a hold of the file reference
var file = e.target.files[0];
// setting up the reader
var reader = new FileReader();
reader.readAsDataURL(file); // this is reading as data url
// here we tell the reader what to do when it's done reading...
reader.onload = readerEvent => {
var content = readerEvent.target.result; // this is the content!
document.querySelector('#content').style.backgroundImage = 'url('+ content +')';
}
}
input.click();
เปิด devtools แล้ววางโค้ดด้านบนลงในหน้าต่างคอนโซล ซึ่งจะมีหน้าต่างเลือกไฟล์ปรากฏขึ้น เมื่อเลือกภาพ พื้นหลังของกล่องเนื้อหาบน Stackoverflow จะเปลี่ยนเป็นภาพที่เลือก
คำตอบ #2
การใช้ jQuery
ฉันจะสร้างปุ่มและอินพุตที่มองไม่เห็นดังนี้:
<button id="button">Open</button>
<input id="file-input" type="file" name="name" style="display: none;" />
และเพิ่ม jQuery บางส่วนเพื่อทริกเกอร์มัน:
$('#button').on('click', function() {
$('#file-input').trigger('click');
});
การใช้ Vanilla JS
แนวคิดเดียวกัน แต่ไม่ใช้ jQuery (ขอบคุณ @Pascale):
<button onclick="document.getElementById('file-input').click();">Open</button>
<input id="file-input" type="file" name="name" style="display: none;" />
คำตอบ #3
ฟังก์ชันพร้อมใช้งาน (ใช้ Promise)
/**
* Select file(s).
* @param {String} contentType The content type of files you wish to select. For instance, use "image/*" to select all types of images.
* @param {Boolean} multiple Indicates if the user can select multiple files.
* @returns {Promise<File|File[]>} A promise of a file or array of files in case the multiple parameter is true.
*/
function selectFile(contentType, multiple){
return new Promise(resolve => {
let input = document.createElement('input');
input.type = 'file';
input.multiple = multiple;
input.accept = contentType;
input.onchange = () => {
let files = Array.from(input.files);
if (multiple)
resolve(files);
else
resolve(files[0]);
};
input.click();
});
}
ลองที่นี่
// Content wrapper element
let contentElement = document.getElementById("content");
// Button callback
async function onButtonClicked(){
let files = await selectFile("image/*", true);
contentElement.innerHTML = files.map(file => `<img src="${URL.createObjectURL(file)}" style="width: 100px; height: 100px;">`).join('');
}
// ---- function definition ----
function selectFile (contentType, multiple){
return new Promise(resolve => {
let input = document.createElement('input');
input.type = 'file';
input.multiple = multiple;
input.accept = contentType;
input.onchange = _ => {
let files = Array.from(input.files);
if (multiple)
resolve(files);
else
resolve(files[0]);
};
input.click();
});
}<button onclick="onButtonClicked()">Select images</button>
<div id="content"></div>คำตอบ #4
ใน HTML เท่านั้น:
<label>
<input type="file" name="input-name" style="display: none;" />
<span>Select file</span>
</label>
ตรวจสอบฟิดเดิลนี้กับโค้ดด้านบน
คำตอบ #5
เพื่อความครบถ้วน สมบัติของ Ron van der Heijden ในรูปแบบ JavaScript ล้วน:
<button onclick="document.querySelector('.inputFile').click();">Select File ...</button>
<input class="inputFile" type="file" style="display: none;">
คำตอบ #6
เพื่อขยายคำตอบจาก 'levi' และเพื่อแสดงวิธีการรับการตอบกลับจากการอัปโหลดเพื่อให้คุณสามารถประมวลผลการอัปโหลดไฟล์ได้:
selectFile(event) {
event.preventDefault();
file_input = document.createElement('input');
file_input.addEventListener("change", uploadFile, false);
file_input.type = 'file';
file_input.click();
},
uploadFile() {
let dataArray = new FormData();
dataArray.append('file', file_input.files[0]);
// Obviously, you can substitute with JQuery or whatever
axios.post('/your_super_special_url', dataArray).then(function() {
//
});
}
