קורס Front End למתכנתים שיעור תרגול: מחלקות ואירועים


זהו נושא דיון מלווה לערך המקורי שב־https://www.tocode.co.il/bundles/frontend/lessons/classes-lab

היי ינון אני עובד על התרגיל השני ואני די תקוע.
קוד 1 - https://codepen.io/Adgha/pen/PomdNRv
קוד 1 עובד לי כשאני מחפש משהו בתיבת חיפוש האפשרויות מצטמטמות לי אבל מחינת כתיבת הקוד אם תשים לב לשורה 69 בשביל שמשתמש יצליח להפעיל את האפשרות הזאת צריך להפעיל EVENT מחוץ לCLASS

והמצב הרצוי הוא כזה
קוד 2 - https://codepen.io/Adgha/pen/JjNaXBL
כפי שתראה בשורה 72 שהמשתמש קורא לפונקציה שהוא מעוניין בה וזהו.
אבל כשאני עושה EVENT בתוך הפונקציה שבCLASS אז היא לא עובדת כמו שצריך
כפי שאפשר לראות בשורה 18.

אני מבקש את עזרתך בנושא תודה=)

הי @11111

למה לא להעביר את ה addEventListener ל constructor ? משהו כזה (שורה אחרונה):

    constructor(el){
        el.innerHTML = `
        <button id="start">Search</button>
        <input type="text" id="search" />
        <ul></ul>` // this is the main content on the <div> 

        this.button = el.querySelector('button'); 
        this.ul = el.querySelector('ul');
        this.input = el.querySelector('input');
        this.input.addEventListener('input', this.filter)
    }

אמת נכון לגמרי לא חשבתי על זה, תודה רבה=)

היי , מצרף פתרון שעשיתי זה נראה קצת מסורבל וארוך וגם קצת פחות טוב עבור זמן ריצה בחלק של הwhile שם אני מסיר כל הזמן את התוצאות שהיו קודם, אשמח לראות קוד יותר יעל ונקי, תודה

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF8" />
        <link rel="stylesheet" href="https://unpkg.com/sakura.css@1.0.0/css/sakura.css" />
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
    </head>

    <body>
        <script src="Search.js"></script>
    </body>
</html>




class Search {
    // NEVER USE document.querySelector INSIDE A COMPONENT
    constructor(el){
        el.innerHTML = `<div >
        <button id="start">
        <i class="fas fa-search"></i> </button>
        <input type="search" id="search" placeholder="Search for names.." />
        <ul></ul> </div>` // this is the main content on the <div> 

        this.button = el.querySelector('button'); 

        this.div = this.button.parentElement;
        this.div.setAttribute("style", `
           padding: 12px 20px 12px 40px;
           border: 1px solid #ddd;
        `);

        this.ul = el.querySelector('ul');
        this.ul.setAttribute("style", `
           display: none;
        `);
       

        this.input = el.querySelector('input');
    

        const style = document.createElement('style');
        style.innerHTML = `
          input {
              font-size: 16px; 
              width: 88%;
          }
          input:focus, :host([matches-are-visible]) input {
            background-color: var(--search-box-results-bg, white);
          }`   
    document.head.appendChild(style);


    this.input.addEventListener('input', this.filter)
    }

  
    filter = () => {
        const items = ["Corn", "Potato","pizza"];
        const frag = document.createDocumentFragment();
        
        while (this.ul.children.length >0)
           this.ul.removeChild(this.ul.lastElementChild);
        
        this.ul.style.display = "none";
        if (this.input.value!=""){  
            for(let item of items){
            if (item.toLowerCase().search(this.input.value.toLowerCase()) == "0" ){
                const li = document.createElement('li');
                li.textContent = item;
                frag.appendChild(li);
            }
            } 
        }
        if (frag.childElementCount>0)
        {
            this.ul.style.display = "block";
            //this.ul.setAttribute("style", `display: none; `);
            this.ul.appendChild(frag);
        }
        

    }
    
}

    const e1 = document.createElement('div');
    document.body.appendChild(e1);
    const c1 = new Search(e1);

הי,

דרך יותר קלה למחוק את כל הילדים היא לרוקן את ה innerHTML, כלומר:

this.ul.innerHTML = '';

דבר שני לגבי כל ה CSS - אני אישית מעדיף לכתוב אותו בקובץ CSS נפרד ובקומפוננט רק להוסיף קלאס שיתאים ל CSS. השיטה שלך גם טובה, ושווה לבדוק את הספריה JSS שנותנת ממשק קצת יותר נוח לכתיבת קוד CSS בתוך ה JavaScript:

היי ינון אשמח לביקורת על תרגיל מספר 2 ואיך אוכל לכתוב את הקוד בצורה יעילה יותר:

קובץ JS:


class autoCorrect {
    constructor(el) {
        this.userTxt='';
        this.drinks = ['Coffee','Tea','Milk','Cola','Orange juice','Lemonade','Fruit juice','Water','Milkshake','Chocolate milk'];
        el.innerHTML = `
        <input class='log' type="text" placeholder="Search..">
        <ul id='list'>
        </ul>
        `;

        this.log=el.querySelector('.log'); // input element
        this.list=el.querySelector('#list'); // ul element
        this.log.addEventListener('input',this.getText); //input event
    }
     
    getText = (event) => {

        // reset ul
        if(this.list.childElementCount > 0){
            const myNode = document.getElementById("list");
            while (myNode.firstChild) {
                myNode.removeChild(myNode.lastChild); // remove all ul childs
            }
        }
        
        // get user text
        this.userTxt = event.target.value;

        if (this.userTxt.length > 0){ //the user added text
            let temp=[];
            let numberOfChars = this.userTxt.length;

            for(let i=0; i<this.drinks.length; i++ ){
                if(this.drinks[i].toLowerCase().startsWith(this.userTxt.substring(0, numberOfChars).toLowerCase())){
                    let elm = document.createElement(`li`); // add ul child
                    this.list.appendChild(elm);
                    elm.innerHTML=this.drinks[i];
                }

            }
            
        }else{ //no text
            this.list.innerHTML = ''; // clean the page
        }     
        
    }
}


// create element
const element1 = document.createElement(`div`);
document.body.appendChild(element1); // add element to body

getWords = new autoCorrect(element1);

קובץ HTML מכיל :

<body>
        <script src="autoCorrect.js"></script>
    </body>

קובץ CSS, אין השפעה גדולה מידי על הקוד, רק נראות בסיסית:

body{
    padding: 5px;
    margin: 10px;
}

.log{
    width: 150px;
    font-size: medium;
    border-color: 2px solid black;

}

.log .list{
    display: block;
    
}

הי,

בטח -

  1. בשביל למחוק את כל הילדים של ה ul עדיף להשתמש ב:
myNode.innerHTML = '';
  1. עדיף ליצור Fragment ולהוסיף אליו את ה li-ים במקום ישר ל ul:
    Document.createDocumentFragment() - Web APIs | MDN

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

  3. (בונוס) יש מבני נתונים יותר יעילים מרשימה כדי לשמור רשימה של טקסטים שאפשר להשלים איתם. הרעיון בגדול הוא לשמור אותם מסודרים לפי התחיליות שלהם. שווה לקרוא על מבנה הנתונים trie ולראות איך הוא יכול לעזור פה:
    https://www.javatpoint.com/trie-data-structure

  4. (בונוס) כיוון אחר ששווה להכיר הוא מאפיין list של input שמאפשר לחבר input לרשימה ולקבל השלמה אוטומטית במתנה מהדפדפן. אפשר לקרוא על זה כאן:
    Lightweight Autocomplete Controls with the HTML5 Datalist - SitePoint

עבודה מצוינת ממש שמחתי לקרוא ומקווה שהטיפים פה יהיו מעניינים ומועילים

אני אעבור על כל הטיפים. תודה רבה!