לדלג לתוכן

3.3 יצירה ומחיקה של אלמנטים תרגול

תרגול - יצירה ומחיקה של אלמנטים

תרגיל 1 - יצירה בסיסית

צרו דף HTML עם div ריק (<div id="output"></div>) וכפתור. כשלוחצים על הכפתור, צרו ב-JavaScript את המבנה הבא והוסיפו אותו ל-div:

<article class="post">
    <h2>My First Post</h2>
    <p class="meta">Published on 2024-01-15</p>
    <p class="content">This is the content of my first blog post.</p>
    <a href="#" class="read-more">Read more</a>
</article>

השתמשו אך ורק ב-createElement, textContent, classList, ו-append/appendChild. לא להשתמש ב-innerHTML.

תרגיל 2 - רשימת קניות

צרו דף עם שדה טקסט, כפתור "Add" ורשימה ריקה (<ul id="shopping-list"></ul>).

  1. כשלוחצים "Add" או Enter, הוסיפו פריט חדש לרשימה
  2. כל פריט צריך להכיל את הטקסט ולצדו כפתור "X" שמוחק את הפריט
  3. אם השדה ריק, אל תוסיפו כלום
  4. אחרי הוספה, נקו את השדה והחזירו את הפוקוס אליו
  5. הוסיפו מונה שמציג כמה פריטים יש ברשימה

תרגיל 3 - טבלה דינמית

נתון מערך של אובייקטים:

const students = [
    { name: "Alice", grade: 92, status: "pass" },
    { name: "Bob", grade: 45, status: "fail" },
    { name: "Charlie", grade: 78, status: "pass" },
    { name: "Diana", grade: 88, status: "pass" },
    { name: "Eve", grade: 34, status: "fail" }
];

צרו ב-JavaScript טבלה מלאה (<table>) שמציגה את הנתונים:
1. צרו שורת כותרת (<thead> עם <th>) עם העמודות: Name, Grade, Status
2. צרו את ה-<tbody> עם שורה לכל סטודנט
3. סטודנטים שנכשלו (status: "fail") יקבלו צבע רקע אדום בהיר
4. השתמשו ב-DocumentFragment להוספת השורות

תרגיל 4 - העברה וסידור מחדש

צרו דף עם שתי רשימות: "Available" ו-"Selected":

<div style="display: flex; gap: 40px;">
    <div>
        <h3>Available</h3>
        <ul id="available">
            <li>JavaScript</li>
            <li>Python</li>
            <li>Java</li>
            <li>C++</li>
            <li>Ruby</li>
        </ul>
    </div>
    <div>
        <h3>Selected</h3>
        <ul id="selected"></ul>
    </div>
</div>

כשלוחצים על פריט ברשימה "Available", הוא עובר לרשימה "Selected" (ונמחק מ-Available). כשלוחצים על פריט ב-"Selected", הוא חוזר ל-"Available".

רמז: כשמוסיפים אלמנט שכבר נמצא ב-DOM למיקום חדש, הוא מועבר אוטומטית (לא צריך למחוק ידנית).

תרגיל 5 - שכפול כרטיסים

צרו "תבנית" (template) של כרטיס:

<div id="card-template" style="display: none;">
    <div class="card">
        <img src="" alt="" class="card-image">
        <h3 class="card-title">Title</h3>
        <p class="card-description">Description</p>
        <button class="card-btn">Details</button>
    </div>
</div>

<div id="cards-container"></div>

נתון מערך:

const products = [
    { title: "Laptop", description: "Powerful laptop", image: "https://picsum.photos/200/150?random=1" },
    { title: "Phone", description: "Smart phone", image: "https://picsum.photos/200/150?random=2" },
    { title: "Tablet", description: "Light tablet", image: "https://picsum.photos/200/150?random=3" }
];

השתמשו ב-cloneNode(true) כדי לשכפל את התבנית עבור כל מוצר. שנו את התוכן של כל שכפול (title, description, image) והוסיפו אותו ל-container.

תרגיל 6 - insertAdjacentHTML

צרו דף עם אלמנט:

<div id="target">
    <p>Original content</p>
</div>
<button id="btn-before-begin">beforebegin</button>
<button id="btn-after-begin">afterbegin</button>
<button id="btn-before-end">beforeend</button>
<button id="btn-after-end">afterend</button>
<button id="btn-reset">Reset</button>

כל כפתור יוסיף HTML במיקום המתאים באמצעות insertAdjacentHTML. כל הוספה תוסיף פסקה עם מספר רץ (פסקה 1, פסקה 2...). כפתור Reset יחזיר את ה-div למצבו המקורי.

תרגיל 7 - רשימת אנשי קשר

צרו אפליקציה שלמה לניהול אנשי קשר:

  1. טופס עם שדות: שם, טלפון, אימייל
  2. כפתור "Add Contact"
  3. אזור תצוגה שמציג כרטיס לכל איש קשר
  4. כל כרטיס מכיל: את הפרטים, כפתור "Edit" וכפתור "Delete"
  5. כפתור "Delete" מוחק את הכרטיס (עם confirm לפני המחיקה)
  6. כפתור "Edit" מאפשר לשנות את השם באמצעות prompt
  7. מונה שמציג כמה אנשי קשר יש

השתמשו ב-createElement לכל ההוספות (בלי innerHTML) כדי להתאמן ולהתרגל.

תרגיל 8 - innerHTML מול createElement

צרו שתי גרסאות של אותה פונקציה:

const data = [
    { title: "Item 1", description: "Description for item 1", tags: ["new", "sale"] },
    { title: "Item 2", description: "Description for item 2", tags: ["popular"] },
    { title: "Item 3", description: "Description for item 3", tags: ["new"] }
];

גרסה א: פונקציה renderWithInnerHTML(data) שבונה את הרשימה באמצעות innerHTML
גרסה ב: פונקציה renderWithCreateElement(data) שבונה את אותה רשימה באמצעות createElement

כל פריט צריך להיראות ככה:

<div class="item">
    <h3>Item 1</h3>
    <p>Description for item 1</p>
    <div class="tags">
        <span class="tag">new</span>
        <span class="tag">sale</span>
    </div>
</div>

השוו בין שתי הגרסאות - מה יותר קל לקרוא? מה יותר בטוח?

שאלות

  1. מה ההבדל בין appendChild ל-append?
  2. למה innerHTML מסוכן עם קלט ממשתמש?
  3. מה ההבדל בין cloneNode(true) ל-cloneNode(false)?
  4. מה זה DocumentFragment ולמה הוא שימושי?
  5. מה קורה כשמוסיפים אלמנט שכבר קיים ב-DOM למיקום חדש?