localStorage ב-JavaScript: איך משחק דפדפן זוכר ניקוד
כשמשחק דפדפן זוכר ניקוד גם אחרי רענון, התלמיד פוגש רעיון חשוב: נתונים לא רק מופיעים על המסך. צריך להחליט מה לשמור, איך לקרוא אותו מחדש, ומה לא לשמור בכלל.
תלמיד בונה משחק קטן ב-JavaScript: בכל פגיעה במטרה הניקוד עולה, אבל ברגע שמרעננים את הדף הכול מתאפס. מבחינת השחקן זה מתסכל. מבחינת הלמידה זה רגע מצוין, כי הוא מעלה שאלה אמיתית בפיתוח ווב: איפה המידע חי כשהדף נסגר ונפתח שוב?
localStorage הוא מנגנון בדפדפן שמאפשר לשמור מחרוזות קטנות במחשב של המשתמש. בפרויקט לימודי הוא מתאים במיוחד לדברים פשוטים כמו ניקוד שיא, הגדרות משחק או שלב אחרון. הוא אינו בסיס נתונים מלא, אינו מחליף שרת, ולא מיועד לשמירת מידע רגיש.
בחומרי JavaScript שנמסרו למכללה מופיעים HTML, CSS ו-JavaScript, משחקי דפדפן, תנאים, לולאות, פונקציות, קריאת קוד, קונסולת הדפדפן ו-localStorage. המאמר מתמקד במושג עצמו ובדוגמאות לימודיות, בלי להבטיח פרטי קורס עדכניים או תוצאה עתידית.
מה קורה מהרגע שהניקוד עולה ועד שהוא חוזר למסך?
במקום להציג את localStorage כפקודת קסם, כדאי לראות אותו כרצף החלטות. כל שלב ברצף יכול לעבוד, להישבר או ללמד משהו על נתונים.
- 1
משהו קורה במשחק
השחקן צובר ניקוד, עובר שלב, משנה הגדרה או מסיים סיבוב קצר.
- 2
המצב נשמר
הקוד בוחר שם מפתח ברור ושומר ערך קטן שהמשחק יוכל לקרוא בהמשך.
- 3
הדף נטען מחדש
המשחק מתחיל מהתחלה, אבל לפני הצגת המסך הוא בודק אם קיים מידע שמור.
- 4
המידע חוזר בזהירות
הקוד ממיר את הערך, בודק שהוא הגיוני, ורק אז מציג אותו לשחקן.
דוגמה קצרה: שמירת ניקוד שיא
נניח שיש במשחק משתנה בשם score. כשסיבוב מסתיים, הקוד יכול להשוות אותו לניקוד השיא ששמור בדפדפן. אם התוצאה החדשה גבוהה יותר, שומרים אותה. כשפותחים את המשחק מחדש, קוראים את הערך ומציגים אותו ליד הלוח.
const savedHighScore = Number(
localStorage.getItem('space-game-high-score') || 0
)
function finishRound(score) {
if (score > savedHighScore) {
localStorage.setItem('space-game-high-score', String(score))
}
}הדוגמה קטנה בכוונה. היא חושפת כמה החלטות חשובות: בחירת שם מפתח, המרה ממחרוזת למספר, ערך ברירת מחדל, ושאלה מתי בדיוק נכון לשמור.
כשצריך לשמור יותר ממספר אחד
localStorage שומר מחרוזות. אם רוצים לשמור אובייקט קטן, למשל ניקוד, שלב והעדפת צבע, ממירים אותו ל-JSON בזמן שמירה ומחזירים אותו לאובייקט בזמן טעינה.
const state = {
level: 3,
muted: true,
}
localStorage.setItem(
'space-game-state',
JSON.stringify(state)
)מה מתאים לשמור בדפדפן ומה לא?
חלק מהלמידה הוא להבין גבולות. העובדה שאפשר לשמור משהו בצד הלקוח לא אומרת שכדאי לעשות זאת.
| מידע | התאמה | למה |
|---|---|---|
| ניקוד שיא | מתאים בדרך כלל | זהו ערך קטן, לא פרטי, שעוזר להמשיך משחק מקומי. |
| שם משתמש אמיתי | לא בלי מחשבה | מידע אישי דורש זהירות, הסכמה והבנה של ההקשר. |
| סיסמה או טוקן | לא מתאים | מידע רגיש לא אמור להישמר כך בפרויקט לימודי בדפדפן. |
| הגדרת קול או צבע | יכול להתאים | העדפה מקומית קטנה היא דוגמה טובה לשמירה פשוטה. |
שמירה בדפדפן אינה פרטית כמו כספת
תלמידים צריכים לדעת ש-localStorage נמצא בצד הלקוח. בפרויקט לימודי אפשר לפתוח את כלי המפתחים ולראות או למחוק את המידע. לכן לא שומרים שם סיסמאות, מפתחות גישה או פרטים אישיים רגישים.
ארבע שאלות שמגלות את רוב הבאגים
- האם שם המפתח זהה בדיוק בשמירה ובקריאה?
- האם הערך נשמר כמחרוזת וצריך להמיר אותו למספר או לאובייקט?
- האם יש ערך ברירת מחדל כשפותחים את המשחק בפעם הראשונה?
- האם הכפתור שמאפס משחק מוחק גם את המידע השמור?
תרגיל טוב מתקדם בשלוש גרסאות קטנות
קל להעמיס על תלמיד מתחיל מערכת שמירה גדולה מדי: משתמשים, חפצים, שלבים, הגדרות ותפריטים. עדיף לבנות את ההבנה בשלבים. בכל גרסה מוסיפים אחריות אחת בלבד, מרעננים את הדף, בודקים מה נשמר, ומתעדים מה השתנה.
גרסה ראשונה: ניקוד שיא בלבד
מתחילים מערך אחד שקל לראות על המסך. מרעננים את הדף, בודקים שהוא נשאר, ואז משנים אותו דרך משחק אמיתי ולא דרך הקונסולה בלבד.
גרסה שנייה: מצב משחק קטן
מוסיפים אובייקט JSON עם שלב נוכחי והגדרה אחת. כך התלמיד רואה למה צריך מבנה נתונים ולא רק משתנה בודד.
גרסה שלישית: כפתור איפוס
מוסיפים פעולה שמוחקת את המידע השמור ומחזירה את המשחק לברירת המחדל. זה מחייב לחשוב גם על התחלה נקייה, לא רק על שמירה.
בסוף התרגיל כדאי לבקש מהתלמיד לפתוח את כלי המפתחים, למצוא את אזור האחסון של האתר, ולהראות במילים שלו איזה מפתח נשמר ומה הערך שלו. השיחה הזו מחברת בין הקוד שכתב, המידע שנמצא בדפדפן וההתנהגות שהשחקן רואה במסך.
