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

محددات jQuery - الجزء الثاني

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

محددات jQuery المتقدمة

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

محددات النماذج

توفر jQuery محددات متخصصة للعمل مع عناصر النماذج:

// اختيار جميع عناصر الإدخال
$(':input')          // جميع input، textarea، select، button

// اختيار حسب نوع الإدخال
$(':text')           // جميع مدخلات النص
$(':password')       // جميع مدخلات كلمة المرور
$(':radio')          // جميع أزرار الراديو
$(':checkbox')       // جميع خانات الاختيار
$(':submit')         // جميع أزرار الإرسال
$(':button')         // جميع الأزرار
$(':file')           // جميع مدخلات الملفات
$(':image')          // جميع مدخلات الصور

// اختيار حسب الحالة
$(':enabled')        // جميع عناصر النماذج المفعّلة
$(':disabled')       // جميع عناصر النماذج المعطّلة
$(':checked')        // جميع خانات الاختيار/أزرار الراديو المحددة
$(':selected')       // جميع الخيارات المحددة في select

أمثلة عملية للنماذج

// الحصول على قيم جميع مدخلات النص
var values = [];
$(':text').each(function() {
    values.push($(this).val());
});

// تعطيل جميع أزرار الإرسال
$(':submit').prop('disabled', true);

// عد خانات الاختيار المحددة
var checkedCount = $(':checkbox:checked').length;

// الحصول على نص الخيار المحدد
var selectedText = $('#country :selected').text();

// التحقق من الحقول المطلوبة
$(':input[required]').each(function() {
    if ($(this).val() === '') {
        $(this).css('border', '2px solid red');
    }
});

مثال نموذج كامل

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <script>
        $(function() {
            // تحديد جميع خانات الاختيار
            $('#checkAll').click(function() {
                $(':checkbox').prop('checked', true);
            });

            // إلغاء تحديد الكل
            $('#uncheckAll').click(function() {
                $(':checkbox').prop('checked', false);
            });

            // عد التحديدات
            $('#count').click(function() {
                var count = $(':checkbox:checked').length;
                alert(count + ' عناصر محددة');
            });

            // تفعيل/تعطيل الإرسال بناءً على خانة الاختيار
            $('#agree').change(function() {
                $(':submit').prop('disabled', !this.checked);
            });
        });
    </script>
</head>
<body>
    <form>
        <label><input type="checkbox" name="item1"> عنصر 1</label><br>
        <label><input type="checkbox" name="item2"> عنصر 2</label><br>
        <label><input type="checkbox" name="item3"> عنصر 3</label><br>
        <br>
        <label><input type="checkbox" id="agree"> أوافق</label><br>
        <br>
        <button type="button" id="checkAll">تحديد الكل</button>
        <button type="button" id="uncheckAll">إلغاء تحديد الكل</button>
        <button type="button" id="count">عد المحدد</button>
        <br><br>
        <button type="submit" disabled>إرسال</button>
    </form>
</body>
</html>

مرشحات المحتوى

اختر العناصر بناءً على محتواها:

// عناصر تحتوي على نص
$(':contains("مرحبا")')      // عناصر بـ "مرحبا" في النص

// عناصر فارغة
$(':empty')                  // عناصر بدون أطفال

// عناصر بها أطفال
$(':parent')                 // عناصر هي آباء

// عناصر تحتوي على عنصر محدد
$('div:has(p)')              // divs تحتوي على فقرات
$('li:has(a)')               // عناصر قائمة تحتوي على روابط

أمثلة مرشحات المحتوى

// تسليط الضوء على الفقرات التي تحتوي على "مهم"
$('p:contains("مهم")').css('background', 'yellow');

// إخفاء الفقرات الفارغة
$('p:empty').hide();

// العثور على divs التي تحتوي على صور
$('div:has(img)').addClass('has-image');

// تنسيق عناصر القائمة بدون روابط
$('li:not(:has(a))').css('color', 'gray');

// إزالة عناصر القائمة الفارغة
$('li:empty').remove();

مرشحات الرؤية

اختر العناصر بناءً على رؤيتها:

// العناصر المرئية
$(':visible')
$('div:visible')
$('p:visible')

// العناصر المخفية
$(':hidden')
$('div:hidden')
$('p:hidden')
📝 ملاحظة: يُعتبر العنصر مخفياً إذا:
  • display: none
  • العرض والارتفاع يساويان 0
  • عنصر الوالد مخفي

أمثلة الرؤية

// عد divs المرئية
var visibleCount = $('div:visible').length;

// إظهار جميع الفقرات المخفية
$('p:hidden').fadeIn();

// تبديل رؤية العناصر المخفية
$('#toggleBtn').click(function() {
    $('.content:hidden').slideDown();
    $('.content:visible').slideUp();
});

محدد النفي/NOT

استبعد العناصر من الاختيار:

// جميع الفقرات باستثناء تلك بفئة "special"
$('p:not(.special)')

// جميع المدخلات باستثناء خانات الاختيار
$(':input:not(:checkbox)')

// جميع divs باستثناء الأول
$('div:not(:first)')

// جميع الروابط بدون خاصية target
$('a:not([target])')

// استبعادات متعددة
$('li:not(.active):not(.disabled)')

أمثلة محدد NOT

// تنسيق جميع الفقرات باستثناء الأولى
$('p:not(:first)').css('margin-top', '20px');

// تعطيل جميع المدخلات باستثناء أزرار الإرسال
$(':input:not(:submit)').prop('disabled', true);

// إخفاء جميع divs بدون فئة "keep"
$('div:not(.keep)').hide();

// إضافة required لجميع مدخلات النص باستثناء الاختيارية
$(':text:not(.optional)').prop('required', true);

طرق التنقل

بعد اختيار العناصر، يمكنك التنقل في DOM للعثور على العناصر ذات الصلة:

العثور على الأقارب

// عنصر الوالد
$('#child').parent()

// جميع الأسلاف
$('#element').parents()

// الأسلاف حتى المحدد
$('#element').parentsUntil('#container')

// الأطفال
$('#parent').children()

// جميع الأحفاد
$('#parent').find('p')

// الأشقاء
$('#element').siblings()

// الشقيق التالي
$('#element').next()

// الشقيق السابق
$('#element').prev()

// جميع الأشقاء التالين
$('#element').nextAll()

// جميع الأشقاء السابقين
$('#element').prevAll()

أمثلة التنقل

<div id="container">
    <div class="parent">
        <p id="para1">فقرة 1</p>
        <p id="para2" class="highlight">فقرة 2</p>
        <p id="para3">فقرة 3</p>
    </div>
</div>

<script>
    // الحصول على والد para2
    $('#para2').parent().css('border', '2px solid blue');

    // الحصول على جميع أشقاء para2
    $('#para2').siblings().css('color', 'gray');

    // الحصول على الشقيق التالي
    $('#para2').next().css('font-weight', 'bold');

    // الحصول على الشقيق السابق
    $('#para2').prev().css('font-style', 'italic');

    // العثور على جميع الفقرات داخل container
    $('#container').find('p').addClass('found');

    // الحصول على أطفال parent
    $('.parent').children().css('padding', '10px');
</script>

طرق التصفية

صقل اختياراتك أكثر:

// تصفية حسب المحدد
$('p').filter('.highlight')

// تصفية حسب دالة
$('li').filter(function(index) {
    return index % 2 === 0;  // فهارس زوجية
});

// العنصر الأول
$('p').first()

// العنصر الأخير
$('p').last()

// عنصر في فهرس
$('p').eq(2)

// نطاق شريحة
$('li').slice(1, 4)  // العناصر 1، 2، 3

// التحقق مما إذا كان التحديد يطابق
if ($('#myDiv').is('.active')) {
    // افعل شيئاً
}

// التحقق مما إذا كان التحديد لديه أحفاد
if ($('#myDiv').has('p').length) {
    // لديه فقرات
}

أمثلة التصفية

// تسليط الضوء على الفقرات الزوجية
$('p').filter(function(index) {
    return index % 2 === 0;
}).css('background', 'yellow');

// الحصول على العناصر الأولى والأخيرة
$('li').first().addClass('first-item');
$('li').last().addClass('last-item');

// الحصول على نطاق محدد
$('li').slice(2, 5).css('color', 'red');

// تصفية حسب خاصية البيانات
$('.item').filter(function() {
    return $(this).data('price') > 100;
}).addClass('expensive');

// التحقق مما إذا كان العنصر لديه فئة
if ($('#box').is('.active')) {
    console.log('الصندوق نشط');
}

تسلسل المحددات والتنقل

ادمج المحددات والتنقل لاستعلامات قوية:

// العثور على الوالد، ثم الأشقاء، ثم التصفية
$('#element')
    .parent()
    .siblings()
    .filter('.active')
    .css('color', 'red');

// العثور على الأطفال، التصفية، ثم العثور على الأحفاد
$('#container')
    .children('div')
    .filter(':visible')
    .find('p')
    .addClass('highlight');

// تنقل معقد
$('#list')
    .find('li')
    .filter(function() {
        return $(this).text().length > 10;
    })
    .first()
    .css('font-weight', 'bold');

طريقة end()

العودة إلى التحديد السابق في السلسلة:

$('#container')
    .find('p')              // اختر الفقرات
    .css('color', 'blue')   // نسق الفقرات
    .end()                   // عد إلى #container
    .find('span')            // الآن اختر spans
    .css('color', 'red');   // نسق spans

// بدون end()، ستحتاج إلى إعادة التحديد:
$('#container').find('p').css('color', 'blue');
$('#container').find('span').css('color', 'red');
💡 نصيحة محترف: استخدم .end() عندما تحتاج إلى العمل مع تحديدات متعددة ذات صلة دون تكرار المحدد الأساسي.
🎯 تمرين متقدم:

أنشئ واجهة إدارة مهام تحتوي على:

  • قائمة مهام (بعضها مميز بفئة "completed")
  • خانات اختيار لكل مهمة
  • أزرار لـ:
    1. إظهار المهام غير المكتملة فقط
    2. إظهار المهام المكتملة فقط
    3. إظهار جميع المهام
    4. وضع علامة على المهام المحددة كمكتملة
    5. إزالة المهام المكتملة
💡 الحل
<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <style>
        .completed {
            text-decoration: line-through;
            color: gray;
        }
        .task {
            padding: 10px;
            margin: 5px 0;
        }
    </style>
    <script>
        $(function() {
            // إظهار غير المكتملة فقط
            $('#showIncomplete').click(function() {
                $('.task').show();
                $('.task.completed').hide();
            });

            // إظهار المكتملة فقط
            $('#showCompleted').click(function() {
                $('.task').hide();
                $('.task.completed').show();
            });

            // إظهار الكل
            $('#showAll').click(function() {
                $('.task').show();
            });

            // وضع علامة على المحددة كمكتملة
            $('#markComplete').click(function() {
                $(':checkbox:checked').closest('.task')
                    .addClass('completed');
            });

            // إزالة المكتملة
            $('#removeCompleted').click(function() {
                $('.task.completed').fadeOut(function() {
                    $(this).remove();
                });
            });
        });
    </script>
</head>
<body>
    <h1>مدير المهام</h1>

    <div class="task">
        <input type="checkbox"> شراء البقالة
    </div>
    <div class="task completed">
        <input type="checkbox"> دفع الفواتير
    </div>
    <div class="task">
        <input type="checkbox"> الاتصال بطبيب الأسنان
    </div>
    <div class="task completed">
        <input type="checkbox"> إرسال التقرير
    </div>

    <br>
    <button id="showIncomplete">إظهار غير المكتملة</button>
    <button id="showCompleted">إظهار المكتملة</button>
    <button id="showAll">إظهار الكل</button>
    <br><br>
    <button id="markComplete">وضع علامة مكتملة</button>
    <button id="removeCompleted">إزالة المكتملة</button>
</body>
</html>

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

⚠️ نصائح الأداء:
  • حفظ التحديدات: احفظ المحددات المستخدمة بشكل متكرر في متغيرات
  • كن محدداً: $('#myId p') أسرع من $('p')
  • استخدم المعرفات عندما يكون ذلك ممكناً: محددات المعرف هي الأسرع
  • تجنب المحدد العام: $('*') بطيء
  • قلل عمق التنقل: لا تتنقل عبر مستويات كثيرة جداً

الملخص

في هذا الدرس، تعلمت:

  • محددات النماذج: :text، :checkbox، :checked، :enabled، إلخ.
  • مرشحات المحتوى: :contains()، :empty، :parent، :has()
  • مرشحات الرؤية: :visible و :hidden
  • محدد NOT :not() لاستبعاد العناصر
  • طرق التنقل: parent()، children()، siblings()، find()
  • طرق التصفية: filter()، first()، last()، eq()، slice()
  • استخدام .end() للعودة إلى التحديد السابق
  • أفضل ممارسات الأداء للمحددات

في الدرس التالي، سنقارن jQuery مع JavaScript العادي الحديث!

ES
Edrees Salih
منذ 11 ساعة

We are still cooking the magic in the way!