אב

המדור לחיפוש קרובים ב-jQuery

באחד האתרים שאני עובדת עליו, יש בדף הראשי אזור של תגובות אחרונות, ואזור של פוסטים מקטגוריה מסויימת. באזורים האלה, אני מראה רק 3 פריטים כשהדף עולה, ומתחתם יש כפתור של “טען עוד”, שלחיצה עליו מראה את השאר. אינני משתמשת ב-ajax מפני שהמידע אינו כבד, אלא אני מסתירה אותם באמצעות JS+ CSS (אסביר בסוף מדוע אני מסתירה עם JS, וההשלכות של זה).

בשני אזורים אלה, הפריטים המוסתרים והגלויים הם li-ים בתוך ul, והכפתור “טען עוד” מופיע אחריהם. זהו המבנה המדובר בשניהם:

<ul id="recentcomments">
    <li class="recentcomments">...</li>
    <li class="recentcomments">...</li>
    <li class="recentcomments">...</li>
    <li class="recentcomments hide">...</li>
    <li class="recentcomments hide">...</li>
</ul>
<div class="showMore toOpen" id="moreComments">טען עוד</div>

מאחר שאת ההסתרה כאמור אני מבצעת ב-JS, אני צריכה למצוא את האלמנטים הרלוונטיים, ולהצמיד להם class בשם hide. התלבטתי, איך מתוך ה-JS להצמיד את ה-class המתאים רק לאלמנטים שאחרי הילד השלישי. כמובן שיכולתי לגשת להורה (ה-ul), לקבל את כל הילדים שלו, ולבצע לולאה עליהם כך שמהילד השלישי יוצמד אליהם ה-hide. אבל זה נראה היה לי קוד מנופח מדי לביצוע פעולה כה קטנה. אז הלכתי לבקר את ידידי jQuery, ושאלתי אותו מה יש לו להציע במדור לחיפוש קרובים. הדברים שמצאתי שם היו כאלה מגניבים שהייתי מוכרחה לשתף .

הדבר הראשון שמצאתי היה הפונקציה הנפלאה nextAll. הפונקציה הזו מביאה את כל האחים שבאים אחרי הסלקטור שבחרתי. אז כך עשיתי:

 $("#secondary .showMore").prev().children(':nth-child(3)').nextAll().addClass('hide');

הסבר: בחרתי את הכפתור ( $("#secondary .showMore")), ביקשתי את האח הקודם שלו – ה-ul- ע”י prev(), ביקשתי את הילדים של האח הזה, עם פרמטר של הילד השלישי (children(':nth-child(3)')), ואז ביקשתי את כל האחים שאחריו (nextAll()) – ולהם הצמדתי את ה-hide.נכון מדליק?

עכשיו, זה מתאים אחלה אם המבנה הוא כמו שהיה אצלי – שהכפתור הוא מחוץ לאלמנט שמחזיק את כל הפריטים. אבל מה קורה במקרה שהכפתור הוא אח של הפריטים, ולפריטים יש עוד אחים לפניכן שבכלל לא קשורים? אז אי אפשר לקבל דווקא את הילד השלישי, מפני שלהורה יש עוד ילדים לפני הפריטים שלנו. במקרה כזה הייתי רוצה לבחור את הכפתור שלי, וללכת אחורה עד הילד השלישי.  אז מתברר של-jQuery יש פתרון גם לזה: הפונקציה המופלאה prevUntil:

$("#morePosts").prevUntil('.hentry:nth-child(3)').addClass('hide');

הסבר: בחרתי את הכפתור ($("#morePosts")), וביקשתי מ-jQuery שילך אחורה עד שימצא את הילד השלישי שיש לו class בשם hentry, כך (prevUntil('.hentry:nth-child(3)')), ויצמיד לכולם את ה-hide. זה בעיני אפילו יותר מדליק מהקודם – שה-jQuery יכול ללכת אחורה עד תנאי עצירה. עוד לא תמו כל פלאייך!

ההחלטה איך להסתיר את האלמנטים לא פשוטה לי: יכולתי להסתיר אותם ב-CSS בלבד ע”י נתינת ה-class ב-php, אבל אני חושבת שמאחר שאת הגילוי אני עושה ב-JS, נכון לבצע גם את ההסתרה ב- JS – ע”י הצמדת class בשם hide שמבצע display: none – אחרת מי שיש לו CSS אך אין לו JS, לא יוכל לגלות אותם לעולם… מצד שני, יש לזה עלות בביצועים: הפונקציות האלה, מגניבות ככל שתהיינה, דורשות זמן. לכן כשהאתר עולה, יש כמה שברירי שניה שבהם רואים את האלמנטים, ורק אז הם נעלמים. אמנם, האלמנטים האלה נמצאים מתחת ל-fold – כך שכשנכנסים לראשונה לאתר לא חשים שזה קורה – אבל אם נמצאים כבר באמצע הדף, ואז מרפרשים, אז כן רואים את שבריר השניה הזה. האם העיכוב הזה שווה את ההסתרה ב-JS? טרם החליטותי…

 

כתבו תגובה

כתובת הדוא"ל שלכם לא תוצג.