From 1109132f09d75da9a28b649c7677bb6ce07c40c0 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:41:45 -0500 Subject: initial commit --- .../build_your_own_function/index.html | 247 ++++++ .../javascript/building_blocks/events/index.html | 588 +++++++++++++ .../building_blocks/functions/index.html | 386 +++++++++ .../he/learn/javascript/building_blocks/index.html | 51 ++ .../building_blocks/looping_code/index.html | 931 +++++++++++++++++++++ .../building_blocks/return_values/index.html | 180 ++++ .../index.html" | 789 +++++++++++++++++ 7 files changed, 3172 insertions(+) create mode 100644 files/he/learn/javascript/building_blocks/build_your_own_function/index.html create mode 100644 files/he/learn/javascript/building_blocks/events/index.html create mode 100644 files/he/learn/javascript/building_blocks/functions/index.html create mode 100644 files/he/learn/javascript/building_blocks/index.html create mode 100644 files/he/learn/javascript/building_blocks/looping_code/index.html create mode 100644 files/he/learn/javascript/building_blocks/return_values/index.html create mode 100644 "files/he/learn/javascript/building_blocks/\327\252\327\240\327\220\327\231\327\235/index.html" (limited to 'files/he/learn/javascript/building_blocks') diff --git a/files/he/learn/javascript/building_blocks/build_your_own_function/index.html b/files/he/learn/javascript/building_blocks/build_your_own_function/index.html new file mode 100644 index 0000000000..47df4e6b3a --- /dev/null +++ b/files/he/learn/javascript/building_blocks/build_your_own_function/index.html @@ -0,0 +1,247 @@ +--- +title: בניית פונקציה משלנו +slug: Learn/JavaScript/Building_blocks/Build_your_own_function +translation_of: Learn/JavaScript/Building_blocks/Build_your_own_function +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Functions","Learn/JavaScript/Building_blocks/Return_values", "Learn/JavaScript/Building_blocks")}}
+ +

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

+ + + + + + + + + + + + +
ידע מוקדם:הכרות בסיסית עם המחשב ועם הבסיס של HTML ו- CSS, וכן סיום במלאו של מודול צעדים ראשונים ב-JavaScript., Functions — פונקציות - חלקי קוד לשימוש חוזר.
מטרה:לספק לכם כלים לבניית פונקציות ולהסביר פרטים שימושיים בהקשר של בניית פונקציות.
+ +

למידה עצמאית: בניית פונקציה

+ +

הפונקציה שנראה לבנות תיקרא displayMessage(). היא תציג הודעה על גבי דף אינטרנט, אשר תחליף את הפונקציה המובנית של הדפדפן alert(). ראינו משהו דומה לפני כן,על מנת לרענן את הזכרון, הדפיסו את הקוד הבא בקונסולה

+ +
alert('This is a message');
+ +

הפונקציה alert מקבל פרמטר אחד כארגומנט - המחרוזת ששתוצג על גבי תיבת ההודעה. נא לשנות המחרוזת על מנת לשנות את ההודעהf

+ +

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

+ +
+

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

+
+ +

הפונקציה הבסיסית

+ +

על מנת להתחיל, בואו נבנה פונקציה בסיסית

+ +
+

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

+
+ +
    +
  1. התחילו בכך שתיצרו עותק מקומי של הקובץ function-start.html. בקובץ אתם תיראו שה-body כולל כפתור אחד. בנוסף הוספנו גם כמה כללי css פשוטים על מנת לעצב את תיבת ההודעה שלנו וכן אלממנט {{htmlelement("script")}} ריקה שבה נוסיף את קוד ה-JavaScriipt שלנו.
  2. +
  3. לאחר מכן, הוסיפו הקוד הבא בתוך האלמנט <script>: +
    function displayMessage() {
    +
    +}
    + אנחנו מתחילים עם המילה השמורה function, אשר משמעותה היא שאנחנו מגדירים פונקציה. לאחר מכן, אנחנו רושמים את שם הפונקציה שנרצה לתת לה, ולאחר מכן סוגריים רגילות () ולאחריהן סוגריים מסולסלות {....}. הפרמטרים שנרצה לתת לפונקציה שלנו - הארגומנטים, ייכנסו בתוך הסוגריים הרגילות (ובמידה שיש לנו כמה ארגומנטים, נפריד ביניהם באמצעות פסיק , ורווח.) את הקוד שנרצה שהפונקציה תריץ בכל פעם שנקרא לה אנחנו נשים בתוך הסוגריים המסולסות {....}.
  4. +
  5. לבסוף, הוסיפו את התקוד הבא בתוך הסוגריים המסולסלות +
    var html = document.querySelector('html');
    +
    +var panel = document.createElement('div');
    +panel.setAttribute('class', 'msgBox');
    +html.appendChild(panel);
    +
    +var msg = document.createElement('p');
    +msg.textContent = 'This is a message box';
    +panel.appendChild(msg);
    +
    +var closeBtn = document.createElement('button');
    +closeBtn.textContent = 'x';
    +panel.appendChild(closeBtn);
    +
    +closeBtn.onclick = function() {
    +  panel.parentNode.removeChild(panel);
    +}
    +
  6. +
+ +

נעבור על הקוד שהוספנו שורה אחר שורה

+ +

השורה הראשונה משתמשת בפונקציה של DOM API הנקראת {{domxref("document.querySelector()")}}, על מנת לבחור אלמנט מסוג {{htmlelement("html")}} ולאחסן הפנייה אליו בתוך משתנה שנקרא html, כדי שנוכל לבצע איתו דברים מאוחר יותר:

+ +
var html = document.querySelector('html');
+ +

החלק הבא בקוד שלנו משתמש בפונקציה נוספת של DOM API הנקראת {{domxref("document.createElement()")}} על מנת ליצור אלמנט מסוג {{htmlelement("div")}} ואנו מאחסנים הפניה אליו בתוך המשתנה שנקרא panel. האלמנט הזה יהיה הקונטיינר החיצוני של תיבת ההודעה שלנו.

+ +

לאחר מכן אנחנו משתמשים בפונקציה נוספת של DOM API שנקראת class על מנת לקבוע {{domxref("Element.setAttribute()")}} למשתנה msgBox שלנו עם הערך msgBox. זה אמור להקל עלינו לעצב את האלמנט - אם תסתכלו ב-CSS שבדךף, אתם תראו שאנחנו משתשמים בסלקטור של CSS .msgBox על מנת לעצב את תיבת ההודעה והתוכן שלה.

+ +

לבסוף - אנחנו קוראים לפונקציית DOM נוספת שנקראת {{domxref("Node.appendChild()")}} על גבי המשתנה html , אשר משרשרת את האלמנט שהיא מקבלת כארגומנט לאלמנט שהיא הופעלה עליו. כאן אנחנו מציינים שאנחנו רוצים שהאלמנט <div> יהיה אלמנט ילד של האלמנט <html>. אחנו צריכים להוסיף פונקציה זו בכל פעם שאנחנו משתמשים בפונקציה {{domxref("document.createElement()")}}, מכיוון שהאלמנט שיצרנו לא יופיע בעצמו ולא יתחבר בעצמו לאלמנט אחר - אנחנו צריכים לציין איפה אנחנו רוצים לשים אותו ולמי הוא יהיה קשור.

+ +
var panel = document.createElement('div');
+panel.setAttribute('class', 'msgBox');
+html.appendChild(panel);
+ +

ב-2 החלקים הבאים אנחנו עושים שימוש באותן פונקציות createElement() ן- appendChild() שהשתמשנו בהן על מנת ליצור שני אלמנטים חדשים: {{htmlelement("p")}} ו- {{htmlelement("button")}} — ומכניסים אותם בתוך הדף כאלמנטים ילדים של <div> panel. לאחר מכן אנחנו משתמשים בפרופ׳ {{domxref("Node.textContent")}} - אשר מייצג בעצם את תוכן הטקסט של אלמנט - על מנת להכניס הודעה בתוך הפסקה וכן אנחנו מוסיפים את התו 'x' בתוך הכפתור. הכפתור הזה צריך להיות לחוץ/מופעל כשהמשתמש רוצה לסגור את תיבת ההודעה.

+ +
var msg = document.createElement('p');
+msg.textContent = 'This is a message box';
+panel.appendChild(msg);
+
+var closeBtn = document.createElement('button');
+closeBtn.textContent = 'x';
+panel.appendChild(closeBtn);
+ +

לבסוף, אנחנו משתמשים במאזין אירוע ומטפל אירוע - {{domxref("GlobalEventHandlers.onclick")}} - על מנת להוסיף האזנה להתרחשות אירוע של לחיצה (במקרה הזה לחיצה על ) closeBtn וטיפול באותו אירוע על ידי הפונקציה האנונימית המכילה קוד שמוחק את כל ה-panel מהדף - כלומר מוחק את תיבת ההודעה.

+ +

בקצרה, מאזין האירוע onclick הוא פרופ׳ שזמין עבור כפתור (ובעצם זמין עבור כל אלמנט בדף) שיכול להיות מוגדר לפונקציה שתבצע קוד מסויים כאשר הכפתור/האלמנט נלחץ. אנחנו נלמד על כך לעומק במאמר שלנו בנושא אירועים. שימו לב שוב שמטפל האירוע של מאזין האירוע onclick שווה לפונקציה אנונימית, אשר מכילה קוד שירוץ כאשר הכפתור נלחץ. שורת הקוד שבתוך הפונקציה האנונימית משתמש בפונקציה של ה- DOM API בשם {{domxref("Node.removeChild()")}} על מנת להסיר אלמנט בן של אלמנט - במקרה זה של אלמנט <div>.

+ +
closeBtn.onclick = function() {
+  panel.parentNode.removeChild(panel);
+}
+ +

בעיקרון - כל הקוד הזה פשוט יוצר בלוק של HTML שנראה כך ומכניס את זה לתוך הדף:

+ +
<div class="msgBox">
+  <p>This is a message box</p>
+  <button>x</button>
+</div>
+ +

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

+ +

קריאה לפונקציה/הפעלת הפונקציה

+ +

כעת יש לנו את הגדרת הפונקציה בתוך האלמנט 555555, אבל היא לא תבצע כלום אם לא נקרא לה.

+ +
    +
  1. נסו לכלול את הקוד הבא מחת לפונקציה על מנת לקרוא לה: +
    displayMessage();
    + שורה זו בעצם קוראת פונקציה (Invoking the function) וגורמת לה לרוץ מיד. כאשר תשמרו את הקוד ותעלו מחדש את הדף בדפדפן, אתם תראו שתיבת ההודעה הופיע מיד, פעם אחת. אחרי הכל, קראנו לפונקציה רק פעם אחת.
  2. +
  3. +

    כעת, פתחו את הקונסולה והדפיסו את השורה למעלה שוב, ואתם תראו את ההודעה שוב. כלומר בנינו פונקציה שאנחנו יכולים להשתמש בה שוב ושוב.

    + +

    רוב הסיכויים שנרצה שתיבת ההודעה תופיע כתגובה לאירועים מסויימים של המערכת או של המשתמש. ביישומים אמיתיים, תיבת הודעה שכזו תיקרא בתגובה למידע חדש שזמין או לשגיאה שנוצרה, או כאשר המשתמש מוחק את הפרופיל שלו (״האם אתה בטוח רוצה למחוק את הפרופיל? וכד׳).

    + +

    בתרגול זה, אנחנו נגרום לתיבת ההודעה להופיע כאשר המשתמש לוחץ על כפתור.

    +
  4. +
  5. מחקו את השורה שהוספתם.
  6. +
  7. כעת, אנחנו נבחר את הכפתור ונאחסן הפניה אליו בתוך משתנה. הוסיפו את הקוד הבא לקוד שלהם, מעל הגדרת הפונקציה : +
    var btn = document.querySelector('button');
    +
  8. +
  9. לבסו, הוסיפו את הקוד הבא, מתחת לקוד שהוספתם בסעיף הקודם: +
    btn.onclick = displayMessage;
    + בדרך דומה ל ...closeBtn.onclick בתוך הפונקציה, כאן אנחנו קוראים קוד מסויים בתגובה כך שהכפתור נלחץ. אבל במקרה הזה במקום לקרוא לפונקציה אנונימית המכילה את אותו קוד, אנחנו קוראים לפונקציה שלנו בשמה באופן מפורש.
  10. +
  11. נסו לשמור ולרענן את הדף - אתם אמורים לראות את תיבת ההודעה כאשר הכפתור נלחץ.
  12. +
+ +

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

+ +
btn.onclick = displayMessage();
+ +

ותרעננו את הדף, אתם תיראו שהתיבת ההודעה הופיע מבלי שלחצנו על הכפתור. הסוגריים () בהקשר זה לפעמים נקראים "function invocation operator". אנחנו משתמשים בהם כאשר אנחנו רוצים להריץ את הפונקציה באופן מיידי בתוך הסקופ הנוכחי. באותו דרך, הקוד שבתוך הפונקציה האנונימית לא ירוץ ישר, שכן הוא נמצא בתוך הסקופ של הפונקציה בלבד - שכאמור תופעל רק כאשר כפתור יילחץ.

+ +

אם ניסיתם את התרגול הקודם של הוספת (), אנא וודאו שמחקתם אותם לפני שאתם ממשיכים

+ +

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

+ +

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

+ +
    +
  1. תחילה, עדכנו את השורה הראשונה של הפונקציה: +
    function displayMessage() {
    + +
    לקוד הבא:
    + +
    function displayMessage(msgText, msgType) {
    + כעת, כאשר אנחנו קוראים לפונקציה, אנחנו מספקים לה שני ערכים של משתנים בתוך הסוגריים () על מנת לציין את תוכן ההודעה שתוצג ואת סוג ההודעה.
  2. +
  3. על מנת לעשות שימוש בפרמטר הראשון, עדכנו את הקוד שבתוך הפונקציה : +
    msg.textContent = 'This is a message box';
    + +
    לקוד הבא
    + +
    msg.textContent = msgText;
    +
  4. +
  5. לבסוף, אנחנו נרצה לעדכן כעת את הפונקציה כך שתכלול הודעה מעודכנת . שנה את השורה הבאה: +
    btn.onclick = displayMessage;
    + +
    לקוד הבא :
    + +
    btn.onclick = function() {
    +  displayMessage('Woo, this is a different message!');
    +};
    + If we want to specify parameters inside parentheses for the function we are calling, then we can't call it directly — we need to put it inside an anonymous function so that it isn't in the immediate scope and therefore isn't called immediately. Now it will not be called until the button is clicked.
  6. +
  7. עכשיו טען מחדש ונסה שוב את הקוד ותראה שהוא עדיין עובד כמו מקודם ,רק שעכשיו גם התווסף אפשרות לשנות את ההודעה שבתוך הפרמטר כדי להציג הודעות שונות בתיבה! 
  8. +
+ +

פרמטר מורכב יותר

+ +

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

+ +
    +
  1. First of all, download the icons needed for this exercise (warning and chat) from GitHub. Save them in a new folder called icons in the same location as your HTML file. + +
    Note: The warning and chat icons were originally found on iconfinder.com, and designed by Nazarrudin Ansyari — Thanks! (The actual icon pages were since moved or removed.)
    +
  2. +
  3. Next, find the CSS inside your HTML file. We'll make a few changes to make way for the icons. First, update the .msgBox width from: +
    width: 200px;
    + +
    ל
    + +
    width: 242px;
    +
  4. +
  5. Next, add the following lines inside the .msgBox p { ... } rule: +
    padding-left: 82px;
    +background-position: 25px center;
    +background-repeat: no-repeat;
    +
  6. +
  7. Now we need to add code to our displayMessage() function to handle displaying the icons. Add the following block just above the closing curly brace (}) of your function: +
    if (msgType === 'warning') {
    +  msg.style.backgroundImage = 'url(icons/warning.png)';
    +  panel.style.backgroundColor = 'red';
    +} else if (msgType === 'chat') {
    +  msg.style.backgroundImage = 'url(icons/chat.png)';
    +  panel.style.backgroundColor = 'aqua';
    +} else {
    +  msg.style.paddingLeft = '20px';
    +}
    + Here, if the msgType parameter is set as 'warning', the warning icon is displayed and the panel's background color is set to red. If it is set to 'chat', the chat icon is displayed and the panel's background color is set to aqua blue. If the msgType parameter is not set at all (or to something different), then the else { ... } part of the code comes into play, and the paragraph is simply given default padding and no icon, with no background panel color set either. This provides a default state if no msgType parameter is provided, meaning that it is an optional parameter!
  8. +
  9. Let's test out our updated function, try updating the displayMessage() call from this: +
    displayMessage('Woo, this is a different message!');
    + +
    to one of these:
    + +
    displayMessage('Your inbox is almost full — delete some mails', 'warning');
    +displayMessage('Brian: Hi there, how are you today?','chat');
    + You can see how useful our (now not so) little function is becoming.
  10. +
+ +
+

לתשומת לב: אם אתם נתקלים בבעיות או הדוגמא אינה עובדת לכם, אנא בדקו את הקוד שלכם אל מול הקוד הסופי שלנו ב- GitHub (או בדף האינטרנט או שאלו אותנו

+
+ +

לסיכום

+ +

במאמר זה ניסינו להסביר לכם את התהליך של בניית פונקציה בעצמנו, כאשר עם עט עבודה נוספת, יכול להפוך לפרוייקט אמיתי. במאמר הבא אנחנו נסיים לעבור על נושא פונקציות ונסביר עקרון חשוב נוסף בנושא זה - ערכי החזרה — return values.

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Functions","Learn/JavaScript/Building_blocks/Return_values", "Learn/JavaScript/Building_blocks")}}

+ +

במודול זה

+ + diff --git a/files/he/learn/javascript/building_blocks/events/index.html b/files/he/learn/javascript/building_blocks/events/index.html new file mode 100644 index 0000000000..9fc4363939 --- /dev/null +++ b/files/he/learn/javascript/building_blocks/events/index.html @@ -0,0 +1,588 @@ +--- +title: היכרות ראשונית עם אירועים - Events +slug: Learn/JavaScript/Building_blocks/Events +translation_of: Learn/JavaScript/Building_blocks/Events +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Return_values","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}}
+ +

אירועים (Evants) אלו פעולות או התרחשויות אשר קורות במערכת שאנחנו מתכנתים בה, והמערכת אומרת לנו  בדרך מסויימת על ההתרחשות שלהם, כך שאנחנו יכולים להגיב להתרחשות של האירוע המסויים בדרך מסויימת שנרצה. לדוגמא אם משתמש לחץ על כפתור באתר, אולי נרצה בתגובה לטפל באירוע הלחיצה הזה על ידי הצגת הודעה כלשהי. במאמר זה אנחנו נדון בעקרונות החשובים של events ונסתכל כיצד הם עובדים בדפדפדנים. אנחנו לא נרחיב יותר מדי, אלא רק מה שתצטרכו לדעת בשלב זה.

+ + + + + + + + + + + + +
ידע מוקדם:הכרות בסיסית עם המחשב ועם הבסיס של HTML ו- CSS, וכן סיום במלאו של מודול צעדים ראשונים ב-JavaScript.
מטרה:להבין את התיאוריה הבסיסית של אירועים וכיצד הם עובדים בדפדפנים וכיצד אירועים יכולים להיות שונים בסביבות פיתוח שונות.
+ +

מה הם אירועים? 

+ +

כפי שרשמנו למעלה, אירועים, events, הם פעולות או התרחשויות שקורות במערכת שאנחחנו מתכנתים עליה - המערכת שולחת סימן מסויים שהאירוע מתרחש וגם מספקת לנו מכניזם מסויים שעל פיו כלומר, קוד מסויים ירוץ בתגובה להתרחשות אירוע מסויים. כמו בדוגמא עם לחיצת הכפתור שפירטנו למעלה. כאשר האירוע של ״לחיצת כפתור״ התרחש, הדפדפן שלח לנו סימן מסויים שהתרחש אירוע וטיפלנו בו באמצעות הקפצת חלונית.

+ +

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

+ +

יש הרבה סוגים של אירועים שיכולים להתרחש. הנה דוגמא קטנה שלהם:

+ + + +

תוכלו לראות בדף MDN בנושא Event reference שיש לא מעט סוגי אירועים שניתן לטפל בהם - כלומר להגיב להתרחשותם.

+ +

לכל אירוע זמין יש ״מטפל אירוע״ - event handler, שזה בעצם בלוק של קוד שבדרך כלל זו פונקציה שאנחנו נגדיר בעצמנו ושירוצו כאשר האירוע החל להתרחש. שימו לב שלפעמים event handlers נקראים event listeners - ״מאזיני אירוע״ בעיקרון, הם כמעט אותו דבר מבחינתנו כרגע, אבל יש הבדלים ביניהם, הם עובדים יחד: מאזין אירוע - event listeners - מאזין להתרחשות האירוע, ואילו מטפל האירוע - event handlers, מטפל באותו אירוע שהתרחש - (הקוד שמורץ בתגובה להתרחשות של אותו אירוע).

+ +
+

לתשומת לב: חשוב לדעת כי אירועי web אינם חלק מהבסיס של JavaScript - הם מוגדרים כחלק מה-API של JavaScript המובנים בתוך הדפדפן.

+
+ +

דוגמא

+ +

נסתכל על דוגמא פשוטה על מנת להסביר את הנושא. ראינו כבר אירועים ו-event handlers בהרבה מהדוגמאות במהלך הקורס אבל בואו נרענן את הזיכרון.

+ +

הסתכלו בדוגמא הבאה, יש לנו אלמנט {{htmlelement("button")}} אחד, אשר כאשר הוא נלחץ, הוא שנה את הצבע של הרקע לצבע אקראי:

+ +
<button>Change color</button>
+ + + +

קוד ה-JavaScript שלנו נראה כך:

+ +
var btn = document.querySelector('button');
+
+function random(number) {
+  return Math.floor(Math.random()*(number+1));
+}
+
+btn.onclick = function() {
+  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+}
+ +

בדוגמא למעלה, אחסנו הפניה לאלמנט <button> בתוך משתנה שנקרא btn, באמצעות פונקציית {{domxref("Document.querySelector()")}}. בנוסף ,הגדרנו פונקציה שמחזירה לנו מספר אקראי. החלק השלישי של הקוד הוא מטפל האירוע - event handler. המשתנה btn מצביע על אלמנט  <button> ולסוג הזה של האובייקט יש מספר מסוים של אירועים שיכולים להתרחש עליו, ולכן יש מספר מטפלי אירוע זמינים עבורו.

+ +

בדוגמא זו אנחנו מקשיבים בעצם לאירוע/התרחשות של לחיצת עכבר באמצעות השמת ערך לתכונה (property) של event handler השווה לפונקציה אנונימית. פונקציה אנונימית זו מכילה קוד שמייצר צבע רנדומלי בפורמט rgb וקובעת את ה-background-color לצבע זה.

+ +

הקוד שבפונקציה האנונימית ירוץ בכל פעם שאירוע הלחיצה על האלמנט <button> יתרחש, כלומר בכל פעם שהמשתמש לחץ על האלמנט הזה.

+ +

התוצאה של הדוגמא תהא כך:

+ +

{{ EmbedLiveSample('A_simple_example', '100%', 200, "", "", "hide-codepen-jsfiddle") }}

+ +

זה לא רק בדפי האינטרנט

+ +

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

+ +

לדוגמא, Node.js היא סביבה המאפשרת לנו הרצה ושימוש ב-JavaScript בצד השרת. מודל האירועים של Node.js מתבסס על מאזינים (listeners) אשר מאזינים לאירועים ועל פולטים (emitters) אשר פולטים אירועים בתדירות מסויימת - זה לא נשמע שונה, אבל הקוד הוא שונה, ושם מתבצע שימוש בפונקציות כמו ()on על מנת לרשום מאזין אירוע ו-()once על מנת לרשום מאזין אירוע שיאזין באופן חד פעמי ויתבטל לאחר שהורץ פעם אחת. דוגמא לכך ניתן לראות ב-HTTP connect event docs.

+ +

דוגמא נוספת למודל אירועים שונים אנחנו יכולים לראות כאשר משתמשים ב-JavaScript על מנת לבנות תוספים לדפדפנים (מעין שיפורים לדפדפנים) - באמצעות טכנולוגיה שנקראת WebExtensions. מודל האירועים שם הוא דומה למודל האירועים של ה-Web, אבל שונה מעט - מאזיני האירועים הם camel-cased - כלומר, onMessage ולא onmessage, והם צריכים להיות ביחד עם פונקצית addListener. לדוגמאות ראו runtime.onMessage page.

+ +

אינכם צריכים להבין עכשיו שום דבר על הסביבות הללו, רק רצינו להסביר לכם שאירועים ומודל האירועים יכול להיות בסביבות פיתוח שונות.

+ +

דרכים לשימוש ב-web events

+ +

יש מספר דרכים שונות שבהם אנחנו יכולים להוסיף מאזין אירוע -event listener לדפי הרשת על מנת שהוא יריץ את ה-event handler כאשר יתרחש האירוע הרלוונטי (event registration). בחלק זה, אנחנו נסקור את הדרכים השונות ונדון באילו מהן אנו צריכים להשתמש.

+ +

דרך I: הוספת תכונה של מטפל אירוע - Event handler properties

+ +

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

+ +
var btn = document.querySelector('button');
+
+btn.onclick = function() {
+  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+}
+ +

התכונה onclick היא תכונת מטפל האירוע (מאזין האירוע) הרלוונטית כרגע לדוגמא זו. היא תכונה בדיוק כמו שיש ל-btn תכונות נוספות שזמינו תעבורו כמו btn.textContent, או btn.style, אבל היא תכונה מסוג מיוחד - כאשר אנחנו משימים בה ערך ששווה לקוד מסויים, הקוד הזה ירוץ בכל פעם שהאירוע יתרחש על הכפתור (או על האלמנט אשר נתנו לו את התכונה הזו).

+ +

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

+ +
var btn = document.querySelector('button');
+
+function bgChange() {
+  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+}
+
+btn.onclick = bgChange;
+ +

יש הרבה סוגים של תכונות מטפלות אירוע שזמינות. ננסה כמה מהם:

+ +

ראשית, שמרו לכם עותק מקומי של random-color-eventhandlerproperty.html, ופיתחו אותו בדפדפן. זהו עותק של הדוגמא הפשוטה של בחירת הצבע שראינו בעבר. עכשיו שנו את ה- btn.onclick לערכים הבאים, כל אחד בתור, וראו מה קורה :

+ + + +

ישנם אירועים שהם מאד כלליים והם זמינים כמעט בכל מקום או עבור כל אלמנט - לדוגמא - אפשר להאזין לאירוע onclick כמעט על כל אלמנט, בעוד יש כאלו שהם יותר ספציפיים ושימושיים בסיטואציות מסויימת. לדוגמא, הגיוני לנו ש-onplay יהיה זמין רק לאלמנטים מסוג מסויים כמו {{htmlelement("video")}}.

+ +

דרך II: לידיעה בלבד - לא להשתמש בהם - Inline event handlers

+ +

יכול להיות שראיתם קוד שנראה כך:

+ +
<button onclick="bgChange()">Press me</button>
+
+ +
function bgChange() {
+  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+}
+ +
+

לתשומת לב: אתם יכולים לראות את קוד המקור לדוגמא זו ב- GitHub או בדף אינטרנט.

+
+ +

בעבר, הדרך לרשום (register) מטפלי אירוע הייתה באמצעות event handler HTML attributes הידועים גם כ- inline event handlers, כמו שרשום בדוגמא למעלה. הערך של אותו attribute הוא ממש קוד JavaScript שאנחנו רוצים שירוץ כאשר האירוע מתרחש. הדוגמא למעלה מפעילה פונקציה שמוגדרת בתוך האלמנט {{htmlelement("script")}} אבל באותה הדרך אנחנו יכולים להכניס פונקציה שלמה לתוך אותו attribute:

+ +
<button onclick="alert('Hello, this is my old-fashioned event handler!');">Press me</button>
+ +

אל תשתמשו בדרך שכזו על מנת לטפל באירוע, זה נחשב כ- bad practice (פרקטיקה שאינה מקובלת בתעשייה). זה אולי נשמע יותר פשוט, אבל מהר מאוד זה הופך למשהו שלא ניתן לעקוב אחריו ולא יעיל.

+ +

בנוסף, זה לא רעיון טוב לערבב בין HTML לבין JavaScript מאחר שזה נהיה קשה לעיבוד - היצמדו לכך שכל ה-JavaScript נמצא במקום אחד.

+ +

אפילו כאשר מדובר בקובץ אחד, inline event handlers הם לא רעיון טוב. כאשר יש כפתור אחד זה עוד סביר, אבל מה אם היו לנו 100 כפתורים? היינו צריכים להוסיף 100 attributes לתוך הקובץ. מהר מאוד זה הופך לסיוט מבחינת תחזוקה של הקוד. עם JavaScript, אנחנו יכולים בקלות להוסיף מטפל אירוע לכל הכפתורים, לא משנה כמה יש כאלו, באמצעות קוד כזה:

+ +
var buttons = document.querySelectorAll('button');
+
+for (var i = 0; i < buttons.length; i++) {
+  buttons[i].onclick = bgChange;
+}
+ +
+

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

+
+ +

דרך addEventListener() : III  ו- ()removeEventListener

+ +

הסוג החדש ביותר של מנגנון אירועים הוגדר ב- Document Object Model (DOM) Level 2 Events של ארגון W3C. מסמך זה הגדיר דרך טובה יותר לנהל אירועים, בין היתר באמצעות אובייקט מיוחד בשם  EvantTarget אשר נוצר בדפדפן כאשר אירוע מתרחש. לאובייקט זה יש שלוש מתודות ואחת מהן היא ()addEventListener. מתודה זו דומה לדרך הראשונה של event handler properties, אבל הסינטקס שונה. אנחנו יכולים לכתוב את הדוגמא שלנו עם הצבעים האקראיים בצורה הזו:

+ +
var btn = document.querySelector('button');
+
+function bgChange() {
+  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+}
+
+btn.addEventListener('click', bgChange);
+ +
+

לתשומת לב:תוכלו למצוא את קוד המקור של דוגמא זו ב- GitHub או ראו כ- דף אינטרנט).

+
+ +

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

+ +
btn.addEventListener('click', function() {
+  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  document.body.style.backgroundColor = rndCol;
+});
+ +

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

+ +
btn.removeEventListener('click', bgChange);
+ +

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

+ +

בנוסף, אנחנו גם יכולים לרשום מספר מטפלי אירוע לאותו אירוע - הקוד הבא לדוגמא לא יכול להחיל שני מטפלי אירוע:

+ +
myElement.onclick = functionA;
+myElement.onclick = functionB;
+ +

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

+ +
myElement.addEventListener('click', functionA);
+myElement.addEventListener('click', functionB);
+ +

במקרה זה, שתי הפונקציות ירוצו כאשר ילחצו על האלמנט.

+ +

כמו כן, יש מספר אפשרויות משמעותיות ותכונות זמינות עבור מנגנון ירועים בדרך הזו. אנחנו לא נרחיב עליהם, אך אם תרצו להרחיב את ידיעתכם בנושא, היכנסו לדפי ההסבר של MDN בנושא ()addEventListener ובנושא ()removeEventListener.

+ +

באיזה מנגנון אירועים להשתמש?

+ +

מתוך שלושת המנגנונים הללו, בוודאות אל תשתמשו במנגנון HTML event handler attributes - זה מנגנון ישן, שלא נמצא כבר בשימוש ונחשב כ- bad practice להשתמש בו.

+ +

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

+ + + +

כמו שאמרנו, היתרון העיקרי של המנגנון השלישי הוא שאתם יכולים להסיר קוד שמטפל באירוע, באמצעות ()removeEventListener, ואתם יכולים להוסיף מספר מאזיני אירוע לאותו אלמנט. לדוגמא, אנחנו יכולים לקרוא ל-({ ... }()addEventListener('click', function על אלמנט מסויים מספר רב של פעמים, כאשר בכל פעם תהיה פונקציה אחרת בארגומנט השני. אופציה זו לא אפשרית ב- event handler properties כי כל הגדרה נוספת של property תמחוק את ההגדרה הקודמת שלו:

+ +
element.onclick = function1;
+element.onclick = function2;
+etc.
+ +
+

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

+
+ +

עקרונות נוספים בנושא אירועים

+ +

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

+ +

Event objects

+ +

לפעמים בתוך פונקצייה המטפלת באירוע (event handler) - אתם תראו פרמטר המצויין בתך הסוגריים, הנושא שם כמו event, evt, או סתם e. זה נקרא event object - האובייקט של האירוע עצמו, והוא מועבר בצורה אוטומטית למטפלי האירוע על מנת לספק אפשרויות נוספות ומידע נוסף. לדוגמא, נרשום את דוגמת הצבעים שלנו מחדש בצורה קצת שונה:

+ +
function bgChange(e) {
+  var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+  e.target.style.backgroundColor = rndCol;
+  console.log(e);
+}
+
+btn.addEventListener('click', bgChange);
+ +
+

לתשומת לב: תוכלו למצוא את קוד המקור ב-GitHub וגם לראות את הדוגמא כדף אינטרנט.

+
+ +

כאן אנחנו יכולים לראות שאנחנו כוללים את האובייקט של האירוע - e, בתוך הפונקציה, ובתוך הפונקציה אנחנו קובעים צבע רקע ל- e.target — שזה בעצם הכפתור עצמו. המאפין target של event object הוא תמיד הפנייה לאלמנט שהאירוע התרחש עליו. כך, בדוגמא שלנו, אנחנו קובעים בעצם צבע רקע אקראי לכפתור עצמו שהאירוע הלחיצה התרחש עליו ולא לדף.

+ +
+

לתשומת לב: אתם יכולים להשתמש באיזה שם שנרצה עבור event object — רק השתמשו בשם שיהיה ברור שזה הפניה ל- event object. השמות המקובלים הם e/evt/event מכיוון שהם קצרים וקל לזכור את ההקשר שלהם.

+
+ +

e.target הוא שימושי להפליא כשאנחנו רוצים לקבוע את אותו event handler על מספר אלמנטים ולעשות משהו לכולם כאשר אותו אירוע מתרחש. לדוגמא, נניח ויש לנו סט של 16 אריחים שנעלמים כאשר הם נלחצים. זה נוח יותר כאשר מתאפשר לנו לקבוע שאלמנט יעלם כשאנחנו נלחץ עליו באמצעות שימוש ב- e.target , מאשר לבחור אותו בצורה מורכבת אחרת. בדוגמאות הבאות למשל ב-useful-eventtarget.html - קוד המקור (ניתן לראות גם ב-דף האינטרנט) יצרנו 16 אלמנטים מסוג {{htmlelement("div")}} באמצעות JavaScript, ואנחנו בוחרים את כולם באמצעות {{domxref("document.querySelectorAll()")}} ואז עוברים על כל אחד מהם באמצעות לולאה ומוסיפים מאזין אירוע ומטפל אירוע של onclick לכל אחד מהם כך שכאשר כל אחד מהאלמנטים הללו נלחץ על ידי המשתמש, צבע אקראי אחר ניתן לאותו אלמנט:

+ +
var divs = document.querySelectorAll('div');
+
+for (var i = 0; i < divs.length; i++) {
+  divs[i].onclick = function(e) {
+    e.target.style.backgroundColor = bgChange();
+  }
+}
+ +

הפלט נראה כך. נסו לשחק איתו:

+ + + +

{{ EmbedLiveSample('Hidden_example', '100%', 400, "", "", "hide-codepen-jsfiddle") }}

+ +

הרבה ממאזיני האירועים/מטפלי האירועים שניתקל בהם הם בעלי סט סטנדרטי של properties ופונקציות - או יותר נכון מתודות, אשר זמינים עבור ה-event object - ראו את הדף בנושא אובייקט {{domxref("Event")}} לרשימה המלאה.

+ +

יש מטפלי אירועים יותר מורכבים, המכילים properties מיוחדים בעלי מידע ספציפי שהם צריכים על מנת לתפקד כמטפל אירוע. לדוגמא ל-Media Recorder API, יש סוג אירוע - dataavailable - שמתרחש כאשר אודיו או וידאו הוקלטו והם זמינים כך שניתן לבצע עליהם פעולות מסויימות - לדוגמא לשמור אותם או לנגן אותם שוב. למאזין האירוע/מטפל אירוע התואם ondataavailable יש property שזמין בשם data עבורו המכיל את האודיו/וידאו שהוקלט ומאפשר לנו לגשת אליו ולעשות איתו דברים.

+ +

מניעת התנהגות ברירת מחדל

+ +

לפעמים אנחנו ניתקל בסיטואצית שאנחנו נרצה למנוע מאירוע לבצע את מה שהוא אמור לעשות כברירת מחדל. הדוגמא הכי נפוצה היא טופס באינטרנט. כאשר אנחנו נמלא את הפרטים ונלחץ על כפתור ה-Submit , ההתנהגות ברירת המחדל תהיה לשלוח את המידע שהוכנס בטופס לדף מסויים בשרת לשם עיבוד, והדפדפן יועבר למעין דף של ״הפרטים נשלחו בהצלחה״ או משהו דומה.

+ +

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

+ +

נתחיל עם טופס HTML פשוט דורש מאיתנו להכניס שם פרטי ושם משפחה:

+ +
<form>
+  <div>
+    <label for="fname">First name: </label>
+    <input id="fname" type="text">
+  </div>
+  <div>
+    <label for="lname">Last name: </label>
+    <input id="lname" type="text">
+  </div>
+  <div>
+     <input id="submit" type="submit">
+  </div>
+</form>
+<p></p>
+ + + +

כעת קצת JavaScript - כאן החלנו בדיקה פשוטה מאוד בתוך מטפל האירוע onsubmit (האירוע של submit מתרחש כאשר הטופס נשלח).

+ +

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

+ +
var form = document.querySelector('form');
+var fname = document.getElementById('fname');
+var lname = document.getElementById('lname');
+var submit = document.getElementById('submit');
+var para = document.querySelector('p');
+
+form.onsubmit = function(e) {
+  if (fname.value === '' || lname.value === '') {
+    e.preventDefault();
+    para.textContent = 'You need to fill in both names!';
+  }
+}
+ +

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

+ +

{{ EmbedLiveSample('Preventing_default_behavior', '100%', 140, "", "", "hide-codepen-jsfiddle") }}

+ +
+

לתשומת לב: ראו את קוד המקור פה preventdefault-validation.html או דף אינטרנט.

+
+ +

event bubbling ו- capture

+ +

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

+ +

event bubbling ו- capture אלו שני מנגנונים אשר מסבירים מה קורה כאשר שנים או יותר מטפלי אירוע של אותו אירוע מופעלים על אלמנט אחד. לצורך ההסבר, פתחו את show-video-box.html בלשונית חדשה בדפדפן ואת קוד המקור בלשונית אחרת. ניתן גם לראות את הדוגמא כאן למטה:

+ + + +

{{ EmbedLiveSample('Hidden_video_example', '100%', 500, "", "", "hide-codepen-jsfiddle") }}

+ +

זו דוגמא פשוטה שמראה ומסתירה אלמנט {{htmlelement("div")}} שמכיל אלמנט {{htmlelement("video")}} בתוכו:

+ +
<button>Display video</button>
+
+<div class="hidden">
+  <video>
+    <source src="rabbit320.mp4" type="video/mp4">
+    <source src="rabbit320.webm" type="video/webm">
+    <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p>
+  </video>
+</div>
+ +

כאשר אנחנו לוחצים על {{htmlelement("button")}} הוידאו מוצג, באמצעות שינוי ה-class של <div> מ- hidden ל- showing (ה-css בקובץ מכיל בין היתר שני classes אשר מציגים את הקופסא במסך או מסתירים אותה, בהתאמה) :

+ +
btn.onclick = function() {
+  videoBox.setAttribute('class', 'showing');
+}
+ +

לאחר מכן אנחנו מוסיפים עוד שני מטפלי אירוע של onclick - הראשון ל- <div> והשני ל - <video>. הרעיון הוא שכאשר האזור של ה- <div> מחוץ לוידאו מקבל לחיצה, הקופסא אמורה להיעלם שוב; כאשר הוידאו עצמו נלחץ, הוידאו אמור לפעול שוב:

+ +
videoBox.onclick = function() {
+  videoBox.setAttribute('class', 'hidden');
+};
+
+video.onclick = function() {
+  video.play();
+};
+ +

אבל ישנה בעי כרגע, כאשר אנחנו לוחצים על הוידאו הוא מתחיל להתנגן, אבל גורם גם ל- <div> להיות מוסתר באותו הזמן. זה מכיוון שהוידאו שבתוך ה-<div> - הוא חלק ממנו - אז כאשר אנחנו לוחצים על הוידאו - אנחנו בעצם גם מפעילים את האירוע על ה-<div> עצמו, ושני מטפלי האירוע נכנסים לפעולה.

+ +

bubbling ו- capturing

+ +

כאשר אירוע מתרחש על אלמנט שיש לו אלמנט אב - לדוגמא האלמנט {{htmlelement("video")}} שלנו, לדפדפנים המודרניים יש שני תהליכים שונים שהם מבצעים: שלב ה- capturing ושלב ה- bubbling.

+ +

בשלב - capturing:

+ + + +

בשלב - bubbling קורה בדיוק ההפך:

+ + + +

+ +

לחצו על התמונה על מנת להגדיל אותה.

+ +

בדפדפנים מודרניים, ברירת המחדל היא שכל ה-event handlers נרשמים בשלב ה-bubbling. בדוגמא שלנו למשל, כאשר לחצנו על הוידאו, האירוע מסוג לחיצה ״בועבע״ מאלמנט <video> הלאה לאלמנט <html>, כאשר במהלך הדרך :

+ + + +

שימו לב שמה שבועבע הוא התרחשות האירוע עצמו, ולא מטפל האירוע (אותו דבר קורה גם בשלב ה-capturing). 

+ +

תיקון הבעיה עם ()stopPropagation

+ +

על מנת לתקן את ההתנהגות הזו, לאובייקט האירוע עצמו - event object - יש מתודה זמינה עבורו שנקראת ()stopPropagation, כאשר היא מופעלת על מטפל האירוע של אובייקט האירוע, היא תריץ את מטפל האירוע, אבל תמנע מהאירוע עצמו להמשיך לבעבע במעלה השרשרת לאלמנטי האב שלו (וכנ״ל גם בשלב ה- capturing) וכך מטפלי אותו אירוע של אלמנטי האב לא ירוצו.

+ +

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

+ +
video.onclick = function(e) {
+  e.stopPropagation();
+  video.play();
+};
+ +

אתם יכולים ליצור עותק מקומי של קוד המקור של show-video-box.html ולתקן זאת בעצמכם או לראות הקובץ המתוקן כאן ואת קוד המקור כאן.

+ +
+

הערה חשובה: אתם בטח שואלים את עצמכם מדוע לטרוח וליצור שני שלבים  - גם capturing וגם bubbling? התשובה נעוצה בהיסטוריה ובימי העבר כאשר התאימות בין דפדפנים הייתה שונה מאוד ולא כפי שהיא היום.

+ +

בימים ההם Netscape השתמש ב-event capturing בלבד ואילו Internet Explorer השתמש ב - event bubbling בלבד. כאשר ארגון W3C החליט לנסות וליצור סטדרט אחיד, הם החליטו על מנגנון שיכלול את שני השלבים - וכל הדפדפנים אימצו את שני השלבים.

+
+ +
+

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

+
+ +

Event delegation

+ +

bubbling מאפשר לנו להשתמש ביתרונות של event delegation — רעיון זה מתבסס על העובדה שאם אנחנו רוצים להריץ קוד מסויים כאשר אנחנו לוחצים על אלמנט ילד אחד שהוא חלק ממספר אלמנטים ילדים של אלמנט אב, אנחנו יכולים לקבוע את מאזין האירוע על אלמנט האב, ואז כאשר האירוע מתרחש על אחד מאלמנטים הילדים, האירוע ״יבועבע״ לאלמנט ההורה שלהם.

+ +

כתיבה שכזו עדיפה על רישום מאזין אירוע לכל אחד מהילדים בנפרד. להזכירכם - בשלב ה-bubbling נבדק האם האלמנט שהאירוע התרחש עליו מכיל מטפל אירוע לאירוע שהתרחש ומתקדם הלאה לאלמנט ההורה ומבעבע אליו את האירוע ובודק האם הוא מכיל מטפל אירוע לאירוע שהתרחש וכך הלאה.

+ +

דוגמא טובה לכך היא רשימה של פריטים - אם אנחנו רוצים שכל פריט מהרשימה יקפיץ הודעה כאשר לוחצים עליו, אנחנו יכולים לקבוע מאזין אירוע על האלמנט ההורה - במקרה שלנו <ul>, וכל לחיצה על פריט מהרשימה (<li>) -  כלומר כל התרחשות אירוע שכזה על פריט מהרשימה - אירוע הלחיצה יבעבע מאלמנט <li> לאלמנט האב - <ul>.

+ +

רעיון זה מוסבר בפירוט רב בבלוג של David Walsh עם דוגמאות נוספות. ראו את המאמר שלו בנושא How JavaScript Event Delegation Works.

+ +

לסיכום

+ +

במאמר זה ניסינו להסביר כל מה שאתם צריכים לדעת על אירועי Web בשלב זה. כפי שנאמר למעלה, אירועים הם לא חלק מה-core של JavaScript - הם מוגדרים ב-Web APIs של הדפדפן.

+ +

חשוב להבין בנוסף שיש הבדלים בין מודלי האירועים של JavaScript בסביסות השונות שהיא מורצת - החל מ- Web APIs ועד לסביבות אחרות כמו Browser WebExtensions ו- Node.js. לא מצפים מכם שכרגע תבינו את כל הסביבות הללו, אבל זה עוזר לכם להבין את הבסיס ככל ותתקדמו בלמידה.

+ +

אם משהו לא ברור, הרגישו חופשי לקרוא שוב את המאמר או ליצור עמנו קשר.

+ +

See also

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Return_values","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}}

+ +

במודול זה

+ + diff --git a/files/he/learn/javascript/building_blocks/functions/index.html b/files/he/learn/javascript/building_blocks/functions/index.html new file mode 100644 index 0000000000..99255d0591 --- /dev/null +++ b/files/he/learn/javascript/building_blocks/functions/index.html @@ -0,0 +1,386 @@ +--- +title: Functions — פונקציות - חלקי קוד לשימוש חוזר +slug: Learn/JavaScript/Building_blocks/Functions +translation_of: Learn/JavaScript/Building_blocks/Functions +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Looping_code","Learn/JavaScript/Building_blocks/Build_your_own_function", "Learn/JavaScript/Building_blocks")}}
+ +

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

+ + + + + + + + + + + + +
ידע מוקדם:הכרות בסיסית עם המחשב ועם הבסיס של HTML ו- CSS, וכן סיום במלאו של מודול צעדים ראשונים ב-JavaScript.
מטרה:הבנה של עקרונות היסוד בנושא פונקציות ב-JavaScript.
+ +

איפה נמצא פונקציות?

+ +

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

+ +

כמעט כל פעם שאנחנו עושים שימוש בביטוי מסויים של JavaScript שעושה שימוש בסוגריים רגילות () וזה לא במסגרת לולאת for או לולאות while ו- do...while loop או משפטי תנאי if...else אנחנו בעצם עושים שימוש בפונקציות.

+ +

פונקציות מובנות (Built-in) של הדפדפן

+ +

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

+ +
let myText = 'I am a string';
+let newString = myText.replace('string', 'sausage');
+console.log(newString);
+// the replace() string function takes a source string,
+// and a target string and replaces the source string,
+// with the target string, and returns the newly formed string
+ +

או בכל פעם שעשינו מניפולציה על מערך:

+ +
let myArray = ['I', 'love', 'chocolate', 'frogs'];
+let madeAString = myArray.join(' ');
+console.log(madeAString);
+// the join() function takes an array, joins
+// all the array items together into a single
+// string, and returns this new string
+ +

או בכל פעם שרצינו ליצור מספר רנדומלי:

+ +
let myNumber = Math.random();
+// the random() function generates a random number between
+// 0 and up to but not including 1, and returns that number
+ +

אנחנו בעצם השתמשנו בפונקציות.

+ +
+

תשומת לבכם: נסו להכניס את השורות קוד הרשומות למעלה לקונסולה אם אתם לא זוכרים איך לעשות בהם שימוש.

+
+ +

ל- JavaScript יש לא מעט פונקציות מובנות אשר מאפשרות לנו לעשות דברים שימושיים מבלי לכתוב את כל הקוד בעצמנו. בפועל, חלק מהקוד שאנחנו מריצים כאשר אנחנו אנחנו קוראים לפונקציה מובנית של הדפדפן, לא יכל היה להירשם ב-JavaScript - הרבה מהפונקציות הללו קוראות לחלקים בקוד הדפדפן עצמו, אשר נבנה בשפה אחרת שאינה JavaScript כלל.

+ +

אנא זכרו שחלק מהפונקציות המובנות של הדפדפם אינן חלק מהבסיס של שפת JavaScript - חלקן מהן מוגדרות כחלק מה-API של הדפדפן, אשר בנוי מעל שפת הכתיבה של הדפדפן על מנת להעניק יותר פונקציונליות. אנחנו נסתכל על ה-API של הדפדפן בהמשך המודול. לרענון זכרונכם, ראו מאמר זה מתחילת הקורס.

+ +

functions vs. methods  - פונקציות מול מתודות

+ +

אנו קוראים לפונקציות שהן חלק מאובייקטים כ-מתודות (methods). אנחנו לא צריכים כרגע לדעת על המבנה הפנימי של אובייקטים ב-JavaScript - אנו נלמד את זה לעומק במודול הבא. לבינתיים, רק רצינו למנוע בלבול בין המושגים השונים. רוב הסיכויים שתשמעו את שניהם.

+ +

הקוד המובנה שעשינו בו שימוש לבינתיים מגיע ב-2 תצורות: פונקציות ו-מתודות. אתם יכולים לבדוק את הרשימה המלאה של פונקציות מובנות וכן את הרשימה המלאה של אובייקטים מובנים והמתודות שלהם פה.

+ +

כמו כן, ראינו הרבה פונקציות מותאמות -custom functions - פונקציות שאנחנו הגדרנו בעצמנו ולא מוגדרות בתוך הדפדפן עצמו. בכל פעם שאנחנו רואים שם שאינו שם שמור של השפה ולאחריו סוגריים רגילות (), זוהי פונקציה שהמפתח הגדיר בעצמו. בתרגול שלנו random-canvas-circles.html וגם בקוד המקור שלו במאמר בנושא לולאות, כללנו פונקציה ()draw שאנחנו בנינו שנראית כך :

+ +
function draw() {
+  ctx.clearRect(0,0,WIDTH,HEIGHT);
+  for (let i = 0; i < 100; i++) {
+    ctx.beginPath();
+    ctx.fillStyle = 'rgba(255,0,0,0.5)';
+    ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
+    ctx.fill();
+  }
+}
+ +

פונקציה זו מציירת 100 עיגולים אקראיים בתוך אלמנט {{htmlelement("canvas")}} . בכל פעם שאנחנו רוצים לעשות זאת, אנחנו יכולים להפעיל את הפונקציה עם הקוד הבא:

+ +
draw();
+
+ +

במקום לכתוב את כל הקוד שבתוך הפונקציה בכל פעם שאנחנו רוצים שיצוייר עיגול. 

+ +

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

+ +
function random(number) {
+  return Math.floor(Math.random()*number);
+}
+ +

אנחנו צריכים לבנות את הפונקציה ()random כי הפונקציה המובנית של הדפדפן ()Math.random מייצרת לנו מספר רנדומלי, אבל מספר רנדומלי עשרוני בין 0 ל-1. אנחנו לעומת זאת רצינו מספר רנדומלי שלם ולא עשרוני ושיהיה בין 0 למספר מסויים שאנחנו נגדיר לו.

+ +

Invoking functions - קריאה לפונקציה

+ +

ככל הנראה אתם כבר מבינים את הנושא, אבל בכל מקרה אנו מזכירים שכדי להשתמש בפועל בפונקציה אחרי שהיא הוגדרה, אנחנו צריכים להריץ אותה, לקרוא לה. בשפה האנגלית זה נקרא To invoke. זה נעשה באמצעות כתיבת שם הפונקציה איפה שנרצה בתוך הקוד שלנו, ולאחריו סוגריים מסולסלות ().

+ +
function myFunction() {
+  alert('hello');
+}
+
+myFunction()
+// calls the function once
+ +

Anonymous functions - פונקציות אנונימיות

+ +

אולי נתקלתם בפונקציות אשר מוגדרות ומופעלות בצורות אחרות. עד עכשיו, יצרנו פונקציה בצורה כזו:

+ +
function myFunction() {
+  alert('hello');
+}
+ +

אבל אנחנו גם יכולים ליצור פונקציה שאין לה שם:

+ +
function() {
+  alert('hello');
+}
+ +

פונקציה שכזו נקראת פונקציה אנונימית - anonymous function - אין לה שם. היא גם לא עושה כלום בעצמה. בדרך כלל אנחנו נשתמש בפונקציה אנונימית ביחד עם ״מטפל אירוע״ - event handler. לדוגמא, הקוד הבא יריץ את הקוד בנמצא בתוך הפונקציה, כאשר הכפתור myButton נלחץ:

+ +
var myButton = document.querySelector('button');
+
+myButton.onclick = function() {
+  alert('hello');
+}
+ +

הדוגמא למעלה דורשת שיהיה אלמנט {{htmlelement("button")}} זמין על גבי הדף כדי שנוכל לבחור אותו וללחוץ עליו. ראיתם מבנה שכזה מספר פעמים במהלך הקורס ואתם תלמדו עליו עוד בהמשך הקורס.

+ +

אנחנו יכולים להשים פונקציה אנונימית לתוך משתנה כך שהיא תהיה הערך של אותו משתנה. לדוגמא:

+ +
let myGreeting = function() {
+  alert('hello');
+}
+ +

ניתן להפעיל את הפונקציה הזו (invoke) באמצעות:

+ +
myGreeting();
+ +

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

+ +
let anotherGreeting = myGreeting;
+ +

הפונקציה הזו יכולה להיות מופעלת בשתי הדרכים:

+ +
myGreeting();
+anotherGreeting();
+ +

אבל זה עלול להיות מבלבל, אז אל תעשו זאת. כשאנחנו יוצרים פונקציות, עדיף יהיה להיצמד למבנה הזה:

+ +
function myGreeting() {
+  alert('hello');
+}
+ +

אנחנו נשתמש בפונקציות אנונימיות בעיקר על מנת להריץ קוד בתגובה לאירוע שהתרחש - כמו לחיצה על כפתור - וזאת באמצעות ״מטפל אירוע״ - event handler. לדוגמא:

+ +
myButton.onclick = function() {
+  alert('hello');
+  // I can put as much code
+  // inside here as I want
+}
+ +

הפרמטרים של הפונקציה

+ +

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

+ +
+

לתשומת לב: פרמטרים אלו נקראים ארגומנטים

+
+ +

כדוגמא, הפונקציה המובנית של הדפדפן לא דורשת שום פרמטרים. כשאנחנו קוראים לה, היא מחזירה מספר עשרוני בין 0 ל-1. ()Math.random:

+ +
let myNumber = Math.random();
+ +

הפונקציה המובנית של הדפדפן ()replace לעומת זאת, צריכה שני ארגומנטים - מחרוזת משנה שנרצה לחפש בתוך מחרוזת ראשית ואת המחרוזת המשנה שתחליף את זו שמצאנו בתוך המחרוזת הראשית:

+ +
let myText = 'I am a string';
+let newString = myText.replace('string', 'sausage');
+ +
+

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

+
+ +

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

+ +
let myArray = ['I', 'love', 'chocolate', 'frogs'];
+let madeAString = myArray.join(' ');
+// returns 'I love chocolate frogs'
+let madeAString = myArray.join();
+// returns 'I,love,chocolate,frogs'
+ +

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

+ +

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

+ +

בוא נדבר מעט על {{glossary("scope")}} - עקרון חשוב מאוד להבנה כאשר אנחנו עוסקים בפונקציות. כאשר אנחנו יוצרים פונקציה, המשתנים וכל הדברים האחרים המוגדרים בתוך הפונקציה נמצאים בתוך scope נפרד, כלומר, הם נעולים בתוך מתחם מסויים, שלא ניתן לגשת אליו מחוץ לפונקציה.

+ +

הסקופ או התחום שנמצא מחוץ לכל הפונקציות שלנו נקרא global scope. ערכים שמוגדרים ב-global scope נגישים מכל מקום בקוד.

+ +

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

+ +

לדוגמא, נניח ויש לנו קובץ HTML אשר קורא לשני קבצי JavaScript חיצוניים, ובשניהם יש משתנה ופונקציה מוגדרים שמשתמשים באותו שם:

+ +
<!-- Excerpt from my HTML -->
+<script src="first.js"></script>
+<script src="second.js"></script>
+<script>
+  greeting();
+</script>
+ +
// first.js
+var name = 'Chris';
+function greeting() {
+  alert('Hello ' + name + ': welcome to our company.');
+}
+ +
// second.js
+var name = 'Zaptec';
+function greeting() {
+  alert('Our company is called ' + name + '.');
+}
+ +

שתי הפונקציות שאנחנו רוצים לקרוא להם נקראות ()greeting, אבל אנחנו יכולים לגשת רק לפונקציה ()greeting שבקובץ second.js - שכן הקישור לקובץ מבוצע ב -HTML מאוחר יותר בקוד שלנו, ולכן המשתנים והפונקציה שלו דורסים את אלו שב- first.js.

+ +
+

לתשומת לב: ניתן לראות את הדוגמא ב-GitHub וכן את קוד המקור).

+
+ +

שמירה על הקוד שלנו נעול בתוך סקופ מונע בעיות שכאלו ונחשב כ- best practice.

+ +

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

+ +

+ +

למידה אקטיבית: לשחק עם ה-scope

+ +

נסתכל על דוגמא על מנת להבין מהו scope.

+ +
    +
  1. ראשית, צרו לעצמכם עותק של הדוגמא שלנו function-scope.html. הקובץ מכיל 2 פונקציות שנקראות ()a ו- ()b וכן שלושה משתנים - x, y, ו- z - שניים מתוכם מוגדרים בתוך פונקציות ואחד מתוכם מוגדר ב-global scope. בנוסף, הדוגמא גם מכילה פונקציה שלישית שנקראת ()output, אשר מקבלת ארגומנט אחד ומציגה אותו בתוך פסקה על גבי הדף.
  2. +
  3. פתחו את הדוגמא בדפדפן ובעורך הקוד שלכם.
  4. +
  5. הקלידו בקונסולה את הקוד הבא: +
    output(x);
    + אתם אמורים לראות שהערך של המשתנה x הוצג למסך.
  6. +
  7. כעת נסו להזין את הקוד הבא לקונסולה: +
    output(y);
    +output(z);
    + שתי הפקודות הללו יחזירו לנו שגיאה ביחד עם המשפט: "ReferenceError: y is not defined". מדוע? הסיבה נעוצה ב-scope של הפונקציות: - y ו- z נעולים בתוך הפונקציות ()a ו- ()b ולכן הפונקציה ()output לא יכולה לגשת אליהם כשהיא נקראת מה-global scope.
  8. +
  9. עם זאת, מה לדעתכם יקרה כשנקרא לפונקציה ()output מתוך הפונקציות? נסו לשנות את ()a ו- ()b שייראו כך: +
    function a() {
    +  let y = 2;
    +  output(y);
    +}
    +
    +function b() {
    +  let z = 3;
    +  output(z);
    +}
    + שמרו את הקוד ואז העלו מחדש את הדף בדפדפן ונסו לקרוא לפונקציות ()a ו- ()b מהקונסולה: + +
    a();
    +b();
    + אתם אמורים לראות את הערכים של y ו- z על גבי הדף. זה עובד מכיוון שהפונקציה ()output מופעלת מתוך פונקציה אחרת - כלומר מתוך אותו סקופ שבו מוגדרים המשתנים שהיא מדפיסה. הפונקציה ()output עצמה זמיני מכל מקום, שכן היא מוגדרת ב-global scope.
  10. +
  11. נסו עכשיו לעדכן את הקוד שלכם כך: +
    function a() {
    +  var y = 2;
    +  output(x);
    +}
    +
    +function b() {
    +  var z = 3;
    +  output(x);
    +}
    + רענון והעלו את הדף שוב והזינו את הקוד הבא בקונסולה:
  12. +
  13. +
    a();
    +b();
    + גם a() וגם b() מחזירים את הערך של x — 1. זה עובד מכיוון שלמרות ש-()output לא מוגדרת באותו סקופ ש- x מוגדר בו, אבל x הוא משתנה גלובלי אז הוא זמין בכל מקום בקוד.
  14. +
  15. לבסוף, עדכנו את הקוד כך: +
    function a() {
    +  var y = 2;
    +  output(z);
    +}
    +
    +function b() {
    +  var z = 3;
    +  output(y);
    +}
    + שמור ורענן את הדף. לאחר מכן הזן את הקוד הבא בקונסולה:
  16. +
  17. +
    a();
    +b();
    + הפעם כשקראנו ל- ()a ו- ()b אנחנו נקבל שגיאה מסוג "ReferenceError: z is not defined" זה מכיוון שביצוע הקוד ()output והמשתנים שהם מנסים להשיג לא מוגדרים בתוך אותו סקופ של פונקציה - המשתנים בעיקרון בלתי נראים לקריאות הפונציה הזו.
  18. +
+ +
+

לתשומת לבכם: אותו מנגנון סקופינג לא חל על לולאות { ... }(...) for ובלוקים של תנאים - { ... }(...) if הם אמנם נראים דומים, אבל הם לא אותו דבר. אל תתבלבלו.

+
+ +
+

לתשומת לבכם: השגיאה ReferenceError: "x" is not defined היא אחת מהשגיאות השכיחות שתיתקלו בה. אם קיבלתם שגיאה שכזו, וודאו שהגדרת את המשתנה הרלוונטי ובסקופ הרלוונטי.

+
+ + + +

פונקציות בתוך פונקציות

+ +

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

+ +
function myBigFunction() {
+  var myValue;
+
+  subFunction1();
+  subFunction2();
+  subFunction3();
+}
+
+function subFunction1() {
+  console.log(myValue);
+}
+
+function subFunction2() {
+  console.log(myValue);
+}
+
+function subFunction3() {
+  console.log(myValue);
+}
+
+ +

חשוב לוודא שהערכים שמבוצע בהם שימוש בתוך הפונקציה, מוגדרים בסקופ הנכון. הדוגמא למעלה תחזיר לנו שגיאה ReferenceError: myValue is not defined מכיוון שאמנם המשתנה myValue מוגדר באותו סקופ שהפונקציה נקראת, אך הוא לא מוגדר בתוך הפונקציות עצמן - בתוך הקוד שירוץ בפועל כשאנחנו קוראים לתתי פונקציות. על מנת לגרום לכך לעבוד, היינו צריכים להעביר אליהם את הפונקציה כפרמטר כמו שרשום בקוד מטה:

+ +
function myBigFunction() {
+  var myValue = 1;
+
+  subFunction1(myValue);
+  subFunction2(myValue);
+  subFunction3(myValue);
+}
+
+function subFunction1(value) {
+  console.log(value);
+}
+
+function subFunction2(value) {
+  console.log(value);
+}
+
+function subFunction3(value) {
+  console.log(value);
+}
+ +

לסיכום

+ +

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

+ +

ראו גם

+ + + + + +

{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Looping_code","Learn/JavaScript/Building_blocks/Build_your_own_function", "Learn/JavaScript/Building_blocks")}}

+ +

במודול זה

+ + diff --git a/files/he/learn/javascript/building_blocks/index.html b/files/he/learn/javascript/building_blocks/index.html new file mode 100644 index 0000000000..e60d618b4e --- /dev/null +++ b/files/he/learn/javascript/building_blocks/index.html @@ -0,0 +1,51 @@ +--- +title: אבני הבנין של JavaScript +slug: Learn/JavaScript/Building_blocks +tags: + - JavaScript + - events + - אירועים + - לולאות + - מדריך + - ערכים מוחזרים מפונקציה + - פונקציות + - תנאים - Conditionals +translation_of: Learn/JavaScript/Building_blocks +--- +
{{LearnSidebar}}
+ +

במודול זה, אנחנו נמשיך להעמיק ביסודות ובמאפיינים והחשובים של JavaScript ונתמקד בסוגים שונים של קוד כגון משפטי תנאי (conditional statements),לולאות (loops), פונקציות (functions), ואירועים (events). חלק מהם כבר ראינו בשלבים קודמים של הקורס, אך לא העמקנו בהם. במודול זה ניכנס לעומק של אותן אבני בניין ונבין כיצד הן עובדות ומה מטרתן.

+ +

ידע מוקדם

+ +

לפני שתתחילו את המודול הזה, אנא וודאו כי הנכם בקיאים ביסודות HTML ושל CSS, וכן סיימתם לעבור על המודול הקודם שלנו צעדים ראשונים ב-JavaScript.

+ +
+

הערה: אם אתם עובדים על מחשב\טבלט\מכשיר אחר שאין לכם אפשרות ליצור עליו קבצים אישיים, אתם יכולים לנסות את (רוב) דוגמאות הקוד על תוכנות קוד אינטרנטיות כמו JSBin או Thimble.

+
+ +

מדריכים

+ +
+
קבלת החלטות בקוד - משפטי תנאי - Conditionals
+
כמו בכל שפת תכנות, קוד צריך לקבל החלטות ולבצע פעולות מסויימות בהתאם למקרים שונים. לדוגמא - במשחק, אם מספר הנסיונות המותרים של השחקן עבר את מספר הנסיונות המקסימלי שהוגדר, המשמעות היא שהמשחק הסתיים. או יישום אינטרנט של מזג אוויר אשר יציג למשתמש עיצוב מסויים של מזג האוויר בהתאם לשעה הנוכחית ביום, כך שבשעות היום יוצג עיצוב בהיר ובשעות הערב יוצג עיצוב כהה. במאמר זה אנחנו נחקור את המבנה של משפטי תנאי ב-JavaScript וכיצד הם עובדים.
+
לולאות - Loops
+
לפעמים אנחנו נצטרך לבצע את אותה פעולה או משימה ברצף, יותר מפעם אחת. לדוגמא -  כשנרצה לעבור רשימת שמות. בתכנות, לולאות יכולות לעשות את העבודה הזו בצורה מצויינת. במאמר זה אנחנו נחקור את המבנה של לולאות ב- JavaScript וכיצד הן עובדות.
+
פונקציות - בלוקי קוד לשימוש חוזר - Functions
+
קונספט הכרחי חשוב בתכנות הוא פונקציות. פונקציות מאפשרות לנו לאחסן חלקי קוד שמבצעים פעולה מסויימת בתוך בלוק מוגדר, ואז לקרוא לאותו קוד כשנצטרך להשתמש בו, באמצעות פקודה קצרה - וזאת במקום לרשום את אותו קוד פעם אחר פעם, כל פעם מחדש. במאמר זה נחקור את המבנה של פונקציה והרעיון העומד מאחוריה, ונבין מה הוא הסינטקס הבסיסי על מנת לרשום פונקציה, כיצד אנו קוראים לפונקציה ועוד. כמו כן, נלמד מהם ארגומנטים או פרמטרים אשר הפונקציות יכולות לקבל וכן מהו Scope.
+
בניית פונקציות משלנו
+
לאחר שנסיים לעבור על התיאוריה ונבין מהן פונקציות, במאמר זה נתרגל ונבין בצורה מעשית כיצד לבנות פונקציות משלנו, בהתאם לפעולת שנרצה לבצע. בהמשך הדרך, אנחנו נסביר גם פרטים שימושיים כיצד לטפל בפונקציות ובערכים שהן יכולות להחזיר לנו. 
+
ערכים מוחזרים מהפונקציה - Function return values
+
עקרון הכרחי וחשוב שאנחנו צריכים להכיר לגבי פונקציות הוא אילו ערכים פונקציות מחזירות לנו, אם בכלל. ישנן פונקציות שלא מחזירות ערכים לאחר שסיימו להריץ את הקוד שבתוכן, וישנן פונקציות שיחזירו לנו ערכים מסויימים. במאמר זה אנחנו נבין מהם אותם ערכים מוחזרים, כיצד אנחנו יכולים להשתמש בהם וכיצד אנחנו יכולים לגרום לפונקציות שלנו להחזיר ערכים. 
+
היכרות ראשונית עם אירועים -Introduction to events
+
אירועים אלו בעצם פעולות או התרחשויות אשר קורים במערכת, אשר אנחנו יכולים ״להאזין״ להם כך שנוכל להגיב בדרך מסויימת, ברגע שהם יתרחשו. לדוגמא, כאשר משתמש לוחץ על כפתור, אולי נרצה להגיב לאותה התרחשות, לאותו אירוע של לחיצת הכפתור על ידי הקפצת הודעה מסויימת. במאמר אחרון זה אנחנו נדון בכמה מהעקרונות החשובים בהקשר של אירועים, ונסתכל כיצד הם עובדים בדפדפנים.
+
+ +

תרגול

+ +

התרגול הבא יבדוק את ההבנה שלכם של החומר שנלמד במודול זה

+ +
+
בניית גלריית תמונות
+
אנו נתרגל שימוש בלולאות ופונקציות וכן בתנאים ואירועים על ידי בנייה של גלריית תמונות.
+
diff --git a/files/he/learn/javascript/building_blocks/looping_code/index.html b/files/he/learn/javascript/building_blocks/looping_code/index.html new file mode 100644 index 0000000000..b9067199e7 --- /dev/null +++ b/files/he/learn/javascript/building_blocks/looping_code/index.html @@ -0,0 +1,931 @@ +--- +title: לולאות +slug: Learn/JavaScript/Building_blocks/Looping_code +translation_of: Learn/JavaScript/Building_blocks/Looping_code +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Building_blocks/conditionals","Learn/JavaScript/Building_blocks/Functions", "Learn/JavaScript/Building_blocks")}}
+ +

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

+ + + + + + + + + + + + +
ידע מוקדם:הכרות בסיסית עם המחשב ועם הבסיס של HTML ו- CSS, וכן סיום במלאו של מודול צעדים ראשונים ב-JavaScript.
מטרה:להבין כיצד להשתמש בלולאות ב-JavaScript ומתי.
+ +

מה הן לולאות?

+ +

לולאו הן עקרון חשוב מאוד בתכנות. לולאות קוד מכילות פעולות שנרצה לבצע שוב ושוב - ובשפה מקצועית - איטראציה - Iteration.

+ +

יש הרבה סוגי לולאות - אבל כולן עושות בעיקרון את אותו דבר: הן חוזרות על פעולה מסויימת מספר פעמים (ואף יכול להיות גם 0 פעמים).

+ +

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

+ +


+

+ +

ללולאה יהיו בדרך כלל אחד או יותר (לא בהכרח את כולם) מהמאפיינים הבאים:

+ + + +

למה צריך לולאות?

+ +

בשלב זה כנראה הבנו את הרעיון העומד מאחורי לולאות. כעת ננסה להבין כיצד זה עוזר לנו לבצע פעולות מסויימות שוב ושוב. 

+ +

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

+ +

נסתכל על דוגמא נוספת על מנת להסביר את הנושא. נניח שאנחנו רוצים לצייר 100 עיגולים אקראיים על אלמנט מסוג {{htmlelement("canvas")}}, ובאמצעות לחיצה על כפתור Update אנחנו נרצה לקבל סט חדש ואחר של 100 עיגולים אקראיים:

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 400, "", "", "hide-codepen-jsfiddle") }}

+ +

אתם לא צריכים להבין את כל הקוד הרשום למעלה, אבל הסתכלו לעומק על החלק שמצייר בפועל 100 כדורים:

+ +
for (let i = 0; i < 100; i++) {
+  ctx.beginPath();
+  ctx.fillStyle = 'rgba(255,0,0,0.5)';
+  ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
+  ctx.fill();
+}
+ + + +

אתם מבינים את הרעיון - אנחנו משתמשים בלולאה על מנת לרוץ 100 איטראציות של הקוד הזה, כאשר בכל ריצה כזו נקבל עיגול במיקום אקראי אחר. אם נרצה יותר מ-100 עיגולים פשוט נשנה מספר אחד!.

+ +

אם לא היינו משתמשים בלולאה, היינו צריכים לרשום את הקוד הבא שוב ושוב בהתאם לכמות הפעמים שהיינו רוצים שיצוייר עיגול:

+ +
ctx.beginPath();
+ctx.fillStyle = 'rgba(255,0,0,0.5)';
+ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
+ctx.fill();
+ +

לולאת for

+ +

נחקור כיצד לולאות מסויימות בנויות. סוגי הלולאות השונים מאפשרים לנו דרכים שונות על מנת לקבוע את נקודת ההתחלה והעצירה של הלולאה.

+ +

הראשונה, שאנחנו נשתמש בה הרבה מאוד פעמים, היא לולאה מסוג for. לולאה זו היא בעלת הסינטקס הבא:

+ +
for (initializer; exit-condition; final-expression) {
+  // code to run
+}
+ +

הסבר:

+ +
    +
  1. המילה השמורה for, ולאחריה סוגריים רגילות ().
  2. +
  3. בתוך הסוגריים הרגילות () יש לנו 3 ביטויים, מופרדים על ידי ;: +
      +
    1. initializer  - מונה-מאתחל — פה אנו נראה בדרך כלל הצהרה על משתנה, בדרך כלל משתנה let אשר אנחנו נותנים לו ערך (מספר) התחלתי לפני שהלולאה רצה. הוא ישמש את הלולאה כמונה של מספר הריצה הרלוונטית. 
    2. +
    3. exit-condition - תנאי יציאה — זהו התנאי שנבדק בטרם כל איטרציה. אם תוצאת המבחן היא true, הלולאה תמשיך לרוץ והביטוי שבתוך הסוגריים המסולסלות יבוצע. אם תוצאת המבחן היא false הלולאה תפסיק לרוץ. תנאי היציאה הוא בדרך כלל ביטוי הכולל אופטורים להשוואה - מבחנים לבדיקה האם התקיים תנאי מסויים.
    4. +
    5. final-expression - iterator - ביטוי לקידום הלולאה — ביטוי זה יבוצע או ירוץ בכל פעם שהלולאה ביצעה ריצה/איטראציה במלואה. ביטוי זה משמש בדרך כלל להעלות (או להוריד) את המונה-מאתחל על מנת לקרב אותו לקיום תנאי היציאה.
    6. +
    7. שימו לב כי כל הביטויים האלו הם אופציונליים - אך לא ניכנס לאפשרויות השונות לעומק. אתם מוזמנים להרחיב בנושא בדף בנושא לולאת for
    8. +
    +
  4. +
  5. לאחר מכן יש לנו סוגריים מסולסלות {...} שכוללות בתוכן קוד אשר ירוץ בכל פעם שהלולאה מבצעת איטרציה.
  6. +
+ +

נסתכל על הדוגמא הבאה:

+ +
const cats = ['Bill', 'Jeff', 'Pete', 'Biggles', 'Jasmin'];
+let info = 'My cats are called ';
+const para = document.querySelector('p');
+
+for (let i = 0; i < cats.length; i++) {
+  info += cats[i] + ', ';
+}
+
+para.textContent = info;
+ +

הקוד למעלה יציג לנו את הפלט הבא:

+ + + +

{{ EmbedLiveSample('Hidden_code_2', '100%', 60, "", "", "hide-codepen-jsfiddle") }}

+ +
+

תשומת לב: ניתן למצוא את הקוד ב- GitHub או לראות אותו פה.

+
+ +

קוד זה מראה לולאת for שמבצעת איטרציה על הפריטים במערך ועושה משהו עם כל אחד מהם - זוהי תבנית שנראה שוב ושוב ב-JavaScript. בדוגמא זו למשל:

+ +
    +
  1. המונה: לפעמים גם נקרא כמאתחל, הינו משתנה i, והוא מתחיל ב-0.   (let i = 0).
  2. +
  3. בדיקת תנאי יציאה/עצירת הלולאה: הלולאה תרוץ כל עוד i קטן יותר ממספר האיברים שנמצאים במערך cats. (מציאת כמות האיברים שנמצאת במערך זה מתבצעת באמצעות cats.length. תנאי היציאה הוא חשוב ביצירת לולאה - הוא קובע מהו התנאי אשר רק כאשר תוצאות תהיה true, הלולאה תמשיך ותבצע איטרציה נוספת. במקרה הזה, כל עוד i < cats.length עדיין נכון, הלולאה תמשיך לרוץ.
  4. +
  5. הרצת הקוד שבתוך הסוגריים המסולסלות: בתוך הלולאה, אנחנו מחברים בין הפריט הנוכחי שהלולאה מבצעת עליו איטרציה [הערך של i באותה ריצה] cats,  ביחד עם פסיק ורווח בסוף המשתנה info: +
      +
    1. במהלך הריצה הראשונה - האיטרציה הראשונה, , i = 0, ולכן cats[0] + ', ' (שהוא שווה ל-Bill, ) יצורף לתוך info.
    2. +
    3. במהלך הריצה השנייה - האיטרציה השנייה , i = 1, ולכן cats[1] + ', ' (אשר שווה ל- Jeff, ) יצורך גם הוא לתוך info.
    4. +
    +
  6. +
  7. קירוב המונה לתנאי היציאה: אחרי כל ריצה של הלולאה, נוסיף 1 ל-i באמצעות ++iשימו לב - רק אחרי שהקוד שבתוך הסוגריים המסולסלות מבוצע, מתבצעת הוספה של 1 למשתנה i וכך הלאה.
  8. +
  9. ביצוע בדיקה חוזרת לתנאי העצירה ועמידה בו:  לאחר קירוב המונה לתנאי העצירה, תבוצע בדיקה חוזרת האם התנאי מתקיים -  כאשר תוצאת התנאי תהיה שוב true, הלולאה תמשיך ותבצע איטרציה נוספת.
  10. +
  11. רק כאשר i יהיה שווה ל- cats.length (במקרה זה, 5), הלולאה תפסיק שכן הערך המתקבל בתוצאה הוא false והדפדפן יעבור לקוד שמתחת לולאה. 
  12. +
+ +
+

לתשומת לבכם: רשמנו את תנאי היציאה כ- i < cats.length, ולא i <= cats.length, מכיוון שמחשבים מתחילים לספור מ-0 ולא מ-1 — אנחנו מתחילים כאשר i שווה ל0, וממשיכים עד אשר i = 4 (האינדקס של האיבר האחרון במערך).

+ +

 cats.length יחזיר 5, ומכיוון שאכן ישנם 5 פריטים, אבל הפריט החמישי של cats.length, נמצא באינדקס מס׳ 4. ולכן אנחנו לא רוצים את cats.length אלא את cats.length פחות אחד. אם נשים רק את cats.length, כאשר   i = 5  המבחן יחזיר לנו ערך של  undefined בעבור הפריט האחרון - שכן אין איבר באינדקס 5. ולכן, אנחנו נרצה להריץ את הלולאה מספר 1 פחות.

+
+ +
+

לתשומת לב: טעות נפוצה עם תנאי יציאה היא להשתמש עם (״שווה ל-״)  (===)  במקום עם (״קטן מ- או שווה ל-״) (<=) .

+ +

אם אנחנו נרצה להריץ את הלולאה שלנו עד אשר i = 5, תנאי היציאה יצטרך להיות i <= cats.length.אם נקבע אותו כ i === cats.length  אזי הלולאה לא תרוץ בכלל מכיוון ש-i לא שווה ל-5 באיטרציה הראשונה של הלולאה, ולכן הלולאה תעצור במיידי.

+
+ +

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

+ +
+

My cats are called Bill, Jeff, Pete, Biggles, Jasmin,

+
+ +

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

+ +
for (let i = 0; i < cats.length; i++) {
+  if (i === cats.length - 1) {
+    info += 'and ' + cats[i] + '.';
+  } else {
+    info += cats[i] + ', ';
+  }
+}
+ +
+

לתשומת לב: ניתן למצוא את קוד הדוגמא הזו ב- GitHub או כ- דף אינטרנט).

+
+ +
+

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

+
+ +

יציאה מלולאות באמצעות break

+ +

אם אנחנו רוצים לצאת מלולאה לפני שכל האיטרציות הושלמו, אנחנו יכולים להשתמש בביטוי break. ראינו אותו בעבר כשלמדנו על משפטי תנאי מסוג switch (כאשר ביטוי מסויים עונה למקרה מסויים - break עוצר באופן מיידי את המשך הבדיקה וממשיך לקוד שלאחר משפט switch).

+ +

בדיוק אותו הדבר כמו עם לולאות - הביטוי break יגרום ליציאה מיידית מהלולאה והדפדפן ימשיך לקוד שנמצא לאחר מכן.

+ +

נניח ואנחנו רוצים לחפש בתוך מערך של אנשי קשר וטלפונים, ואז להחזיר רק את המספר שאנחנו רוצים למצוא? נתחיל ב-HTML פשוט - תיבת טקסט + {{htmlelement("input")}}, המאפשרת לנו להכניס את השם שנרצה לחפש ואלמנט מסוג כפתור {{htmlelement("button")}} על מנת לשלוח את החיפוש וכן אלמנט של פסקה  {{htmlelement("p")}} על מנת להציג בו את התוצאות.

+ +
<label for="search">Search by contact name: </label>
+<input id="search" type="text">
+<button>Search</button>
+
+<p></p>
+ +

כעת נכניס - JavaScript:

+ +
const contacts = ['Chris:2232322', 'Sarah:3453456', 'Bill:7654322', 'Mary:9998769', 'Dianne:9384975'];
+const para = document.querySelector('p');
+const input = document.querySelector('input');
+const btn = document.querySelector('button');
+
+btn.addEventListener('click', function() {
+  let searchName = input.value.toLowerCase();
+  input.value = '';
+  input.focus();
+  for (let i = 0; i < contacts.length; i++) {
+    let splitContact = contacts[i].split(':');
+    if (splitContact[0].toLowerCase() === searchName) {
+      para.textContent = splitContact[0] + '\'s number is ' + splitContact[1] + '.';
+      break;
+    } else {
+      para.textContent = 'Contact not found.';
+    }
+  }
+});
+ + + +

{{ EmbedLiveSample('Hidden_code_3', '100%', 100, "", "", "hide-codepen-jsfiddle") }}

+ +
    +
  1. ראשית - הגדרנו קבועים - יש לנו מערך עם פרטי קשר - כאשר כל איבר במערך הוא מחרוזת המכילה שם ומספר טלפון המופרדים על ידי :. הגדרנו קבוע בשם para שמקבל הפנייה לאלמנט <p>. הגדרנו קבוע בשם input שמקבל הפניה לאלמנט <input> וקבוע בשם btn שמקבל הפניה ל-<button>
  2. +
  3. לאחר מכן חיברנו ״מאזין אירוע״ לכפתור - (btn), כך שבכל פעם שהוא יילחץ ירוץ קוד מסויים לביצוע החיפוש ויחזיר את התוצאה (event handler). במקרה הזה, זו הפונקציה האנונימית שנמצאת מיד לאחר הביטוי 'click'.
  4. +
  5. אחסנו את הערך שהוכנס לתוך תיבת הטקסט (input)  בתוך משתנה שנקרא searchName, לאחר מכן ריקנו את תיבת הטקסט מתוכן, ועשינו עליה פוקוס באמצעות מתודת ()focus , על מנת שתהיה מוכנה לחיפוש הבא. שימו לב שאנחנו גם הרצנו את מתודת ()toLowerCase על הערך שהתקבל ב-input כדי לנרמל את המחרוזת. 
  6. +
  7. ועכשיו לחלק המעניין של לולאת ה-for: +
      +
    1. אנחנו מתחילים את המונה ב-0, מתבצעת בדיקת עמידה בתנאי, ככל והערך המוחזר הוא true, מתבצעת איטרציה - הרצה של הקוד שבתוך הסוגריים המסולסלות של הלולאה: +
        +
      1. בתוך הלולאה אנחנו תחילה מחלצים כל חלק מהמחרוזת הראשית באמצעות מתודה שאנחנו מכירים ()split, אשר מקבלת את התו : כתו שיחצה את המחרוזת contacts בכל פעם שהמתודה תמצא את התו הזה. להזכירכם מתודה זו מחזירה מערך של מחרוזות שהופרדו על ידי התו שהיא קיבלה. במקרה הזה אנחנו מאחסנים במשתנה בשם splitContact את המערך החדש שהוחזר לנו בכל איטרציה שזה בעצם מערך עם שני איברים: שם ומספר. 
      2. +
      3. לאחר מכן אנחנו משתמשים במשפט תנאי לבדוק האם [splitContact[0 שזה בעצם שם האדם מנורמל באמצעות()toLowerCase, שווה לטקסט שנמצא ב-searchName. אם כן, אנחנו נכניס מחרוזת לתוך הפסקה עם הטלפון שלו שזה בעצם [splitContact[1, ונשתמש ב-break על מנת לעצור את הלולאה. 
      4. +
      +
    2. +
    3. לאחר מכן מתבצעת הגדלת של ה-i ב-1 בכל איטרציה מוצלחת של הלולאה באמצעות ++i.
    4. +
    +
  8. +
  9. אחרי כל האיטרציות, כאשר i יהיה שווה לאיבר האחרון במערך של המחרוזת הראשית - כלומר אחרי (contacts.length-1) אם searchName לא זהה לאף  [splitContact[i, אז טקטסט של הפסקה הופך ל- "Contact not found."  
  10. +
+ +
+

לתשומת לב: ניתן למצוא את קוד המקור - GitHub code on GitHub או כדף אינטרנט.

+
+ +

דילוג על איטרציה עם continue

+ +

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

+ +

ה-HTML  בעיקרון דומה לדוגמא הקודמת - יש לנו תיבת טקסט פשוטה ופסקה להציג את הפלט. ה-JavaScript גם דומה, למרות שהלולאה שלנו קצת אחרת:

+ +
let num = input.value;
+
+for (let i = 1; i <= num; i++) {
+  let sqRoot = Math.sqrt(i);
+  if (Math.floor(sqRoot) !== sqRoot) {
+    continue;
+  }
+
+  para.textContent += i + ' ';
+}
+ +

זה הפלט שלנו:

+ + + +

{{ EmbedLiveSample('Hidden_code_4', '100%', 100, "", "", "hide-codepen-jsfiddle") }}

+ +
    +
  1. במקרה הזה, הקלט צריך להיות מספר - num. אנו נותנים ללולאת ה-for מונה שמתחיל ב-1 (אנחנו לא מעוניינים ב- 0 במקרה הנוכחי), תנאי יציאה שאומר שהלולאה תפסיק כאשר המונה יהיה גדול מהמספר שהכנסנו - מ-num, ואז ביטוי העלאה שמוסיף למונה 1 בכל איטרציה. 
  2. +
  3. בתוך הלולאה, אנחנו מוצאים את השורש הריבועי של כל מספר (של כל num) באמצעות שימוש במתודה ()Math.sqrt, ואז בודקים האם השורש הריבועי הוא שלם על ידי בדיקה האם הוא זהה לעצמו כשהוא מעוגל כלפי מטה לשלם הקרוב - זה מה שמתודת ()Math.floor עושה למספר שמועבר אליה - היא מחזירה את המספר השלם הגדול ביותר אשר נמוך מהמספר שהבאנו לה או השווה לו.
  4. +
  5. אם השורש הריבועי והמספר שעוגל כלפי מטה אינהם זהים אחד לשני - (!==), המשמעות היא שהשורש הריבועי הוא לא מספר שלם, ולכן אנחנו לא מעוניינים בו. במקרה כזה, אנחנו נשתמש בביטוי continue על מנת לעבור לאיטרציה הבאה, אבל מבלי להמשיך להריץ את קוד אשר נמצא בהמשך האיטרציה הנוכחית (וביתר האיטרציות) ומבלי לצאת מהלולאה.
  6. +
  7. אם השורש הריבוע הוא מספר שלם, אנחנו לא עומדים בתנאי שרשום במשפט ה-if ולכן המשפט continue לא מורץ. במקום, אנחנו מצרפים את הערך שבתוך i בצירוף רווח, לסוף של הטקסט שבתוך הפסקה. 
  8. +
+ +
+

לתשומת לב: ניתן לראות את  קוד המקור ב-GitHub או לראות את הדף אינטרנט.

+
+ +

while ו-do ... while

+ +

לולאות for הן לא הלולאות היחידות שיש לנו ב-JavaScript. האמת שיש עוד הרבה אחרות. אנחנו ללא צריכים לדעת את כולן כעת, אבל שווה יהיה להעיף מבט בכמה ונבין שאפשרויות שונות עובדים בצורה שונה.

+ +

לולאת while מורכבת מהסינטקס הבא:

+ +
initializer
+while (exit-condition) {
+  // code to run
+
+  final-expression
+}
+ +

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

+ +

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

+ +

בוא נסתכל שוב על רשימת החתולים, אבל נכתוב אותה באמצעות לולאת while:

+ +
let i = 0;
+
+while (i < cats.length) {
+  if (i === cats.length - 1) {
+    info += 'and ' + cats[i] + '.';
+  } else {
+    info += cats[i] + ', ';
+  }
+
+  i++;
+}
+ +
+

לתשומת לב: זה עובד כמו שציפינו — ראו את הדף עובד ב-GitHub או את קוד המקור).

+
+ +

לולאת do...while דומה מאוד ללולאת while אבל שונה מעט:

+ +
initializer
+do {
+  // code to run
+
+  final-expression
+} while (exit-condition)
+ +

במקרה הזה, המאתחל מגיע שוב ראשון, לפני שהלולאה מתחילה. המילה שמורה do ולאחר מכן סוגריים מסולסלות {} שבותכן ייכנס הקוד שנרה שירוץ בלולאה. ולסוף , המילה השמורה while ולאחרי קוד היציאה.

+ +

השוני כאן זה שתנאי היציאה מגיע בסוף, עטוף בתוך סוגריים רגילות (). בלולאת do...while, הקוד בתוך הסוגריים המסולסלות {...} תמיד ירוץ פעם אחת לפחות לפני בדיקת התנאי ואז יבדוק את התנאי על מנת לבדוק האם לרוץ שוב. להזכירכם - בלולאות while ובלולאות for, בדיקת התקיימות התנאי מתבצעת לפני הרצת הקוד שבתוך {...}  כך שיכול להיות שהקוד בלולאות אלו לא יבוצע לעולם. בלולאת do...while לעומת זאת, הקוד תמיד ירוץ פעם אחת לפחות.

+ +

בוא נכתוב את הדוגמא שלנו באמצעות הלולאה do...while:

+ +
let i = 0;
+
+do {
+  if (i === cats.length - 1) {
+    info += 'and ' + cats[i] + '.';
+  } else {
+    info += cats[i] + ', ';
+  }
+
+  i++;
+} while (i < cats.length);
+ +
+

לתשומת לב: הלולאה עובדת בדיוק כפי שרצינו - ראו ב- GitHub וכן את קוד המקור.

+
+ +
+

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

+
+ +

למידה עצמאית: בניית שעון ספירה לאחור

+ +

בתרגיל זה, אנחנו נרצה שתבנה תוכנית שתדפיס שעון עצר מ-10 ל-0 וכן:

+ + + + +

אם עשיתם טעות אתם תמיד יכולים לאתחל את הקוד באמצעות הכפתור "Reset" ואם ממש נתקתעם לחצו על כפתור "Show solution" לפתרון.

+ + + +

{{ EmbedLiveSample('Active_learning', '100%', 880, "", "", "hide-codepen-jsfiddle") }}

+ +

למידה עצמאית - מילוי של רשימת אורחים

+ +

+ בתרגיל זה, אנחנו רוצים שתיקחו רשימה של שמות שמאוחסנים במערך ותכניסו אותם לתוך רשימת אורחים. זה לא כזה קל - אנחנו רוצים רשימת אורחים שמורשים להיכנס ורשימת אורחים שלא מורשים להיכנס.

+ +

אתם מתבקשים לבצע את הדברים הבאים:

+ + + +

לבינתיים סיפקנו לכם:

+ + + +

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

+ +

אם עשיתם טעות אתם תמיד יכולים לאתחל את הקוד באמצעות הכפתור "Reset" ואם ממש נתקתעם לחצו על כפתור "Show solution" לפתרון

+ + + +

{{ EmbedLiveSample('Active_learning_2', '100%', 680, "", "", "hide-codepen-jsfiddle") }}

+ +

באיזו לולאה עלינו להשתמש??

+ +

+ בדרך כךך, לשימושים בסיסים, הלולאות for, while, ו-do...while, הן חלופיות. כולן לרוב יכולות לפתור את אותן בעיות ואתם תחליטו במה לבחור.

+ +

תחילה לולאת for:

+ +
for (initializer; exit-condition; final-expression) {
+  // code to run
+}
+ +

לולאת while:

+ +
initializer
+while (exit-condition) {
+  // code to run
+
+  final-expression
+}
+ +

לולאת do...while:

+ +
initializer
+do {
+  // code to run
+
+  final-expression
+} while (exit-condition)
+ +

+ אנחנו ממליצים על לולאת _____, לפחות בהתחלה, כיוון שהיא לרוב הקלה ביותר לזכור - המאתחל, תנאי היציאה ומקדם/מחסיר, אשר כולם נכנסים בתוך הסוגריים הרגילות וכך קל לבדוק שלא שכחנו כלום.

+ +
+

לתשומת לב: + יש סוגי לולאות נוספים ואפשרויות נוספות ללולאות, גם לאלו שסקרנו במאמר זה. אפשרויות ולולאות אלו הן מאוד שימושיות במקרים מתקדמים או פרטניים ולא נגע בהם במאמר זה. אם תרצו להעמיק, ראו את הדף בנושא + Loops and iteration guide.

+
+ +

לסיכום

+ +

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

+ +

ראו גם

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Building_blocks/conditionals","Learn/JavaScript/Building_blocks/Functions", "Learn/JavaScript/Building_blocks")}}

+ +

במודול זה

+ + diff --git a/files/he/learn/javascript/building_blocks/return_values/index.html b/files/he/learn/javascript/building_blocks/return_values/index.html new file mode 100644 index 0000000000..52e224289b --- /dev/null +++ b/files/he/learn/javascript/building_blocks/return_values/index.html @@ -0,0 +1,180 @@ +--- +title: return values - ערכים המוחזרים מפונקציה +slug: Learn/JavaScript/Building_blocks/Return_values +tags: + - Beginner + - Functions + - JavaScript + - Return values + - מדריך + - ערכים מוחזרים + - פונקציות +translation_of: Learn/JavaScript/Building_blocks/Return_values +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Build_your_own_function","Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}
+ +

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

+ + + + + + + + + + + + +
ידע מוקדם: +

הכרות בסיסית עם המחשב ועם הבסיס של HTML ו- CSS, סיום במלואו של מודול צעדים ראשונים ב-JavaScript. וכן, את המאמר בנושא Functions — פונקציות - חלקי קוד לשימוש חוזר.

+
מטרה:להבין מהם return values, וכיצד להתשמש בהם.
+ +

מה הם return values?

+ +

Return values הם בדיוק כמו שהם נשמעים - אלו ערכים שמוחזרים על ידי הפונקציה כאשר היא מסיימת. אנחנו כבר ראינו return values במספר פעמים, למרות שאולי לא חשבנו עליהם כך. נחזור לקוד שאנחנו מכירים:

+ +
var myText = 'I am a string';
+var newString = myText.replace('string', 'sausage');
+console.log(newString);
+// the replace() string function takes a string,
+// replaces one substring with another, and returns
+// a new string with the replacement made
+ +

ראינו את הקוד הזה בעבר במאמר הראשון בנושא פונקציות. אנחנו קוראים/מפעילים את הפונקציה ()replace על המחרוזת myText ומעבירים לה שני פרמטרים (ארגומנטים) - את המחרוזת משנה('string') שהיא צריכה לחפש במחרוזת הראשית (myText) ואת המחרוזת משנה החדשה שתחליף את המחרוזת משנה שנמצאה ('sausage'). כאשר פונקציה זו מסיימת - משלימה את הריצה שלה, היא מחזירה ערך, שהוא בעצם המחרוזת החדשה עם ההחלפה שבוצgה. בקוד למעלה, אנחנו שומרים את אותו ערך מוחזר כערך של המשתנה newString שלנו.

+ +

אם תעיפו מבט על הדף שלנו בנושא פונקציית ()replace, אתם תראו חלק שנקרא Return value. תמיד חשוב לדעת ולהבין אלו ערכים מוחזרים על ידי פונקציה, על מנת שנוכל להשתמש בהם אם נרצה או כשנצטרך.

+ +

חלק מהפונקציות לא מחזירות return value. במקרים כאלו, הערך המוחזר יהיה void או undefined. לדוגמא, בפונקציה ()displayMessage שבנינו במאמר הקודם, אין ערך מוחזר כתוצאה מהשלמת ריצת הפונקציה. היא רק גרמה לקופסא להיות מוצגת איפשהו על המסך.

+ +

באופן כללי, return value משמש כאשר הפונקציה היא שלב ביניים בחישוב כלשהו שאנחנו מבצעים לשם קבלת תוצאה סופית. ערכים מוחזרים אלו צריכים להיות מחושבים על ידי הפונקציה, והיא מחזירה את הערכים הללו בתור התוצאות של הקריאה לה (הריצה שלה), ובתוצאות הללו ניתן להשתמש בשלב הבא של החישוב.

+ +

שימוש ב- return values בפונקציות שלנו

+ +

על מנת להחזיר ערך מפונקציה שאנחנו בונים, אנחנו צריכים להשתמש במילה השמורה return. ראינו מילה זו בפעולה לאחרונה בתרגול שלנו בנושא random-canvas-circles.html. פונקציית ()draw שלנו מציירת 100 עיגולים אקראיים על האלמנט {{htmlelement("canvas")}}:

+ +
function draw() {
+  ctx.clearRect(0,0,WIDTH,HEIGHT);
+  for (var i = 0; i < 100; i++) {
+    ctx.beginPath();
+    ctx.fillStyle = 'rgba(255,0,0,0.5)';
+    ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
+    ctx.fill();
+  }
+}
+ +

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

+ +
function randomNumber(number) {
+  return Math.floor(Math.random()*number);
+}
+ +

הקוד למעלה היה יכול להירשם גם כך:

+ +
function randomNumber(number) {
+  var result = Math.floor(Math.random()*number);
+  return result;
+}
+ +

אבל הגרסה הראשונה של הקוד קלה יותר לכתיבה וגם קומפקטית יותר.

+ +

אנחנו מחזירים את התוצאה של החישוב (Math.floor(Math.random()*number בכל פעם שקוראים לפונקציה. הערכים המוחזרים הללו מופיעים ברגע שהפונקציה נקראת (מופעלת), והקוד ממשיך. לדוגמא, אם נריץ את השורות הבאות:

+ +
ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
+ +

ושלושת הקריאות לפונקציה ()random החזירו נניח את הערכים 500, 200, ו- 35, בהתאמה, השורה תרוץ בפועל כאילו היא נכתבה כך :

+ +
ctx.arc(500, 200, 35, 0, 2 * Math.PI);
+ +

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

+ +

למידה עצמאית: הגדרת - return value של הפונקציה שלנו

+ +

בתרגול זה אנחנו נכתוב פונקציות משלנו הכוללות return values.

+ +
    +
  1. ראשית, שמרו עותק מקומי של הקובץ function-library.html מ-GitHub. זהו דף HTML פשוט המיכל שדה טקסט {{htmlelement("input")}} ופסקה. בנוסף יש גם אלמנט {{htmlelement("script")}} כאשר בתוכו עשינו הפנייה לשני האלמנטים של ה-HTML בתוך שני משתנים. דף זה יאפשר לנו להכניס מספר כלשהו לתוך תיבת טקסט, ולהציג חישובים שונים על המספר הזה בתוך הפסקה שמתחת.
  2. +
  3. כעת, נוסיף פונקציות בתוך <script>. מתחת לשתי השורות הקיימות של JavaScript, הוסיפו את הגדרות הפונקציות הבאות: +
    function squared(num) {
    +  return num * num;
    +}
    +
    +function cubed(num) {
    +  return num * num * num;
    +}
    +
    +function factorial(num) {
    +  var x = num;
    +  while (x > 1) {
    +    num *= x-1;
    +    x--;
    +  }
    +  return num;
    +}
    + הפונקציות ()squared ו- ()cubed דיי ברורות - הן מחזירות את תוצאות ההכפלה או את השילוש של מספר שניתן להן כפרמטר, בעצמו. הפונקציה ()factorial מחזירה את תוצאת העצרת של מספר מסויים. אם אתם לא זוכרים מה זה עצרת, ראו הסבר על הערך בויקיפדיה.
  4. +
  5. כעת, אנחנו הולכים להוסיף דרך להדפיס את כל המידע הזה לגבי המספר שהכנסנו. הכניסו את הקוד הבא, מתחת לפונקציות הנוכחיות: +
    input.onchange = function() {
    +  var num = input.value;
    +  if (isNaN(num)) {
    +    para.textContent = 'You need to enter a number!';
    +  } else {
    +    para.textContent = num + ' squared is ' + squared(num) + '. ' +
    +                       num + ' cubed is ' + cubed(num) + '. ' +
    +                       num + ' factorial is ' + factorial(num) + '.';
    +  }
    +}
    + +

    הוספנו פונקציה בתור ״מטפל אירוע״ אשר תרוץ כל פעם שאירוע מסוג onchange החל להתרחש בשדה הטקסט שלנו (input), כלומר - כל פעם שמוכנס ערך חדש לתוך שדה הטקסט והערך הזה הוגש - כלומר לחצנו על אנטר או עברנו לאלמנט אחר בדף. כאשר פונקציה אנונימית זו רצה, הערך שהוכנס לתוך שדה הטקסט מאוחסן בתוך המשתנה num.

    +
  6. +
  7. +

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

    + +
      +
    1. +

      אם הערך שהוכנס אינו מספר, אנחנו נציג הודעת שגיאה לתוך הפסקה. המבחן שלנו מבצע שימוש בפונקציית ()isNaN אשר בודקת האם הערך שהוכנס ב-num הוא לא מספר. אם הערך שהוכנס הוא מספר - היא מחזירה false ואם הוא לא מספר היא מחזירה true.

      +
    2. +
    3. +

      אם המבחן שלנו החזיר false, אז הערך של num הוא מספר ואנחנו יכולים להדפיס לתוך האלמנט p שלנו מהו תוצאת ההכפלה, השילוש והעצרת שלו. המשפט שלנו קורא לפונקציות ()squared(), cubed, ו- ()factorial על מנת לקבל את הערכים הללו.

      +
    4. +
    +
  8. +
  9. שמרו את הקוד ונסו אותו בדפדפן שלכם.
  10. +
+ +
+

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

+
+ +

תרגיל זה ניסה להציג לכם כמה מהנקודות החשובות של ביטוי return. בנוסף:

+ + + +

לסיכום

+ +

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

+ +

ראו גם

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Build_your_own_function","Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}

+ +

במודול זה

+ + diff --git "a/files/he/learn/javascript/building_blocks/\327\252\327\240\327\220\327\231\327\235/index.html" "b/files/he/learn/javascript/building_blocks/\327\252\327\240\327\220\327\231\327\235/index.html" new file mode 100644 index 0000000000..4c5c5dcc54 --- /dev/null +++ "b/files/he/learn/javascript/building_blocks/\327\252\327\240\327\220\327\231\327\235/index.html" @@ -0,0 +1,789 @@ +--- +title: משפטי תנאי - קבלת החלטות בקוד שלנו +slug: Learn/JavaScript/Building_blocks/תנאים +tags: + - Conditionals + - Switch + - else if + - if ... else + - ternary + - אופרטור טרנארי + - משפטי אם...אחר + - משפטי תנאי + - תנאים +translation_of: Learn/JavaScript/Building_blocks/conditionals +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/JavaScript/Building_blocks/Looping_code", "Learn/JavaScript/Building_blocks")}}
+ +

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

+ + + + + + + + + + + + +
ידע מוקדם:הכרות בסיסית עם המחשב ועם הבסיס של HTML ו- CSS, וכן סיום במלאו של מודול צעדים ראשונים ב-JavaScript.
מטרה:להבין כיצד להשתמש במשפטי תנאי ב-JavaScript.
+ +

תנאים והתניות בחיים האמיתיים

+ +

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

+ +

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

+ +

+ +

if ... else - משפטי אם ... אחרת

+ +

נסתכל על הסוג הנפוץ ביותר של משפטי תנאי ב-JavaScript - משפט התנאי if ... else.

+ +

הסינטקס הבסיסי של משפטי if ... else

+ +

אם ננסה להמחיש את הסינטקס הבסיסי של if...else בצורה מופשטת של {{glossary("pseudocode")}}, הוא ייראה כך:

+ +
if (condition - תנאי) {
+  code to run if condition is true - הקוד שירוץ אם התנאי נכון
+} else {
+  run some other code instead  - הקוד שירוץ אם התנאי לא נכון
+}
+ +

מה שיש לנו כאן זה:

+ +
    +
  1. המילה השמורה if ולאחרי סוגריים רגילות ().
  2. +
  3. לאחר מכן - התנאי שנבדוק האם הוא מתקיים נמצא בתוך ה- () (כמו: ״האם הערך הזה גדול מערך אחר״ או ״הערך הזה קיים״). תנאי זה יעשה שימוש באופרטורים שדבירנו עליהם במודול הקודם - comparison operators אופרטורים להשוואה ויחזיר לנו ערך של אמת - true או ערך של שקר - false.
  4. +
  5. לאחר מכן  - סוגריים מסולסלות - {} - שבתוכן נכניס כל קוד שנרצה, אשר יתבצע אך ורק אם התנאי התקיים, כלומר החזיר תוצאת אמת - true.
  6. +
  7. לאחר מכן - מילה שמורה נוספת שהיא else. אשר באה לבטא מה יקרה, אם בכלל, כאשר התנאי לא יחזיר תוצאת true
  8. +
  9. ולבסוף - סוגריים מסולסלות נוספות{}- שבתוכן נכניס כל קוד שנרצה, אשר יתבצע אך ורק אם התנאי עצמו לא התקיים, כלומר החזיר תוצאת שקר - false.
  10. +
+ +

קוד זה דיי קריא ומובן על ידי בני אדם - הוא אומר בעצם ש-"אם ה- condition (התנאי) מתקיים - כלומר מחזיר ערך של אמת - true, תריץ את קוד A, אחרת - תריץ את קוד B"

+ +

שימו לב שאנחנו לא חייבים את לכלול את ה- else ואת הסוגריים המסולסלות השניות. כך לדוגמא, התנאי הבא הוא חוקי לחלוטין:

+ +
if (condition) {
+  code to run if condition is true
+}
+
+run some other code
+ +

יחד עם זאת, אנחנו צריכים לזכור שבמקרה כזה, הקוד השני שאינו חלק ממשפט התנאי, לא נשלט על ידיו ולא כפוף למשפט התנאי - מה שאומר שהוא ירוץ תמיד לא משנה אם התנאי החזיר ערך true או false. זה לאו דווקא משהו רע, אבל חשוב לדעת זאת.

+ +

לפעמים אנחנו גם נראה משפטי- if...else ללא סוגריים מסולסלות כלל, בקיצור אשר נראה כך:

+ +
if (condition) code to run if condition is true
+else run some other code instead
+ +

זהו קוד תקין לחלוטין, אך אינו מומלץ לשימוש -  הרבה יותר קל לקרוא קוד ולהבין מה קורה, אם אנחנו משתמשים בסוגריים מסולסולת לתחום את הקוד, וכן משתמשים במס׳ שורות ורווחים על מנת להפוך את הקוד לקריא ומובן יותר.

+ +

דוגמא לתרגול

+ +

על מנת להבין את הסינטקס טוב יותר, בוא ננסה דוגמא קטנה לתרגול. דמיינו ילד אשר התבקש לעזור לאימו בביצוע הקניות. אם הוא ישלים את המשימה, הוא יקבל דמי כיס גבוהים יותר מהרגיל:

+ +
var shoppingDone = false;
+
+if (shoppingDone === true) {
+  var childsAllowance = 10;
+} else {
+  var childsAllowance = 5;
+}
+ +

עם זאת, קוד זה תמיד יגרום לכך שהילד יקבל דמי כיס מופחתים שכן בתחילת הקוד המשתנה shoppingDone קיבל את הערך של false. אנחנו צריכים למצוא דרך להפוך את הערך של המשתנה shoppingDone - true אם הילד השלים את הקניות.

+ +
+

תשומת לב: ניתן לראות את הפתרון לתרגול זה ב- GitHub (וכן ניתן לראות אותו כדף אינטרנט.)

+
+ +

else if - משפטי התניה משורשרים

+ +

הדוגמא הקודמת נתנה לנו שתי אפשרויות אך מה אם נצטרך יותר משתי אפשרויות?

+ +

ישנה דרך לשרשר אפשרויות נוספות לתוך משפט if...else שלנו באמצעות שימוש ב- else if. כל בחירה נוספות דורשת בלוק נוסף של קוד שייכנס בין{ ... }() if לבין { ... }else — ראו את הדוגמאות הבאות, שהן בעצם חלק מיישום פשוט לתחזית מזג אוויר:

+ +
<label for="weather">Select the weather type today: </label>
+<select id="weather">
+  <option value="">--Make a choice--</option>
+  <option value="sunny">Sunny</option>
+  <option value="rainy">Rainy</option>
+  <option value="snowing">Snowing</option>
+  <option value="overcast">Overcast</option>
+</select>
+
+<p></p>
+ +
var select = document.querySelector('select');
+var para = document.querySelector('p');
+
+select.addEventListener('change', setWeather);
+
+function setWeather() {
+  var choice = select.value;
+
+  if (choice === 'sunny') {
+    para.textContent = 'It is nice and sunny outside today. Wear shorts! Go to the beach, or the park, and get an ice cream.';
+  } else if (choice === 'rainy') {
+    para.textContent = 'Rain is falling outside; take a rain coat and a brolly, and don\'t stay out for too long.';
+  } else if (choice === 'snowing') {
+    para.textContent = 'The snow is coming down — it is freezing! Best to stay in with a cup of hot chocolate, or go build a snowman.';
+  } else if (choice === 'overcast') {
+    para.textContent = 'It isn\'t raining, but the sky is grey and gloomy; it could turn any minute, so take a rain coat just in case.';
+  } else {
+    para.textContent = '';
+  }
+}
+
+
+ +

{{ EmbedLiveSample('else_if', '100%', 100, "", "", "hide-codepen-jsfiddle") }}

+ +
    +
  1. כאן יש לנו אלמנט {{htmlelement("select")}} המאפשר לנו לבחור אפשרויות שונות, וכן פסקה פשוטה.
  2. +
  3. ב-JavaScript, אנחו מאחסנים הפניות לאלמנט {{htmlelement("select")}} ולאלמנט- {{htmlelement("p")}} על ידי שמירתם במשתנים ומוסיפים ל-{{htmlelement("select")}} ״מאזין אירוע״ - event listener לאלמנט {{htmlelement("select")}} כך שכאשר הערך שלו ישתנה, הפונקציה ()setWeatherתופעל.
  4. +
  5. כאשר הפונקציה הזו רצה, אנחנו מגדירים תחילה משתנה בשם choice ומשימים לו את הערך הרלוונטי שהמשתמש בחר באלמנט <select>. לאחר מכן, אנחנו משתמשים במשפטי תנאי על מנת לתת כיתוב שונה בטקסט של הפסקאות, בהתאם לערך שיקבל <select> בכל פעם. שימו לב שכל התנאים נבדקים בבלוקי קוד של משפט תנאי {...}()else if, למעט האפשרות הראשונה, אשר נבדק בבלוק של המשפט התנאי {...}()if.
  6. +
  7. האפשרות האחרונה הנמצאת בבלוק של {...}else היא בעצם ברירת המחדל, או האופציה האחרונה. הקוד בבלוק שלה ירוץ רק אם אף אחד מהתנאים לא החזירו true. במקרה הזה, זה ישמש לרוקן את הטקסט מהפסקה ומידה ושום אופציה לא נבחרה.
  8. +
+ +
+

לתשומת לב: אתם גם יכולים למצוא את הדוגמא הזו ב- GitHub או להריץ אותה.

+
+ +

תשומת לב לאופרטורים להשוואה

+ +

אופרטורים להשוואה משמשים לבדוק את התנאים בתוך משפטי התנאי שלנו. עברנו עליהם במאמר מתמטיקה בסיסית ב-JavaScript — מספרים ואופרטורים שלנו. האפשרויות שלנו הן:

+ + + +
+

לתשומת לבכם: חיזרו על החומר אם אינכם זוכרים אותם. 

+
+ +

כאשנו מדברים על תוצאות ההשוואה, אנחנו רוצים לשים תשומת לב לערכים הבוליאנים שנקבל - הלא הם (true/false) ומהו המקור שלהם וכן לשים לב להתנהגות מסויימת שאנחנו ניתקל בה שוב ושוב.

+ +

כל ערך שהוא לא false, undefined, null, 0, NaN, או מחרוזת ריקה - (''), יחזיר לנו אמת - true כאשר הוא נבדק כתנאי במשפט תנאי. ולכן, אנחנו יכולים להשתמש רק בשם של המשתנה בלבד על מנת לבדוק האם הוא אמת או אפילו לבדוק האם הוא קיים - כלומר הוא לא undefined לדוגמא:

+ +
var cheese = 'Cheddar';
+
+if (cheese) {
+  console.log('Yay! Cheese available for making cheese on toast.');
+} else {
+  console.log('No cheese on toast for you today.');
+}
+ +

ואם נחזור לדוגמא הקודמת שלנו עם הילד והמטלה, נוכל לרשום זאת כך:

+ +
var shoppingDone = false;
+
+if (shoppingDone) { // don't need to explicitly specify '=== true'
+  var childsAllowance = 10;
+} else {
+  var childsAllowance = 5;
+}
+ +

שרשור של if ... else

+ +

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

+ +
if (choice === 'sunny') {
+  if (temperature < 86) {
+    para.textContent = 'It is ' + temperature + ' degrees outside — nice and sunny. Let\'s go out to the beach, or the park, and get an ice cream.';
+  } else if (temperature >= 86) {
+    para.textContent = 'It is ' + temperature + ' degrees outside — REALLY HOT! If you want to go outside, make sure to put some suncream on.';
+  }
+}
+ +

למרות שכל הקוד עובד יחד, כל משפט if...else עובד לחלוטין באופן עצמאי מהאחר.

+ +

AND, OR או NOT :אופרטוריים לוגיים - Logical operators

+ +

אם נרצה לבדוק מספר תנאים מבלי לשרשר משפטי if...else שונים, logical operators אופרטוריים לוגיים - יכולים לעזור לנו. כשנעשה בהם שימוש בתנאים, השניים ראשונים עושים את הדברים הבאים:

+ + + +

 ניתן היה לרשום את הקוד הקודם באמצעות שימוש באופרטור הלוגי AND בצורה הבאה:

+ +
if (choice === 'sunny' && temperature < 86) {
+  para.textContent = 'It is ' + temperature + ' degrees outside — nice and sunny. Let\'s go out to the beach, or the park, and get an ice cream.';
+} else if (choice === 'sunny' && temperature >= 86) {
+  para.textContent = 'It is ' + temperature + ' degrees outside — REALLY HOT! If you want to go outside, make sure to put some suncream on.';
+}
+ +

בדוגמא זו, הבלוק קוד הראשון ירוץ רק אם 'choice === 'sunny וגם temperature < 86 יחזיר true.

+ +

דוגמא לשימוש באופרטור הלוגי OR:

+ +
if (iceCreamVanOutside || houseStatus === 'on fire') {
+  console.log('You should leave the house quickly.');
+} else {
+  console.log('Probably should just stay in then.');
+}
+ +

הסוג האחרון של אופרטור לוגי - NOT, מבוטא על ידי האופרטור ! וניתן לשימוש על מנת לשלול ביטוי מסויים. נראה אותו בדוגמא הבאה:

+ +
if (!(iceCreamVanOutside || houseStatus === 'on fire')) {
+  console.log('Probably should just stay in then.');
+} else {
+  console.log('You should leave the house quickly.');
+}
+ +

בקוד זה אם ביטוי של OR מסויים מחזיר true, אז האופרטור NOT יהפוך אותו לשלילי על מנת שכל הביטוי יחזור false.

+ +

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

+ +
if ((x === 5 || y > 3 || z <= 10) && (loggedIn || userName === 'Steve')) {
+  // run the code
+}
+ +

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

+ +
if (x === 5 || 7 || 10 || 20) {
+  // run my code
+}
+ +

במקרה זה, התנאי בתוך הסוגריים () יחזיר לנו תמיד true, כי המספר 7 או כל מספר שאינו 0, תמיד יחזיר ערך של true כי כל ערך שהוא לא false, undefined, null, 0, NaN, או מחרוזת ריקה - (''), יחזיר לנו אמת - true כאשר הוא נבדק כתנאי במשפט תנאי. 

+ +

על מנת שקוד זה יעבוד לוגית כפי שרצינו, אנחנו צריכים להשתמש אופרטור OR על כל אחד מהם:

+ +
if (x === 5 || x === 7 || x === 10 ||x === 20) {
+  // run my code
+}
+ +

משפטי switch

+ +

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

+ +

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

+ +
switch (expression) {
+  case choice1:
+    run this code
+    break;
+
+  case choice2:
+    run this code instead
+    break;
+
+  // include as many cases as you like
+
+  default:
+    actually, just run this code
+}
+ +

הסבר:

+ +
    +
  1. המילה השמורה switch, ולאחריה סט של סוגריים רגילות ().
  2. +
  3. ביטוי או ערך בתוך הסוגריים.
  4. +
  5. המילה השמורה case, ולאחריה מקרה אפשרי שהביטוי או הערך יכול להיות, לאחריו :.
  6. +
  7. קוד שירוץ אם המקרה מתאים לביטוי/ערך.
  8. +
  9. המילי השמורה break, ולאחריה ; אם האפשרות הקודמת תואמת לערך/ביטוי, הדפדפן יפסיק להריץ את הקוד במשפט ה-switch וימשיך לקוד שמתחת למשפט ה-switch.
  10. +
  11. ניתן להוסיף case כמה שרק נרצה. 
  12. +
  13. לבסוף, המילה השמורה default, ולאחריה : וקוד שירוץ. default תרוץ אם הערך/ביטוי שהוכנס לא תואם לאף אחד מאפשרויות ה-case שרשמנו. במקרה של default - אין צורך להתשמש במילה השמורה break, מכיוון שאין מה להפסיק/לעצור לאחר התקיימותו של מקרה זה. 
  14. +
+ +
+

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

+
+ +

דוגמא למשפט switch

+ +

נסתכל על דוגמא אמיתית - נכתוב את יישום מזג האוויר שלנו מחדש באמצעות שימוש במשפט switch:

+ +
<label for="weather">Select the weather type today: </label>
+<select id="weather">
+  <option value="">--Make a choice--</option>
+  <option value="sunny">Sunny</option>
+  <option value="rainy">Rainy</option>
+  <option value="snowing">Snowing</option>
+  <option value="overcast">Overcast</option>
+</select>
+
+<p></p>
+ +
var select = document.querySelector('select');
+var para = document.querySelector('p');
+
+select.addEventListener('change', setWeather);
+
+
+function setWeather() {
+  var choice = select.value;
+
+  switch (choice) {
+    case 'sunny':
+      para.textContent = 'It is nice and sunny outside today. Wear shorts! Go to the beach, or the park, and get an ice cream.';
+      break;
+    case 'rainy':
+      para.textContent = 'Rain is falling outside; take a rain coat and a brolly, and don\'t stay out for too long.';
+      break;
+    case 'snowing':
+      para.textContent = 'The snow is coming down — it is freezing! Best to stay in with a cup of hot chocolate, or go build a snowman.';
+      break;
+    case 'overcast':
+      para.textContent = 'It isn\'t raining, but the sky is grey and gloomy; it could turn any minute, so take a rain coat just in case.';
+      break;
+    default:
+      para.textContent = '';
+  }
+}
+ +

{{ EmbedLiveSample('A_switch_example', '100%', 100, "", "", "hide-codepen-jsfiddle") }}

+ +
+

לתשומת לבכם: אפשר למצוא את הדוגמא ב-​​​​​GitHub או להריץ אותה פה.

+
+ +

 Ternary operator - אופרטור טרנארי

+ +

סינטקס נוסף שנרצה להציג בפניכם לפני שנמשיך הוא אופרטור טרנארי

+ +

אופרטור טרנארי הוא סינטקס קצר אשר בודק התקיימותו של תנאי מסויים ומבצע פעולה מסויימת אם התנאי מתקיים - true, ופעולה אחרת אם התנאי לא מתקיים - false. אופרטור זה שימושי בסיטואציות מסוימות ויכול לקחת הרבה פחות קוד מאשר if...else, במידה ויש שתי אפשרויות, אשר נבחרות לפי מבחן/תנאי true/false.

+ +

על מנת להפשיט את הנושא, הקוד בצורה רעיונית נראה כך:

+ +
( condition ) ? run this code : run this code instead
+ +

נסתכל על דוגמא פשוטה:

+ +
var greeting = ( isBirthday ) ? 'Happy birthday Mrs. Smith — we hope you have a great day!' : 'Good morning Mrs. Smith.';
+ +

יש לנו פה משתנה בשם isBirthday - אם הוא true, אנחנו נתן הודעת יומולדת שמח, ואם הוא false, אנחנו נתן ברכה רגילה.

+ +

דוגמא לאופרטור טרנארי

+ +

שימו לב כי אנחנו לא חייבים לקבוע ערכים בפרמטרים של האופרטור הטרנארי - אנחנו יכולים גם לתת לו כפרמטרים שורות קוד או פונקציות - כל דבר שנרצה. הדוגמא הבאה מראה לנו אפשרות לבחירת עיצוב לאתר על בסיס אופרטור טרנארי.

+ +
<label for="theme">Select theme: </label>
+<select id="theme">
+  <option value="white">White</option>
+  <option value="black">Black</option>
+</select>
+
+<h1>This is my website</h1>
+ +
var select = document.querySelector('select');
+var html = document.querySelector('html');
+document.body.style.padding = '10px';
+
+function update(bgColor, textColor) {
+  html.style.backgroundColor = bgColor;
+  html.style.color = textColor;
+}
+
+select.onchange = function() {
+  ( select.value === 'black' ) ? update('black','white') : update('white','black');
+}
+
+ +

{{ EmbedLiveSample('Ternary_operator_example', '100%', 300, "", "", "hide-codepen-jsfiddle") }}

+ +

כאן יש לנו אלמנט {{htmlelement('select')}} המאפשר לנו לבחור את הסגנון (שחור או לבן) ובנוסף כותרת פשוטה של {{htmlelement('h1')}} על מנת להציג את הכותרת של האתר. לאחר מכן יש לנו פונקציה שנקראת ()update שמקבלת שני צבעים כארגומנטים. הרקע של האתר נקבע על ידי הצבע הראשון שאנחנו בוחרים, והצבע של הטקסט ניתן כפרמטר השני.

+ +

לבסוף ישלנו ״מאזין אירוע״ - event listener בשם onchange. מאזין אירוע זה מכיל ״מטפל אירוע״ - event handler מסוג מסוג אופרטור טרנארי. הוא מתחיל עם מבחן התנאי - select.value === 'black'. אם התנאי מחזיר true, אנחנו נריץ את פונקציית true עם האפרמטרי ׳black׳ ו-׳white׳ - כלומר אנחנו נקבל רקע שחור עם כיתוב טקסט לבן. אם זה תוצאת התקיימות התנאי היא false - פונקציית ()update תרוץ עם פרמטרים לבן ושחור, כלומר הצבעים יהיו הפוכים.

+ +
+

לתשומת לבכם:  אירועים אלו בעצם פעולות או התרחשויות אשר קורים במערכת, אשר אנחנו יכולים ״להאזין״ להם באמצעות ״מאזין אירוע״ - event listener כך שנוכל להגיב בדרך מסויימת, ברגע שהם יתרחשו באמצעות ״מטפל אירוע״ - event handler. אנו נגע בהם בהמשך.

+
+ +
+

לתשומת לב: ראו גם דוגמא זו ב- GitHub או בדוגמא כדף אינטרנט

+
+ +

למידה עצמאית: לוח שנה פשוט

+ +

בדוגמא הבאה, אנחנו הולכים לכתוב דוגמא ללוח שנה. בקוד שלנו יש:

+ + + +

אנחנו צריכים משפט תנאי בתוך ה-event handler שלנו - כלומר בתוך פונקציית onchange שלנו, מתחת להערה ADD CONDITIONAL HERE //. משפט תנאי זה אמור:

+ +
    +
  1. להסתכל על החודש שנבחר ואוכסן במשתנה choice. זה יהיה הערך של האלמנט <select> לאחר שהערך שלו השתנה. בדוגמא שלנו זה יהיה January.
  2. +
  3. להגדיר משתנה בשם days שיהיה שווה למספר הימים בחודש הנבחר. על מנת לעשות זאת אנחנו נצטרך להסתכל על מספר הימים בכל חודש בשנה. אנחנו יכולים להתעלם משנים מעוברות לצרכי דוגמא זו.
  4. +
+ +

רמזים:

+ + + +

אם אתם עושים טעות - תמיד ניתן לאתחל את הקוד למצבו הראשוני באמצעות כפתור ה-״Reset״. אם ממש נתקעתם - הסתכלו על הפתרון.

+ + + +

{{ EmbedLiveSample('Playable_code', '100%', 1110, "", "", "hide-codepen-jsfiddle") }}

+ +

למידה עצמאית: יותר אפשרויות צבעים!

+ +

בתרגול זה, אנחנו הולכים לקחת את האופרטור הטרנארי שראינו קודם, ולהפוך אותו למשפט switch שיאפשר לנו לבחור מבין אפשרות אחת מבין אפשרויות רבות יותר עבור האתר הפשוט שלנו. הסתכלו על {{htmlelement("select")}} - הפעם אתם תראו שיש לו חמש אופציות ולא שתיים. אתם נדרשים להוסיף משפט switch ישר מתחת להערת ADD SWITCH STATEMENT //אשר יבצע את הפעולות הבאות:

+ + + +

אם אתם עושים טעות - תמיד ניתן לאתחל את הקוד למצבו הראשוני באמצעות כפתור ה-״Reset״. אם ממש נתקעתם - הסתכלו על הפתרון.

+ + + +

{{ EmbedLiveSample('Playable_code_2', '100%', 950, "", "", "hide-codepen-jsfiddle") }}

+ +

לסיכום

+ +

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

+ +

ראו גם

+ + + +

{{NextMenu("Learn/JavaScript/Building_blocks/Looping_code", "Learn/JavaScript/Building_blocks")}}

+ +

במודול זה

+ + -- cgit v1.2.3-54-g00ecf