جاري التحميل...

سحب وإفلات HTML

تقنية السحب والإفلات (Drag and Drop) في HTML تُعد من الأدوات التفاعلية المتقدمة التي تتيح للمستخدم تحريك العناصر داخل الصفحة بسهولة، كما لو كان يرتب كتبًا في مكتبة (organizing a library) أو يزيّن غرفة (decorating a room). هذه التقنية تضيف بعدًا حيويًا وتجربة مستخدم أكثر سلاسة، دون الحاجة لإعادة تحميل الصفحة أو تنفيذ إجراءات معقدة.
يتم استخدام سحب وإفلات HTML في مواقع الأخبار لتغيير ترتيب المقالات، وفي المنصات التجارية (e-commerce) لإضافة العناصر إلى سلة الشراء، وعلى الصفحات الشخصية لترتيب المهارات أو المعرض، وفي البوابات الحكومية لتقديم مستندات إلكترونية بطريقة سهلة للمواطنين.
في هذا الدرس، سنتعلّم كيفية جعل العناصر قابلة للسحب باستخدام الخاصية draggable، وكيفية التعامل مع الأحداث مثل ondragstart وondrop وondragover. سنتعرّف أيضًا على مفهوم dataTransfer لنقل البيانات بين العنصر الذي يتم سحبه والمكان الذي يُسقط فيه.
هذا الدرس مخصص للمطورين الطموحين الذين يريدون إتقان التفاعل المتقدم باستخدام HTML فقط، مع التركيز على الأمثلة العملية، توضيح المفاهيم خطوة بخطوة، وتجنب الأخطاء الشائعة.

مثال أساسي

html
HTML Code
<!-- عنصر قابل للسحب ومساحة إفلات -->
<div id="drag" draggable="true">اسحبني</div>
<div id="drop" ondrop="drop(event)" ondragover="allowDrop(event)">أسقط هنا</div>

<script>
// السماح بالإفلات داخل المنطقة
function allowDrop(ev) {
ev.preventDefault();
}
// تنفيذ عند الإفلات
function drop(ev) {
ev.preventDefault();
const item = document.getElementById("drag");
ev.target.appendChild(item); // نقل العنصر داخل المنطقة
}
</script>

في هذا المثال، نُنشئ عنصرًا يمكن سحبه وآخر يُستخدم كمنطقة للإفلات. أولاً، الخاصية draggable="true" تُستخدم لجعل العنصر قابلًا للسحب. بدون هذه الخاصية، لا يمكن للعنصر التفاعل مع الأحداث الخاصة بالسحب.
المنطقة التي نستقبل فيها العنصر تحتوي على خاصيتين هامتين: ondrop وondragover. الدالة allowDrop تقوم بمنع السلوك الافتراضي للمتصفح باستخدام ev.preventDefault()، وذلك لأن المتصفح يمنع بشكل افتراضي عملية الإسقاط ما لم يتم إيقاف هذا السلوك.
عند الإفلات، يتم استدعاء الدالة drop، والتي بدورها تمنع السلوك الافتراضي وتقوم بجلب العنصر المسحوب باستخدام getElementById("drag"). بعد ذلك يتم إلحاق هذا العنصر إلى منطقة الإفلات عبر appendChild.
هذا المفهوم يمكن تطبيقه عمليًا في موقع حكومي حيث يُطلب من المستخدم سحب الملفات إلى منطقة تحميل، أو في موقع إخباري لترتيب الأقسام حسب الأولوية. من الأسئلة الشائعة: "هل يمكن سحب أكثر من عنصر؟" نعم، باستخدام معرفات فريدة وتعديل الدوال، يمكن دعم ذلك. هل يمكن تخصيص شكل العنصر أثناء السحب؟ بالتأكيد، باستخدام CSS وتأثيرات dragenter وdragleave.

مثال عملي

html
HTML Code
<!-- ترتيب مقالات الأخبار حسب الأهمية -->
<ul id="news">
<li id="art1" draggable="true" ondragstart="start(event)">مقال 1</li>
<li id="art2" draggable="true" ondragstart="start(event)">مقال 2</li>
</ul>

<ul id="priority" ondrop="drop(event)" ondragover="allowDrop(event)">
<li><strong>مقالات مهمة</strong></li>
</ul>

<script>
function allowDrop(ev) {
ev.preventDefault();
}
function start(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
const id = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(id));
}
</script>

أفضل الممارسات والأخطاء الشائعة:
أفضل الممارسات:

  1. استخدم عناصر دلالية (semantic HTML) مثل <ul>, <li>, <section> لتوضيح الهيكل العام وتحسين الوصولية.
  2. أضف خصائص aria-grabbed وaria-dropeffect لزيادة الدعم لمستخدمي قارئات الشاشة.
  3. استخدم CSS لتوضيح المناطق القابلة للإفلات (مثلاً بتغيير اللون عند dragenter).
  4. اجعل الأكواد نظيفة ومنظمة وافصل بين الهيكل (HTML) والتفاعل (JavaScript) والتنسيق (CSS).
    أخطاء شائعة يجب تجنبها:

  5. عدم استخدام ev.preventDefault() في ondragover، مما يمنع الإفلات.

  6. عدم تعيين معرف فريد لكل عنصر مسحوب.
  7. إدراج عناصر داخل مناطق لا تسمح بالإفلات مما يؤدي إلى أخطاء منطقية.
  8. استخدام عناصر غير مناسبة مثل <span> أو <b> لعناصر السحب دون داعٍ.
    نصائح تصحيح الأخطاء:
  • استخدم console.log() داخل الدوال لرؤية قيم dataTransfer والتأكد من أن البيانات تمر بشكل صحيح.
  • تحقق أن جميع المعرفات (id) فريدة وأن العناصر موجودة في DOM.
  • جرّب على متصفحات مختلفة، فبعض المتصفحات تتطلب تعديلات طفيفة في السلوك الافتراضي.

📊 مرجع سريع

Property/Method Description Example
draggable تمكين السحب على العنصر <div draggable="true">
ondragstart حدث بدء السحب ondragstart="start(event)"
ondrop حدث الإفلات ondrop="drop(event)"
ondragover تمرير العنصر فوق منطقة ondragover="allowDrop(event)"
dataTransfer.setData() تخزين معرف العنصر ev.dataTransfer.setData("text", id)
dataTransfer.getData() استرجاع معرف العنصر ev.dataTransfer.getData("text")

الملخص والخطوات القادمة:
تقنية سحب وإفلات HTML تفتح المجال لإنشاء واجهات ديناميكية وتفاعلية بدون الحاجة إلى مكتبات خارجية. أهم ما تعلمناه اليوم هو دور خاصية draggable، التعامل مع الأحداث (ondragstart, ondrop, ondragover)، وأهمية dataTransfer في ربط العنصر بمكان الإفلات.
هذا المفهوم يمكن تعزيزه باستخدام CSS لإضافة تأثيرات بصرية عند السحب أو الإفلات، مثل تغيير اللون أو إضافة ظل. كما يمكن ربطه بـJavaScript لبناء منطق أكثر تعقيدًا مثل حفظ الترتيب في قاعدة بيانات أو تفعيل ردود فعل صوتية.
المواضيع التالية المقترحة:

  • تأثيرات CSS أثناء السحب والإفلات
  • دعم الأجهزة المحمولة (Touch Events)
  • دمج السحب مع مكتبات JavaScript مثل Vue أو React
  • التعامل مع ملفات باستخدام Drag and Drop
    ابدأ بالتجريب على مشروعك الشخصي، سواء صفحة سيرة ذاتية أو موقع حكومي، وستشعر بأنك ترتب مكتبة تفاعلية بكفاءة وسلاسة.

🧠 اختبر معرفتك

جاهز للبدء

اختبر معرفتك

اختبر فهمك لهذا الموضوع بأسئلة عملية.

3
الأسئلة
🎯
70%
للنجاح
♾️
الوقت
🔄
المحاولات

📝 التعليمات

  • اقرأ كل سؤال بعناية
  • اختر أفضل إجابة لكل سؤال
  • يمكنك إعادة الاختبار عدة مرات كما تريد
  • سيتم عرض تقدمك في الأعلى