javascript - كيفية تعيين قيمة إدخال الملف عند إسقاط الملف على الصفحة؟



jquery forms (1)

إخلاء المسئولية: تصحيح اعتبارًا من ديسمبر 2017 وللمتصفحات الحديثة فقط.

TL ؛ DR: نعم ، الآن يمكنك!

* إذا كان لديك كائن DataTransfer أو FileList

في السابق ، تم تعطيل تغيير حقل input[type=file] برمجيًا بسبب الثغرات الأمنية القديمة ، والتي تم إصلاحها على المتصفحات الحديثة.

آخر المتصفحات الرئيسية (Firefox) ، قد مكننا مؤخرًا من تعيين الملفات لحقل ملف الإدخال. وفقًا لاختبار W3C ، يبدو أنه يمكنك فعل ذلك بالفعل على Google Chrome!

لقطة الشاشة ذات الصلة والنص المقتبس من MDN:

يمكنك كذلك تعيين قيمة HTMLInputElement.files في جميع المتصفحات الحديثة.
توافق المصدر والمستعرض ، راجع

يحتوي مؤشر ترابط مناقشة bugfix في Firefox على هذا العرض التوضيحي الذي يمكنك اختباره ، وهنا المصدر إذا كنت ترغب في تحريره . للرجوع إليها مستقبلاً في حالة وفاة هذا الرابط ، سوف أدرجه أيضًا في شكل مقتطف قابل للتشغيل أدناه:

let target = document.documentElement;
let body = document.body;
let fileInput = document.querySelector('input');

target.addEventListener('dragover', (e) => {
  e.preventDefault();
  body.classList.add('dragging');
});

target.addEventListener('dragleave', () => {
  body.classList.remove('dragging');
});

target.addEventListener('drop', (e) => {
  e.preventDefault();
  body.classList.remove('dragging');
  
  fileInput.files = e.dataTransfer.files;
});
body {
  font-family: Roboto, sans-serif;
}

body.dragging::before {
  content: "Drop the file(s) anywhere on this page";
  position: fixed;
  left: 0; width: 100%;
  top: 0; height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 1.5em;
  background-color: rgba(255, 255, 0, .3);
  pointer-events: none;
}

button, input {
  font-family: inherit;
}

a {
  color: blue;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
      <link href="https://fonts.googleapis.com/css?family=Roboto:400,400i,700" rel="stylesheet"> 

  <title>JS Bin</title>
</head>
<body>
  
  <h1>Drag and drop files into file input</h1>
  
  <p><small>Supported in <a href="https://github.com/whatwg/html/issues/2861">WebKit and Blink</a>. To test, drag and drop one or more files from your operating system onto this page.</small></p>
  
  <p>
    <input type="file">
  </p>

</body>
</html>

ملاحظة مهمة:

يمكنك القيام بذلك فقط إذا كان لديك كائن FileList أو كائن dataTransfer يمكنك ضبطه على عنصر ملف الإدخال (حيث لا تقبل طريقة setter سلاسل نصية عادية).

لمزيد من المعلومات ، راجع إجابة كايدو هنا: كيفية تعيين كائنات الملف وخاصية الطول في كائن FileList حيث تنعكس الملفات أيضًا في كائن FormData؟

الآن للإجابة على سؤالك الأصلي ، يجب أن يكون الأمر بهذه البساطة:

document.querySelector('.preview-image-instruction')
    .addEventListener('drop', (ev) => {
        ev.preventDefault();
        document.querySelector('.image-url').files = ev.dataTransfer.files;
    });

أحاول إجراء تحكم حيث يمكنك تحديد ملف لتقديمه في النموذج وإسقاط ملف فيه للقيام بالشيء نفسه. لدي شيء مثل هذا ، حيث سيُظهر أيضًا معاينة للملف إذا كانت صورة:

<div class="preview-image-container">

  <input type="file" name="File" id="File" accept="image/*" 
         class="image-url form-control" style="display:none;" />

  <div class="preview-image-dummy"></div><img class="preview-image-url" />
  <div class="preview-image-instruction">
    <div class="preview-image-btn-browse btn btn-primary">Select file</div>
    <p>or drop it here.</p>
  </div>

</div>

وإليك كمان مع MCVE .

يسقط المستخدم الملف في preview-image-container . لم يتم تقديم الملف مع AJAX ، يحتاج المستخدم إلى إرسال النموذج الذي يحتوي على المزيد من البيانات.

لأسباب أمنية ، لا يُسمح لنا بتغيير قيمة ملف الإدخال باستخدام JavaScript. ومع ذلك ، فأنا أعلم أن ملف الإدخال الافتراضي يدعم droppable وهناك مجموعة من مواقع الويب التي تتيح لنا تحديد الملفات عن طريق إسقاطها في النموذج لذلك أعتقد أن هناك طريقة للقيام بذلك.

كما ترى من MCVE ، أنا مهتم باستخدام jQuery أو JavaScript فقط بدون مكتبات إضافية.

على الرغم من إمكانية استخدام dropzone.js ، إلا أنه لا يلائم متطلباتي ويتطلب قدراً كبيراً من الوقت لتخصيص مظهره. علاوة على ذلك ، لدى dropzone.js متطلبات تكوين معينة لا يمكن الوفاء بها في تطبيق ASP.NET الخاص بي.

هناك سؤال مشابه ولكن ليس لديه إجابة مناسبة:
كيفية تعيين كائن ملف في ملف الإدخال في النموذج في HTML؟

كما لا يشبه سحب ملف إدخال الصور والمعاينة قبل التحميل لأنني حققت بالفعل إجراء السحب والإفلات. سؤالي خاص بمشكلة وجود إدخال ملف فارغ عند إسقاط الملف في حاوية الأصل.





events