jQuery والتعامل مع DOM

استبدال وتغليف العناصر

12 دقيقة الدرس 15 من 30

استبدال وتغليف العناصر

توفر jQuery طرقًا قوية لاستبدال العناصر الموجودة بمحتوى جديد أو تغليف العناصر بهيكل HTML إضافي. هذه التقنيات ضرورية لتحويل DOM الخاص بك ديناميكيًا.

استبدال العناصر

تستبدل طريقة .replaceWith() العناصر المطابقة بمحتوى جديد:

.replaceWith() - استبدال العنصر: // استبدال بسلسلة HTML $(".old-button").replaceWith("<button class='new-button'>زر محدّث</button>"); // استبدال بكائن jQuery let newElement = $("<div>", { class: "new-content", text: "هذا محتوى جديد" }); $(".old-content").replaceWith(newElement); // استبدال باستخدام دالة $("p.status").replaceWith(function() { let status = $(this).text(); return "<span class='badge'>" + status + "</span>"; }); // استبدال عناصر متعددة $("img.placeholder").replaceWith(function() { return "<div class='image-loaded'><img src='" + $(this).data("src") + "'></div>"; });
.replaceAll() - عكس replaceWith(): // إنشاء عنصر جديد واستبدال جميع التطابقات $("<h2>عنوان جديد</h2>").replaceAll("h3.old-heading"); // استبدال جميع رسائل الخطأ $("<div class='alert alert-success'>نجاح!</div>").replaceAll(".error-message");
مهم: عند استبدال عنصر، تتم إزالة جميع معالجات الأحداث والبيانات المرتبطة بالعنصر القديم. إذا كنت بحاجة إلى الاحتفاظ بها، ففكر في إخفاء العنصر القديم وإظهار عنصر جديد بدلاً من ذلك.

مثال عملي: شارة حالة ديناميكية

HTML: <div class="order-list"> <div class="order-item"> <span class="order-number">#1234</span> <span class="status" data-status="pending">قيد الانتظار</span> </div> <div class="order-item"> <span class="order-number">#1235</span> <span class="status" data-status="shipped">تم الشحن</span> </div> </div>
jQuery: $(document).ready(function() { // استبدال نص الحالة بشارات منسقة $(".status").replaceWith(function() { let status = $(this).data("status"); let statusText = $(this).text(); let badgeClass = ""; switch(status) { case "pending": badgeClass = "badge-warning"; break; case "shipped": badgeClass = "badge-info"; break; case "delivered": badgeClass = "badge-success"; break; case "cancelled": badgeClass = "badge-danger"; break; } return $("<span>", { class: "badge " + badgeClass, text: statusText, "data-status": status }); }); });

تغليف العناصر

تسمح لك طرق التغليف بإحاطة العناصر بهيكل HTML جديد:

.wrap() - تغليف كل عنصر: // تغليف كل فقرة في div $("p").wrap("<div class='paragraph-wrapper'></div>"); // تغليف بكائن jQuery $("img").wrap($("<div>", { class: "image-container" })); // تغليف باستخدام دالة (غلاف مختلف لكل عنصر) $(".card").wrap(function(index) { return "<div class='card-wrapper card-" + index + "'></div>"; }); // تغليف حقول النموذج بتسميات $("input[type='text']").wrap(function() { let placeholder = $(this).attr("placeholder"); return "<div class='form-group' data-label='" + placeholder + "'></div>"; });
.wrapAll() - تغليف جميع العناصر معًا: // تغليف جميع الفقرات في حاوية واحدة $("p").wrapAll("<div class='content-wrapper'></div>"); // تغليف العناصر المحددة في مجموعة $(".product.selected").wrapAll("<div class='selected-products'></div>"); // إنشاء معرض من الصور $(".gallery img").wrapAll("<div class='image-gallery'><div class='gallery-inner'></div></div>");
ملاحظة: تنقل .wrapAll() جميع العناصر المطابقة إلى موقع واحد وتغلفها معًا. إذا كانت العناصر متناثرة في DOM، فسيتم نقلها إلى موقع العنصر الأول.
.wrapInner() - تغليف المحتوى داخل العناصر: // تغليف محتوى كل فقرة $("p").wrapInner("<span class='text-content'></span>"); // إضافة غلاف أيقونة داخل الأزرار $("button").wrapInner("<span class='btn-text'></span>"); // تغليف محتوى عنصر القائمة $("li").wrapInner(function() { return "<div class='list-content'></div>"; }); // إضافة غلاف رابط حول نص العنوان $("h2").wrapInner("<a href='#'></a>");
.unwrap() - إزالة الغلاف الأصلي: // إزالة الغلاف الأصلي $("span").unwrap(); // إزالة أصل محدد $(".wrapped-content").unwrap(".wrapper"); // فك تغليف مستويات متعددة $(".nested-content").unwrap().unwrap(); // إزالة مستويين أصليين

مثال عملي: معرض صور مع صندوق إضاءة

HTML: <div class="photo-gallery"> <img src="photo1.jpg" alt="صورة 1"> <img src="photo2.jpg" alt="صورة 2"> <img src="photo3.jpg" alt="صورة 3"> </div>
jQuery: $(document).ready(function() { // تغليف كل صورة في figure مع تسمية توضيحية $(".photo-gallery img").wrap(function() { let alt = $(this).attr("alt"); return "<figure class='gallery-item'></figure>"; }).after(function() { return "<figcaption>" + $(this).attr("alt") + "</figcaption>"; }); // تغليف جميع عناصر المعرض في حاوية $(".gallery-item").wrapAll("<div class='gallery-grid'></div>"); // إضافة وظيفة صندوق الإضاءة $(".gallery-item img").click(function() { let imgSrc = $(this).attr("src"); let imgAlt = $(this).attr("alt"); // إنشاء طبقة صندوق الإضاءة let lightbox = $("<div>", { class: "lightbox-overlay", html: "<div class='lightbox-content'>" + "<img src='" + imgSrc + "' alt='" + imgAlt + "'>" + "<button class='close-lightbox'>×</button>" + "</div>" }); $("body").append(lightbox); lightbox.fadeIn(300); }); // إغلاق صندوق الإضاءة $(document).on("click", ".close-lightbox, .lightbox-overlay", function(e) { if (e.target === this) { $(".lightbox-overlay").fadeOut(300, function() { $(this).remove(); }); } }); });

تقنيات تغليف متقدمة

هياكل تغليف معقدة: // تغليف بعناصر متداخلة متعددة $(".quote").wrap( "<div class='quote-container'>" + "<div class='quote-inner'>" + "</div>" + "</div>" ); // تغليف وإضافة عناصر شقيقة $("blockquote").wrap("<div class='quote-wrapper'></div>") .parent() .prepend("<span class='quote-icon'>"</span>") .append("<span class='quote-icon'>"</span>"); // تغليف مشروط $("img").each(function() { if ($(this).width() > 500) { $(this).wrap("<div class='large-image-wrapper'></div>"); } else { $(this).wrap("<div class='small-image-wrapper'></div>"); } });

الجمع بين الاستبدال والتغليف

تحويل العناصر: // استبدال وتغليف في عملية واحدة function upgradeButton(selector) { $(selector).each(function() { let buttonText = $(this).text(); let buttonClass = $(this).attr("class"); // إنشاء هيكل زر جديد let newButton = $("<button>", { class: buttonClass + " upgraded", html: "<span class='btn-icon'></span>" + "<span class='btn-text'>" + buttonText + "</span>" }); // استبدال الزر القديم $(this).replaceWith(newButton); }); } // الاستخدام upgradeButton(".old-style-btn"); // استبدال عقد النص بعناصر منسقة $("p").contents().filter(function() { return this.nodeType === 3; // عقدة نصية }).wrap("<span class='text-node'></span>");
تمرين: أنشئ محسن جدول تسعير ديناميكي يقوم بما يلي:
  • تغليف كل سعر في حاوية منسقة
  • استبدال رموز العملة بخطوط الأيقونات
  • تغليف قوائم الميزات في أقسام قابلة للتوسيع
  • إضافة شريط "شائع" إلى مستوى التسعير الأوسط
  • تغليف أزرار الإجراءات في مجموعة أزرار

إضافي: أضف تأثيرات تمرير تستبدل نص الزر مؤقتًا بـ "اختر الخطة".

أفضل الممارسات

  • الأداء: التغليف والاستبدال عمليات مكلفة؛ قم بتجميعها عند الإمكان
  • معالجات الأحداث: تذكر أن .replaceWith() تزيل معالجات الأحداث من العنصر القديم
  • حفظ البيانات: استخدم .data() للحفاظ على المعلومات قبل الاستبدال
  • HTML الدلالي: تأكد من أن الهياكل المغلفة تحافظ على دلالات HTML الصحيحة
  • فك التغليف بحذر: تأكد من وجود العناصر الأصلية قبل استدعاء .unwrap()
  • اختبر جيدًا: يمكن أن يؤثر التغليف على محددات CSS والتخطيط

اعتبارات الأداء

تغليف فعال: // غير فعال: عمليات DOM متعددة $("li").each(function() { $(this).wrap("<div class='item-wrapper'></div>"); }); // أفضل: عملية واحدة لجميع العناصر $("li").wrap("<div class='item-wrapper'></div>"); // تخزين كائنات jQuery مؤقتًا let items = $(".item"); let wrapper = $("<div class='wrapper'></div>"); items.wrapAll(wrapper);

الملخص

في هذا الدرس، تعلمت كيفية استبدال العناصر وتغليفها:

  • استبدال العناصر باستخدام .replaceWith() و .replaceAll()
  • تغليف كل عنصر باستخدام .wrap()
  • تغليف عناصر متعددة معًا باستخدام .wrapAll()
  • تغليف محتوى العنصر باستخدام .wrapInner()
  • إزالة الأغلفة باستخدام .unwrap()
  • التطبيقات العملية لتحسين واجهة المستخدم
  • الأداء وأفضل الممارسات

بعد ذلك، سنستكشف إزالة العناصر من DOM بأمان وكفاءة.