نستمر في إنشاء تنزيلات السحب والإسقاط، واليوم سنكتب خادمنا ونبدأ في كتابة كود JavaScript.
في المقالة الأخيرة قمنا بكتابة ملف Index.html وأنماطه. سنكتب اليوم خادمًا يقوم بتنزيل الملفات وإرسال المعلومات المتعلقة بها مرة أخرى إلى البرنامج النصي، ولكن دعونا نتحدث أولاً عن بنية الملف التي سنحصل عليها:
كل شيء واضح مع ملفات Index.html وstyle.css. نقوم ببساطة بتعيين الترميز في ملف .htaccess حتى لا تكون هناك مشاكل.
AddDefaultCharset UTF-8
سيقوم ملف upload.php بتحميل الملفات إلى الخادم في مجلد التحميلات.
لذلك دعونا نبدأ مع PHP. للقيام بذلك، افتح ملف upload.php واكتب ما يلي:
في بداية الملف نكتب رأس نوع المحتوى لإخبار المتصفح بأنه سيتلقى ملف json. ثم نقوم بإنشاء مصفوفة فارغة تم تحميلها $ ونتحقق من وجود أي ملفات على الإطلاق. إذا كانت الإجابة بنعم، فإننا نراجعها ونرفعها إلى دليل التحميلات الخاص بنا، ونملأ أيضًا مصفوفتنا الرئيسية $uploaded بمصفوفات فرعية تحتوي على معلومات حول الملفات. في حالتنا، هذا هو اسم الملف وموقعه. أخيرًا، نقوم بتحويل المصفوفة إلى json وإخراجها. كما ترون، الخادم ليس معقدا على الإطلاق.
الآن دعنا ننتقل إلى ملف Index.html
اسحب الملفات هنا
(وظيفة() (
var dropzone = document.getElementById("dropzone");
dropzone.ondragover = function() (
this.className = "سحب منطقة الإسقاط";
this.innerHTML = "حرر الماوس";
عودة كاذبة؛
};
Dropzone.ondragleave = function() (
عودة كاذبة؛
};
Dropzone.ondrop = الوظيفة (هـ) (
this.className = "dropzone";
this.innerHTML = "اسحب الملفات هنا";
e.preventDefault();
};
})();
هل تتذكر فئة .dragover التي كتبناها في المقالة الأخيرة، وقلت أنه سيتم استخدامها عندما يكون هناك ملف ما فوق الكتلة الخاصة بنا؟ وهذا في الواقع ما فعلناه الآن. عندما يظهر ملف ما فوق الكتلة، يتم إطلاق حدث ondragover، حيث نقوم ببساطة بإضافة فئة .dragover وتغيير النص إلى "حرر الماوس". عندما نحرك الماوس بالملف بعيدًا عن الكتلة الخاصة بنا، يتم تشغيل حدث ondragleave، حيث نعيد كل شيء إلى موضعه الأصلي. عندما "يسقط" شخص ما ملفًا في الكتلة الخاصة بنا، يتم تشغيل حدث ondrop. هناك نقوم بتغيير كل شيء مرة أخرى، كما كان في البداية، وإلا فإن فئة .dragover الخاصة بنا سوف "تتجمد" وتلغي السلوك الافتراضي. إذا لم نفعل ذلك، فسيتم فتح ملفنا ببساطة في المتصفح، وهذا ليس ما نريده.
تحياتي للجميع! أريد في هذه المقالة أن أتحدث عن العديد من تجاربي مع HTML5. سأبدأ من بعيد. يتعين علينا جميعًا العمل بشكل دوري مع واجهات الويب المختلفة وغالبًا ما نشعر أنه يمكن تنظيم هذا العمل بشكل أكثر كفاءة.
ربما يقع اللوم في بعض الحالات على مطوري الخدمة، ولكن غالبًا ما تكمن المشكلة في القيود التي تفرضها المتصفحات. دعونا نفكر في تحميل الملفات إلى الخادم. في معظم الحالات، سيظهر لك حقل قياسي يحتوي على زر لتحديد ملف من جهاز الكمبيوتر الخاص بك و/أو حقل يمكنك من خلاله تحديد عنوان URL لملف موجود في مكان ما على الإنترنت.
لن نتطرق إلى تنزيل الملفات من جهاز كمبيوتر محلي في الوقت الحالي، وأخطط لنشر منشور منفصل حول هذا الموضوع، فلننظر إلى التنزيل من خادم بعيد.
المشاكل تبدأ من الخطوة الأولى. حتى إذا كنت تفهم بوضوح مكان البحث عن عنوان URL وتجيد استخدام أدوات مثل firebug، فسيظل الأمر يتطلب بضع نقرات للحصول على العنوان الصحيح. سيكون الأمر أكثر ملاءمة لسحب الصورة المطلوبة من نافذة متصفح إلى أخرى.
سأعرض مثالاً على تنفيذ مثل هذه الواجهة في هذه المقالة. إذا كنت تريد، يمكنك أن ترى كيف يعمل على الصفحة التجريبية أو .
ملحوظة! هذا المثال يعمل فقط في متصفح Google Chrome. من الناحية النظرية، يدعم Firefox وSafari جميع التقنيات الضرورية، لكنني لم أكتشفها بعد. كأشياء "للسحب"، التقطت بشكل أساسي صورًا من ويكيبيديا. تمت ملاحظة العديد من المشكلات المتعلقة بالأحرف غير اللاتينية في عناوين URL للصور، ولكن لكي لا أثقل كاهل المثال بعمليات التحقق والتحويلات، تركتها كما هي.
مبدأ التشغيل
يوفر معيار HTML5 الدعم لسحب وإفلات كائنات الصفحة. بالمناسبة، لقد أظهرت بالفعل مثالا على أبسط تنفيذ D&D - السحب والإسقاط باستخدام HTML5. وإلى جانب ذلك، هناك عدد لا بأس به من مكتبات JavaScript التي تنفذ دعم D&D.
ولكن من المهم هنا أن تفهم أنه إذا كنت بحاجة إلى "سحب" الصور من موارد الطرف الثالث، فلن تتمكن من استخدام المكتبات. لأن لن تتمكن من إضافة كود JS الخاص بك إلى صفحة شخص آخر. ومن أجل تنزيل صورة، نحتاج إلى الحصول على عنوان URL الخاص بها، أي. يجب أن ينقل المتصفح أيضًا معلماته مع الكائن المسحوب (على سبيل المثال، سمة src لصورة ما أو علامة img بأكملها).
في هذه الحالة، يمكننا إنشاء "مستقبل" للصور على صفحتنا. سيكون هذا قسمًا عاديًا مع تعيين معالج حدث الإسقاط. إذا قام المستخدم "بإسقاط" الصورة فوق هذا القسم، فسيتم استدعاء المعالج وسيتلقى في المعلمة الأولى كائنًا يحتوي على معلومات حول الصورة التي يتم سحبها.
تطبيق
لنبدأ بصفحة التطبيق الخاصة بنا.
تحميل الصور
يحتوي على كتلتين: الصور - هنا سنعرض الصور التي تم تنزيلها وimg_target - تحتاج إلى سحب الصور إلى هذه الكتلة. في أسفل الصفحة، نقوم بتوصيل مكتبة jQuery والبرنامج النصي main.js، الذي سيرسل معلومات حول الصور المسحوبة إلى الخادم.
دعونا نلقي نظرة على main.js
$(وظيفة() (
$("#img_target")
.bind("dragenter"، الوظيفة(الحدث) (
$(this).addClass("drop_here");
عودة كاذبة؛
})
.bind("dragleave"، الوظيفة(الحدث) (
عودة كاذبة؛
})
.bind("dragover"، الوظيفة(الحدث) (
عودة كاذبة؛
})
.bind("إسقاط"، وظيفة(حدث) (
$(this).removeClass("drop_here");
var srcRegex = /src=\"([^\s]+)\"/ig;
var data = events.originalEvent.dataTransfer.getData("text/html");
var img_data = srcRegex.exec(data);
$.post("upload.php", ("file_url":img_data), الوظيفة(الدقة) (
استجابة var = eval("(" + res + ")");
$("#images").append($(""));
});
عودة صحيحة؛
});
});
نقوم هنا بتعيين معالجات لأحداث Dragenter وDragleave وDrover. يجب أن تقوم جميعها ببساطة بإرجاع خطأ، ومن أجل إعلام المستخدم بطريقة أو بأخرى أنه يمكن "إسقاط" الصورة، في معالج Dragenter، قمنا بتعيين فئة CSS drop_here لكتلة جهاز الاستقبال. يتم تنفيذ معظم العمل في معالج حدث الإسقاط. عند حدوث هذا الحدث، نقرأ معلومات حول كائن "إعادة التعيين" و"نقطع" قيمة السمة src، أي. عنوان URL للصورة. يتم نقل المعلومات في كائن events.originalEvent.dataTransfer.
ثم نقوم بتكوين طلب AJAX عادي ونمرر عنوان URL الذي تم العثور عليه كمعلمة. سيتلقى البرنامج النصي للخادم (upload.php) عنوان URL للصورة على الخادم البعيد ويقوم بتحميله. واستجابة لطلب AJAX، سيتم إرسال عنوان URL الجديد للصورة المحملة. بدوره، سيقوم معالج طلب AJAX بإنشاء علامة img وإدراجها في كتلة الصور. وبالتالي ستظهر الصور التي تم تنزيلها أعلى حقل التنزيل.
فكر في upload.php
مبدأ التشغيل هو على النحو التالي. نقرأ عنوان URL للصورة ونحاول تنزيلها. إذا تم تحميل الصورة، فاحفظها في مجلد التحميل. يتم استلام الصورة من خادم بعيد باستخدام وظائف fread. تتم قراءة الملف في كتل بحجم 1 كيلو بايت. يتيح لك هذا الأسلوب مقاطعة تنزيل الملف إذا تجاوز حجمه حدًا محددًا (300 كيلو بايت في هذه الحالة).
بعد تنزيل الملف، نقوم بإنشاء عنوان URL له وإرساله إلى المتصفح بتنسيق JSON. كما ترون، تنفيذ مثل هذا محمل الإقلاع ليس بالأمر الصعب. وهي مريحة جدًا للاستخدام. بطبيعة الحال، العيب الرئيسي هو دعم المتصفحات لـ HTML5، أو بالأحرى عدم وجودها، ومع ذلك، إذا كنت تقوم بإنشاء واجهة لموظفي الشركة، ويمكنك تحديد نوع المتصفح، فيمكن استخدام HTML5.
وسأعرض لك في هذا الدرس مثالاً على دمج المكون الإضافي الرائع Dropzone.js مع موقع PHP الخاص بك لتحميل الملفات إلى الخادم في بضعة أسطر فقط من التعليمات البرمجية.
Dropzone.JS هي مكتبة رائعة مفتوحة المصدر مكتوبة بلغة Vanilla JS والتي توفر لك واجهة السحب والإفلات لتحميل الملفات مع معاينات الملفات.
أولاً قم بتحميل الإصدار الأخير من المكتبة وأنماطها:
ثم قم بإنشاء مجلد التحميلات وملفات Index.php وupload.php
يمكن أن يكون ملف الفهرس php ذلك الجزء من التعليمات البرمجية الخاصة بك الذي يحتوي على نموذج إضافة مواد إلى الموقع. في المثال الخاص بي، سأقوم بإنشاء صفحة فارغة مع الحد الأدنى من العلامات ومكتبة وأنماط Dropzone.js المضمنة:
كما لاحظت على الأرجح، قمنا بإنشاء نموذج باستخدام الإجراء upload.php، لكننا لم نقم بإنشاء أي مدخلات لإرفاق الملفات، ولم نعلن عن نوع النموذج. لا يوجد خطأ في هذا، كل شيء يتم التعامل معه بواسطة مكتبة DropzoneJS نفسها. كل ما يتعين علينا فعله هو إعطاء النموذج فئة Dropzone. افتراضيًا، يبحث DropzoneJS عن جميع النماذج التي تحتوي على هذه الفئة ويرسم واجهته تلقائيًا.
يمكنك فتح صفحة Index.php للتنفيذ في المتصفح والتأكد من أن المكتبة تعمل على النحو المنشود. وهنا ما حصلت عليه:
لنقم الآن بإنشاء معالج تحميل قمنا بإنشاء ملف upload.php له بالفعل. فيما يلي مثال لأبسط كود التحميل الخاص بي:
العمل مع الملفات التي تم تنزيلها
للتفاعل بشكل كامل مع ملفاتك، نحتاج فقط إلى إضافة القدرة على معالجتها. أولاً، نحتاج إلى إضافة جزء من التعليمات البرمجية لاستخراج المعلومات حول الملفات المخزنة (الاسم والحجم) وإعادتها بتنسيق JSON.
للقيام بذلك، قم بتحديث ملف upload.php إلى هذا النموذج (يتم إدراج شرط آخر):
حان الوقت الآن لتحديث ملف Index.php:
Dropzone.options.myDropzone = ( init: function() ( thisDropzone = this; $.get("upload.php", function(data) ( $.each(data, function(key,value)( var mockFile = ( name : value.name, size: value.size ); thisDropzone.options.addedfile.call(thisDropzone, mockFile); thisDropzone.options.thumbnail.call(thisDropzone, mockFile, "uploads/"+value.name ))) ؛ ;
ماذا فعلنا هنا؟ دعونا معرفة ذلك:
إذا فعلت كل شيء بشكل صحيح. قم بتحميل بعض الصور وأعد تحميل صفحة النموذج. يجب أن تظهر الملفات التي تم تحميلها مسبقًا تلقائيًا في منطقة Dropzone.
إعداد: يفغيني ريجكوف وإيجور سكورنياكوف تاريخ النشر: 2011/06/12
مهمةالسماح للمستخدم بتحميل الملفات إلى الخادم عن طريق سحبها، على سبيل المثال، من سطح المكتب. علاوة على ذلك، سيكون من الممكن سحب وإسقاط عدة ملفات في وقت واحد.
حلدعونا نلقي نظرة على المثال التجريبي. يمكن العثور على مثال في الأرشيف. التحقق:
اسمحوا لي أن ألفت انتباهكم إلى أنه في هذه الحالة تم التحقق منه!= وهو يعمل:
وما فائدة ذلك في هذه الحالة؟ يحصل مستخدمو المتصفحات العادية على مواقع أكثر ملاءمة.
ما يجب تنزيله:نقوم بتوصيل البرامج النصية، ونضيف type =file مع . إذا كان المتصفح لا يدعم المجموعة المطلوبة من واجهات برمجة التطبيقات، فسيتمكن المستخدم من تحميل الصورة بالطريقة القديمة. لكي تتاح له الفرصة لإضافة عدة صور، سنضيف ديناميكيًا زر "+"، والذي سيضيف حقول نوع الإدخال = الملف. لهذه الأغراض، يحتوي معرف الحقل على 0 لتسهيل تنظيم الأسماء الصحيحة للحقول المضافة.
...
بالنسبة للمتصفحات التي تدعم Dnd وFile API، يمكنك إخفاء أو إزالة حقول type=file بالكامل.
كيف تعملإذا لم تخوض في الكثير من التفاصيل، فيمكن عرض مبدأ التشغيل في شكل رسم تخطيطي مماثل:
التحديث: 18/09/12 بواسطة أندريه كوسياك.
مكون إضافي مناسب تمامًا لـ js لتحميل الملفات إلى الخادم. مكتوب بلغة JS خالصة. يتكون من جزء الخادم (بعدة لغات) وجزء العميل (JS وCSS).
لايستخدم فلاش وأي أطر.
يستخدم Fineuploader كائن XMLHttpRequest لنقل الملفات باستخدام شريط التقدم للمتصفحات الحديثة، وبالنسبة لأي سلة مهملات، يتم استخدام طريقة iframe القديمة الجيدة.
دعونا تعرف:التحقق:
يجب التحقق من وظائف المكون الإضافي حصريًا من الخادم (المحلي جيد). في المثال سأستخدم جزء الخادم في PHP.
قبل البداية الأولى، تحتاج إلى إعداد الأرض:
على الخادم المحلي، أول شيء سيطلبه البرنامج النصي هو زيادة قيم معلمات post_max_size وupload_max_filesize. افتح ملف php.ini، وابحث عن هذه المعلمات واضبط القيم على >= 10M. على الخادم الحقيقي، من المرجح ألا يكون هذا العنصر مطلوبًا.
من المجلد /server الخاص بالمكون الإضافي، نأخذ ملف php.php. في الكتلة الأولى من التعليقات مكتوب فيه الخطوط التي يجب استخراجها من التعليقات من أجل تهيئة الفصل. أضف مباشرة بعد كتلة التعليق:
// امتدادات الملفات المسموح بها $allowedExtensions = array(); // الحد الأقصى لحجم الملف $sizeLimit = 10 * 1024 * 1024؛ // تهيئة الفئة $uploader = new qqFileUploader($allowedExtensions, $sizeLimit); // هنا تحتاج إلى تحديد المسار إلى المجلد / التحميلات $result = $uploader->handleUpload("../uploads/"); // إرجاع الاستجابة بعد حفظ الملف echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);
نحن نربط البرنامج النصي والأنماط:
الرجاء تمكين JavaScript لاستخدام أداة تحميل الملفات.
تهيئة JS:
Window.onload = function())( var uploader = new qq.FileUploader(( element: document.getElementById("file-uploader1")، الإجراء: "php/upload.php" // المسار إلى جانب الخادم للمكون الإضافي )));
أولاً، بالطبع، تحتاج إلى إنشاء عنصر "يلتقط" الملف. بالإضافة إلى ذلك، سنضع علامة امتداد في هذا العنصر لعرض رسائل حول حالة التحميل و مدخلمع النوع ملف، حتى لا يقتصر اختيار الملف على السحب والإفلات، ولكن أيضًا للسماح للمستخدمين بتحديد ملف من خلال النقر على هذه المنطقة المخصصة. ويرد أدناه الشكل النهائي لمثل هذا الهيكل.
انقر هنا أو قم بسحب وإسقاط الملف للتحميل.
CSSالى هذا لغة البرمجةالكود غير ملحوظ، باستثناء تصميم الحقل مدخل:
#ملف (العرض: 100%؛ الارتفاع: 100%؛ العرض: كتلة؛ الموضع: مطلق؛ أعلى: 0؛ يسار: 0؛ العتامة: 0.01؛)
نحن أيضًا نصف فئتين، عند إضافتهما إلى منطقة "التقاط" الملف، ستشير إلى نجاح تنزيل الملف أو حدوث خطأ في حالة حدوثه:
#drop-zone.success(لون الخلفية:#2ecc71;) #drop-zone.error(لون الخلفية:#e74c3c;)
الآن يمكننا أن ننتقل إلى كتابة "الإجراء" الخاص بصفحتنا. أولاً، دعنا نكتب في المتغيرات إشارات إلى الكائنات التي سنصل إليها كثيرًا:
var dropZone = document.getElementById("drop-zone"); var msgContainer = document.querySelector("#drop-zone .text");
بعد ذلك، سوف نتخلص من الأحداث الافتراضية عندما يضرب المؤشر منطقة استلام الملفات لدينا على النحو التالي:
var eventsClear = function (e) ( e.stopPropagation(); e.preventDefault(); ) dropZone.addEventListener("dragenter", eventsClear, false); dropZone.addEventListener("dragover", eventsClear, false);
DropZone.addEventListener("drop"، الوظيفة (e) ( if(!e.dataTransfer.files) return; e.stopPropagation(); e.preventDefault(); sendFile(e.dataTransfer.files); ), false); document.getElementById("file").addEventListener("change", function (e) ( sendFile(e.target.files); ), false);
في كلتا الحالتين، ينتهي الحدث باستدعاء دالة إرسال ملف، حيث يتم نقل الملف المستلم من المستخدم.
هذه الوظيفة مسؤولة عن نقل الملف إلى الخادم. يمكنك رؤية وصفه أدناه.
var sendFile = function(file) ( // إزالة فئات الحالة التي كان من الممكن إضافتها // إذا كان المستخدم قد حاول بالفعل تنزيل شيء ما dropZone.classList.remove("success"); dropZone.classList.remove("error") // التحقق باستخدام تعبير عادي لنوع الملف // (في المثال، يُسمح بتحميل الصور فقط) var re = /(.jpg|.jpeg|.bmp|.gif|.png)$/i ; exec(file.name)) ( msgConteiner.innerHTML = "تنسيق الملف غير صالح!"؛ dropZone.classList.remove("success"); dropZone.classList.add("error"); ) else ( var fd = new FormData ; ( ); // إنشاء كائن نموذج fd.append("upfile", file); // إضافة ملف إلى نموذج الإرسال var xhr = new XMLHttpRequest(); = statChange؛ // الإرسال إلى الخادم)
كما لاحظت، قبل إرسال البيانات إلى الخادم، يتم أيضًا تعيين حدثين، الأول منهما مسؤول عن عرض تقدم التنزيل، والثاني للإعلام بنتيجة التنزيل. تعمل على النحو التالي:
var showProgress = function(e) ( if (e. lengthComputable) ( // احسب نسبة التحميل var بالمائة = Math.floor((e.loaded / e.total) * 100); // عرض النسبة المئوية الحالية msgConteiner.innerHTML = " جارٍ التحميل... ("+ بالمائة +"%)"); var statChange = function (e) ( if (e.target.readyState == 4) ( // عند الانتهاء من معالجة الطلب إلى الخادم if (e.target.status == 200) ( // إذا كان الطلب ناجحًا msgConteiner.innerHTML = "تم التحميل بنجاح!"; dropZone.classList.remove("error"); dropZone.classList.add("success"); // else msgConteiner.innerHTML = "حدث خطأ!"; dropZone.classList.remove("success"); dropZone.classList.add("error" ) )
ستكون المرحلة النهائية هي معالجة البيانات التي يتلقاها الخادم.