الكثير من المطورين يستخدمون مكتبة jQuery المشهورة والمميزة بسهولتها وقلة عدد أسطر الكتابة فيها، من بين الطرق (methods) الخاصة بمعالجة العناصر وطرق الأحداث توجد طرق خاصة لإنشاء عناصر HTML من ثم التحكم بها وهو ما كان موجود منذ الإصدارة 1.3 من مكتبة jQuery.

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

إنشاء عنصر جديد

لإنشاء عناصر جديدة بإستخدام jQuery تتوفر عدة طرق ضمن طرق المعالجة Manipulation.

prepend

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

$('#content').prepend('<p>hello world</p>');

صورة توضيحية عن الطريقة

append

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

$('#content').append('<p>hello world</p>');

صورة توضيحية عن الطريقة

html

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

$('#content').html('<p>hello world</p>');

صورة توضيحية عن الطريقة

text

تقوم هذه الطريقة بإنشاء نص بداخل عنصر محدد مسبقاً (مثل p, span, small) ويمكن أن تستبدله بنص موجود مسبقاً في العنصر. مثال:

$('#content p').text('hello world');

صورة توضيحية عن الطريقة

val

تقوم هذه الطريقة بوضع قيمة للعناصر الخاصة بالنماذج البريدية أو عنصر يحمل الخاصية value في شفرة html، مثال:

$('#content form input#name').val('Ahmedz');

صورة توضيحية عن الطريقة

after

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

$('#content p').after('<p>hello world</p>');

صورة توضيحية عن الطريقة

before

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

$('#content p').before('<p>hello world</p>');

صورة توضيحية عن الطريقة

prependTo

تقوم هذه الطريقة بنقل عنصر بداخل عنصر آخر في مقدمة محتوى ذلك العنصر. مثال:

$('<p>hello world</p>').prependTo('#content');

صورة توضيحية عن الطريقة

appendTo

تقوم هذه الطريقة بنقل عنصر بداخل عنصر آخر في مؤخرة محتوى ذلك العنصر. مثال:

$('<p>hello world</p>').appendTo('#content');

صورة توضيحية عن الطريقة

التحكم بالعناصر الجديدة

التحكم بالعناصر الموجودة بالأصل في الصفحة فيها سهولة أكثر من العناصر التي أنشأت بعد ظهور الصفحة (أعني غير موجودة في الشفرة المصدرية أساساً للصفحة)، ولا يمكن تحديدها بالطرق الخاصة بالأحداث المستخدمة في مكتبة jQuery مثل bind(),click() , .. وغيرها. هذه بعض الطرق التي يمكن تحديد العناصر الجديدة في الصفحة والتحكم بها.

live

هي طريقة مشابهة لطريقة bind المتعلقة بالأحداث مثل حدث overmouse, load, click, .. وغيرها من الأحداث، ولكن طريقة live خاصة للعناصر التي أنشأت بعد تحديث الصفحة، أقصد غير موجودة في الشفرة المصدرية الخاصة بالصفحة.

حالياً تدعم الأحداث keydown, keypress, keyup, mousedown, mousemove, mouseout, mouseover, mouseup, dblclick, click فقط. مثال:

$('input[type=submit]').live('click',function(){
    // code
});

die

عكس طريقة live، تقوم هذه الطريقة بإلغاء الأحداث التي تعمل في الوقت الحالي والتي تم إنشائها باستخدام أي حدث مثل click وغيره. لفهم طريقة die أكثر، عندما يتكرر أي حدث أكثر من مرة لاستدعائه خصوصا مع اتصال الأجاكس بسبب عمل الحدث مع تصرف المستخدم وبقاء أول عملية للحدث حتى نهاية تصفح الصفحة (يمكن ملاحظة ذلك عبر مراقبة الأحداث والعمليات التي تمت تنفيذها في نافذة Console التابعة لإضافة Firebug الموجودة في متصفح فايرفوكس) ستحتاج إلى طريقة die لإبطال الحدث بشكل نهائي بعد عمله مرة واحدة عند طلب المستخدم. مثال:

$('input[type=submit]').click(function(){
    // code

    $(this).die('click');
});

في حال إستخدام طريقة live لعمل حدث للعناصر الجديدة مع عدم تكرار عملية الحدث أكثر من مرة مع كل إستدعاء لا تصلح طريقة die لإنهاء الحدث بعد إستدعائه، بل يتم الإشارة إلى قيمة false في قبل نهاية الدالة التي يتم إنشائها في عبر طريقة live، مثال عبر الشفرة التالية:

$('input[type=submit]').live('click',function(){
    // code

    return false;
});

each

طريقة لتطبيق مجموعة من العمليات على كل عنصر متكرر يتم تحديده، يمكن الاستفادة من هذه الطريقة في تحديد عنصر جديد لا يمكن تحديده بأحداث غير مدعومة في طريقة live. مثال:


$('#content').append('<div class="form-popup"></div>'); //إضافة عنصر عبارة عن نافذة جديدة إلى عنصر content

$('div.form-popup').each(function() { // تحديد العنصر الجديد بإستخدام طريقة each
    $(this).load('form-page.html'); // جلب صفحة جديدة إلى العنصر الجديد
});

not

طريقة يمكن أن تستخدم في حذف العناصر وتحديد أي عنصر غير متوافق مع الشرط الذي تحدده. مثال:


$('#content p').not(':has(.msg)').remove();

في الشفرة السابقة قمت بتحديد أي عنصر من عناصر p (التي تستخدم في إنشاء الفقرات) لا تستخدم الصنف msg. أعني إذا كانت هناك أي عناصر من الوسم p لم يُستخدم فيها الصنف .msg سيتم حذفها.

مثال عملي

هذا مثال عملي عبارة عن نموذج بريدي سيتم إنشائه في الصفحة أعني أنه لن يكون موجود بالأصل، وذلك من خلال نافذة جديدة تظهر بعد الضغط على زر النموذج البريدي، الدرس سيكون بالتأكيد باستخدام مكتبة jQuery.

قبل أن نبدأ سأستخدم رابط مكتبة jQuery من موقع جوجل.

نبدأ أولاً بوضع شفرة HTML الخاصة بالصفحة (اسم الصفحة في المثال هو form.html)، ستكون عبارة عن رابط للنموذج البريدي الذي سيظهر على شكل نافذة وهو غير موجود في الصفحة بالأصل:

<div id="content">

    <a id="form-button" href="#form">نموذج بريدي</a>

</div>

بالإضافة إلى محتوى النافذة وهو النموذج البريدي سيكون في صفحة أخرى، وسيتم استدعاء هذه الصفحة إلى صفحة الرابط، اسم الصفحة سيكون contact-form.html مثلاً، والمحتوى هو:

<span class="close"><!--Close--></span>
<h2>نموذج بريدي للمراسلة</h2>

<p>إملأ النموذج التالي لإرسال رسالتك إلى إدارة الموقع، جميع الحقول التالية مطلوبة.</p>

<ul>
    <form action="#" method="post">
        <li>
            <label for="name">الإسم</label>
            <input id="name" class="text" name="name" type="text" />
        </li>
        <li>
            <label for="email">البريد الإلكتروني</label>
            <input id="email" class="text" name="email" type="text" />
        </li>

        <li>
            <label for="message">الرسالة</label>
            <textarea id="message" class="text" name="message"></textarea>
        </li>
        <li>
            <label><span style="display: none;">إرسال</span></label>
            <input id="contact-submit" name="submit" type="submit" value="إرسـال" />
        </li>
    </form>
</ul>

شفرة CSS الخاصة بتنسيق الصفحة الرئيسية (التي تحتوي على الرابط) إضافةً إلى تنسيق شكل النافذة والنموذج:

body, p, h1, h2, h3, ul, li, label, input {
    margin: 0;
    padding: 0;
}
body {
    margin: 150px 0;
    text-align: center;
    direction: rtl;
}

a#form-button {
    background: url("form-button.png") no-repeat scroll 0 0 transparent;
    display: inline-block;
    height: 45px;
    width: 246px;
    text-indent: -9999px;
    overflow: hidden;
    text-decoration: none;
}

a#form-button:hover {
    opacity: 0.9;
}

#wrap {
    background-color: #000000;
    height: 100%;
    width: 100%;
    left: 0;
    top: 0;
    position: fixed;
    opacity: 0.6;
    display: none;
}

div.form-popup {
    background-color: #FFFFFF;
    border: 1px solid #000000;
    margin: 0 auto;
    padding: 15px;
    position: fixed;
    top: 70px;
    width: 570px;
    text-align: right;
    display: none;
    border-radius: 10px;
    -moz-border-radius: 10px;
    -webkit-border-radius: 10px;
}

div.form-popup h2 {
    color: #382514;
    font: bold 30px simplified arabic,arial;
    margin-bottom: 20px;
}

div.form-popup p {
    color: #2D2D2D;
    font: bold 16px simplified arabic,arial;
    margin: 10px 0;
}

div.form-popup .msg {
    margin: 15px 0;
    padding: 0 15px;
    border-radius: 10px;
    -moz-border-radius: 10px;
    -webkit-border-radius: 10px;
}

div.form-popup .msg.success {
    background-color: #FFE774;
    border: 1px solid #BB8D3C;
}

div.form-popup .msg.error {
    background-color: #FFBEBE;
    border: 1px solid #A90000;
}

div.form-popup ul {
    list-style: none;
}

div.form-popup ul li {
    overflow: hidden;
    padding: 10px 0;
}

div.form-popup ul li label {
    float: right;
    padding: 2px 0 5px 15px;
    text-align: left;
    width: 150px;
    font: bold 16px simplified arabic,arial;
}

div.form-popup ul li input[type=submit] {
    padding: 5px;
}

div.form-popup ul li input.text, div.form-popup ul li textarea.text {
    float: right;
    font: bold 15px simplified arabic,arial;
    padding: 3px 10px;
    width: 380px;
}

div.form-popup ul li label.error { color: red; }
div.form-popup ul li input.error, div.form-popup ul li textarea.error { border: 1px solid red; }

لن أركز على شفرة CSS لأنها ليست مهمة في الدرس، يمكنك نسخها واستخدامها مع المثال مباشرةً، الآن تبقى لنا التعامل مع مكتبة jQuery.

بداية الشفرة تكون مع كتابة الدالة الرئيسية للبدأ بالبرمجة بإستخدام مكتبة jQuery:


$(function(){
    // code
});

نبدأ بكتابة الشفرة الخاصة بإظهار النافذة إذا تم الضغط على رابط النموذج البريدي كما تبين الشفرة التالية مع الملاحظات المكتوبة:


// عمل نافذه جديدة وإستدعاء صفحة النموذج بعد الضغط على على رابط النموذج البريدي
$('#form-button').click(function(){

    // العناصر الخاصة بظهور النافذة
    // عنصر النافذة غير موجود في الصفحة بالأساس لذا سنضيفه في محتوى العنصر #content
    $('#content').append('<div id="wrap"></div>');
    $('#content').append('<div class="form-popup"></div>');

    // تحديد عنصر النافذة لإجراء تعديلات على تنسيق CSS
    // إضافةً إلى إستدعاء ملف النموذج البريدي
    $('div.form-popup').each(function() {

        // إستدعاء النموذج البريدي
        $(this).load('contact-form.html');

        // توسيط النموذج حسب عرض الصفحة
        $(this).css('left', $(window).width()/2 - ($(this).width() + 32)/2);
    });

    // إظهار النافذة
    $('#wrap, div.form-popup').fadeIn(500);
});

إذا تم الضغط على علامة X الموجودة في أعلى النافذة وتشير إلى إغلاقها أو تم الضغط على المساحة المحيطة بالنافذة الملونة بالأسود مع وجود الشفافية فيها يتم إزالة النافذة والعودة إلى الصفحة مجدداً، كما تبين الشفرة التالية مع الملاحظات المكتوبة:


$('#wrap, div.form-popup span.close').live('click',function(){
    $('#wrap, div.form-popup').fadeOut(500, function(){
        $(this).remove();
    });
    $(this).die();
});

الشفرة الأخيرة خاصة بإرسال النموذج، إذا تم الضغط على زر الإرسال، يتم إظهار رسالة شكر تفيد بنجاح العملية وبعدم وجود حقل فارغ، أما إذا كانت هناك حقول فارغة يتم إظهار رسالة خطأ تفيد بوجوب تعبئة حقول النموذج، كما تبين الشفرة التالية مع الملاحظات المكتوبة:


// لإرسال النموذج live إستخدام طريقة
// لأن النموذج البريدي عبارة عن عنصر جديد في الصفحة لا يمكن إستخدام الطرق الأخرى للأحداث live إستخدمنا طريقة
$('#contact-submit').live('click', function() {

    // تحديد الحقول من خلال متغيرات جديدة
    var name = $('input#name');
    var email = $('input#email');
    var message = $('textarea#message');

    // التأكد من الحقول أنها ليست فارغة
    if(name.val() != '' && email.val() != '' && message.val() != '') {

        // حذف أي رسالة خطأ أو رسالة نجاح للعملية
        $('div.success, div.error').remove();
        $('input, textarea, label').removeClass('error');

        // وضع رسالة تفيد بنجاح العملية
        $('div.form-popup p').after('<div class="msg success"><p>تم إرسال الرسالة بنجاح، سيصلك الرد في أقرب وقت ممكن.</p></div>');
        $('div.success').hide().fadeIn(500);

    } else {
        // إذا كانت الحقول فارغة فسيتم وضع رسالة تفيد بذلك

        // حذف أي رسالة خطأ أو رسالة نجاح للعملية
        $('div.success, div.error').remove();
        $('input, textarea, label').removeClass('error');

        // وضع رسالة الخطأ بأنه يجب كتابة الحقول جيداً
        $('div.form-popup p').after('<div class="msg error"><p>الرجاء التأكد من تعبئة الحقول جيداً</p></div>');
        $('div.error').hide().fadeIn(500);

        // إذا كان حقل الإسم أو البريد الإلكتروني أو الرسالة فارغ يتم إضافة صنف خاص للحقل وعنوانه يشير إلى وجود الخطأ
        // وهو يقوم بتغيير لون النص ولون حدود الحقل إلى اللون الأحمر
        if(name.val() == '') {
            $('input#name, label[for=name]').addClass('error');
        }

        if(email.val() == '') {
            $('input#email, label[for=email]').addClass('error');
        }

        if(message.val() == '') {
            $('textarea#message, label[for=message]').addClass('error');
        }
    }

    // Javascript لإلغاء إرسال النموذج بالطريقة العادية ما دام أن المستخدم يتصفح الموقع بإستخدام
    return false;
});

بهذا نكون إنتينا من الدرس.