質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

1回答

658閲覧

ローカルストレージに保存可能に

zawber

総合スコア16

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

1クリップ

投稿2024/10/25 03:00

編集2024/10/25 07:02

単語帳がローカルストレージに保存出来るようになったのですが、流れが分かりません。
教えて貰えると助かります。
97行目のwordはクラスのものとは別ですよね?
質問の要点の一つは、118行のlist.push(word);があるので99行の list.push(new Word(word.en, word.ja));をどう解釈するかということ。突然のnew Word(word.en, word.ja)に面食らっています。

これは要るんだろうかと思い92~102行をコメントにして実行したら以降のようになりました。
驚いたのは、コメントにしない場合と同じ結果だった事です。
イメージ説明
以前のコード

html

1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>単語帳</title> 8</head> 9 10<body> 11 <h1>プログラミング必須英単語600+</h1> 12 <input type="text" placeholder="単語"> 13 <input type="text" placeholder="意味"> 14 <button id="btn">登録</button> 15 <p id="total">全0件</p> 16 <table id="table"> 17 <tr> 18 <th>単語</th> 19 <th>意味</th> 20 </tr> 21 <tr> 22 <td colspan=2 id="class">BASIC 300</td> 23 </tr> 24 </table> 25 26 27 <style> 28 h1 { 29 font-family: "Yu Gothic"; 30 } 31 32 /*idにテーブルがついている要素*/ 33 #table { 34 /* テーブルの境界線を重ねて表示し、隣接するセルの境界線を1本にまとめる */ 35 border-collapse: collapse; 36 } 37 38 /*td要素とth要素*/ 39 td, 40 th { 41 /*1px実践の罫線(色は#333)*/ 42 border: 1px solid #333; 43 /*上下0 左右10pxのパディング*/ 44 padding: 0 10px; 45 /*テキストを中央揃えにする */ 46 text-align: center; 47 } 48 49 th { 50 background: #0000ff; 51 /*文字色を白に設定*/ 52 color: white; 53 } 54 55 #class { 56 background: pink; 57 } 58 </style> 59 60 61 <script> 62 'use strict'; 63 64 //文書が読み込み終わったら処理を実行 65 window.onload = () => { 66 class Word { 67 //コンストラクター 68 constructor(en, ja) { 69 this.en = en; 70 this.ja = ja; 71 } 72 73 //メソッド 74 showInfo() { 75 return `<td>${this.en}</td><td>${this.ja}</td>`; 76 } 77 } 78 79 //input要素をNodeListとして取得 80 const inputs = document.querySelectorAll('input'); 81 //セレクタをもとに要素を取得 82 const btn = document.querySelector('#btn'); 83 const total = document.querySelector('#total'); 84 const table = document.querySelector('#table'); 85 86 //空の配列を準備 87 let list = []; 88 89 //btnにクリックイベントを登録 90 btn.addEventListener('click', () => { 91 // 入力値を取得(前後についた無駄なスペースを除去) 92 const enValue = inputs[0].value.trim(); 93 const jaValue = inputs[1].value.trim(); 94 95 if (enValue === '' || jaValue === '') { 96 alert('単語と意味を両方入力してください。'); 97 return; // 入力が不正な場合は処理を中断 98 } 99 100 //Wordインスタンスを作成 101 let word = new Word(enValue, jaValue); 102 //インスタンスを配列に追加 103 list.push(word); 104 //すべてのinput要素を空欄にする 105 inputs.forEach((input) => { 106 input.value = ''; 107 }); 108 updateTable(); 109 }); 110 111 function updateTable() { 112 //見出し行を作成 113 // table.innerHTML = '<tr><th>単語</th><th>意味</th></tr>'; 114 // table.innerHTML = '<tr><td>BASIC 300</td></tr>'; 115 116 //配列から1件1件取り出しながら処理を行う(取り出した1件をwordとして扱う) 117 list.forEach((word) => { 118 //tr要素を作成 119 let tr = document.createElement('tr'); 120 //trの子要素をhtmlが含まれた文字列で設定 121 tr.innerHTML = word.showInfo(); 122 //table要素の子要素として作成したtr要素を追加 123 table.appendChild(tr); 124 }); 125 126 //total要素のテキストコンテントを設定 127 total.textContent = `${list.length}`; 128 } 129 130 131 updateTable(); 132 }; 133 </script> 134 135</body> 136 137</html>

今のコード。88~102、124,125が追加されてます。

html

1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>単語帳</title> 8</head> 9 10<body> 11 <h1>プログラミング必須英単語600+</h1> 12 <input type="text" placeholder="単語"> 13 <input type="text" placeholder="意味"> 14 <button id="btn">登録</button> 15 <p id="total">全0件</p> 16 <table id="table"> 17 <tr> 18 <th>単語</th> 19 <th>意味</th> 20 </tr> 21 <tr> 22 <td colspan=2 id="class">BASIC 300</td> 23 </tr> 24 </table> 25 26 27 <style> 28 h1 { 29 font-family: "Yu Gothic"; 30 } 31 32 /*idにテーブルがついている要素*/ 33 #table { 34 /* テーブルの境界線を重ねて表示し、隣接するセルの境界線を1本にまとめる */ 35 border-collapse: collapse; 36 } 37 38 /*td要素とth要素*/ 39 td, 40 th { 41 /*1px実践の罫線(色は#333)*/ 42 border: 1px solid #333; 43 /*上下0 左右10pxのパディング*/ 44 padding: 0 10px; 45 /*テキストを中央揃えにする */ 46 text-align: center; 47 } 48 49 th { 50 background: #0000ff; 51 /*文字色を白に設定*/ 52 color: white; 53 } 54 55 #class { 56 background: pink; 57 } 58 </style> 59 60 61 <script> 62 'use strict'; 63 64 //文書が読み込み終わったら処理を実行 65 window.onload = () => { 66 class Word { 67 //コンストラクター 68 constructor(en, ja) { 69 this.en = en; 70 this.ja = ja; 71 } 72 73 //メソッド 74 showInfo() { 75 return `<td>${this.en}</td><td>${this.ja}</td>`; 76 } 77 } 78 79 //input要素をNodeListとして取得 80 const inputs = document.querySelectorAll('input'); 81 //セレクタをもとに要素を取得 82 const btn = document.querySelector('#btn'); 83 const total = document.querySelector('#total'); 84 const table = document.querySelector('#table'); 85 86 //空の配列を準備 87 let list = []; 88 89 //localStorageからwordsというキーがついた項目を取得 90 const loadData = localStorage.getItem('words'); 91 92 //データがあれば 93 if (loadData !== null) { 94 //取得したJSON形式のデータをオブジェクトの配列に変換 95 const words = JSON.parse(loadData); 96 //配列から1件ずつwordとして取り出す 97 words.forEach((word) => { 98 //listにWordインスタンスを追加 99 list.push(new Word(word.en, word.ja)); 100 }); 101 updateTable(); 102 } 103 104 //btnにクリックイベントを登録 105 btn.addEventListener('click', () => { 106 // 入力値を取得(前後についた無駄なスペースを除去) 107 const enValue = inputs[0].value.trim(); 108 const jaValue = inputs[1].value.trim(); 109 110 if (enValue === '' || jaValue === '') { 111 alert('単語と意味を両方入力してください。'); 112 return; // 入力が不正な場合は処理を中断 113 } 114 115 //Wordインスタンスを作成 116 let word = new Word(enValue, jaValue); 117 //インスタンスを配列に追加 118 list.push(word); 119 //すべてのinput要素を空欄にする 120 inputs.forEach((input) => { 121 input.value = ''; 122 }); 123 updateTable(); 124 //配列の単語リストをJSON形式に変換し、localStorageに保存 125 localStorage.setItem('words', JSON.stringify(list)); 126 }); 127 128 function updateTable() { 129 //見出し行を作成 130 // table.innerHTML = '<tr><th>単語</th><th>意味</th></tr>'; 131 // table.innerHTML = '<tr><td>BASIC 300</td></tr>'; 132 133 //配列から1件1件取り出しながら処理を行う(取り出した1件をwordとして扱う) 134 list.forEach((word) => { 135 //tr要素を作成 136 let tr = document.createElement('tr'); 137 //trの子要素をhtmlが含まれた文字列で設定 138 tr.innerHTML = word.showInfo(); 139 //table要素の子要素として作成したtr要素を追加 140 table.appendChild(tr); 141 }); 142 143 //total要素のテキストコンテントを設定 144 total.textContent = `${list.length}`; 145 } 146 147 updateTable(); 148 }; 149 </script> 150 151</body> 152 153</html>

gitデータはGitHubで送れますか?その場合htmlファイルだけで良いんですか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lhankor_Mhy

2024/10/25 03:16

> 97行目のwordはクラスのものとは別ですよね? 「そうですね」という回答でいいでしょうか? ダメなのであればもう少し疑問点を詳しく書いた方がいいかもしれません。
zawber

2024/10/25 07:04

確かに
quickquip

2024/10/25 07:10

「『ローカルストレージ』とはなんですか? どういうものですか?」の方が質問/タイトルとしてふさわしいように感じていて、"ブラウザ ローカルストレージ"で検索して分からないところを質問するのがよいのかな、とも思います
Lhankor_Mhy

2024/10/25 07:31

質問の編集を拝読。 どの部分について面食らっているのかがわかりませんでした。 (というか、あなたが書いたコードではないのですか?) list.push(new Word(word.en, word.ja)); と let word = new Word(enValue, jaValue); list.push(word); の書き方が違うのはなぜか、前者は直接引数に渡しているのに後者は一度変数に入れている理由はあるのか、みたいな話をしてますか? もう少し具体的に何に違和感があるのか書けますか?
Lhankor_Mhy

2024/10/25 08:12 編集

> 92~102行をコメントにして実行したら以降のようになりました。 > 驚いたのは、コメントにしない場合と同じ結果だった事です その部分はローカルストレージに係る出力の部分なので、削除してもローカルストレージに係る出力以外は同じ結果になるだろうと思います。 スクリーンショットはローカルストレージの中身を見ていると思いますが、ここの値を取り出して出力をするコードをコメントアウトしただけなので、ローカルストレージには普通に保存される、ということです。
zawber

2024/10/25 08:30

というか。表には3件表示で良いんですよ。 驚いたいうのはコメントにしなくても同じではプログラムが成立しない為です。 ぶっちゃけ自分で使うのでnullじゃなかったらとか要らんねん。
juner

2024/10/25 08:38 編集

> ぶっちゃけ自分で使うのでnullじゃなかったらとか要らんねん。 いや、手動で localStorage に初回設定するのは非常にめんどいのでは……?(初回にエラーで動作しないってことですよね? loadData が null だと words がnullになるのでforEach の実行にエラーとなって、つまりクリックイベントの登録と初回再表示されないのでは……? 初期値入れればいいよねなのはそう。 ```js const loadData = localStorage.getItem('words') ?? '[]'; ```
Lhankor_Mhy

2024/10/25 08:42 編集

> 驚いたいうのはコメントにしなくても同じではプログラムが成立しない為です はい。ですので、同じ結果になるのは部分的なので特に驚くにはあたらない、というのが先ほどのコメントです。 疑問点についてこれ以上の表現は無理、とのことでしたが、これで解消できましたでしょうか? もしまだ何かある場合はもう少し表現を頑張っていただくか、別の回答者をお待ちください。
zawber

2024/10/25 08:46

エラーメッセージは出ていないです。
Lhankor_Mhy

2024/10/25 08:54 編集

見返してみると、典型的なXY問題のように感じますね。 https://zenn.dev/yoppe/articles/d25e7009759c2a コードを動かしてみると登録した単語が何度も表示されているので、そのあたりが想定されていない動作なんじゃないかと思います。 なので、X「登録した単語が何度も表示されるのを直したい」と聞けばいいのですが、「word のスコープが怪しいと思う」という推測を元に、Y「97行目のwordはクラスのものとは別ですよね?」と聞いてしまっているのがバッドコミュニケーションの原因かもしれません。 とりあえず、ご自身の感じている問題を整理してみてはどうでしょうか。 あと、もし上記のとおりであるなら、130行をコメントアウトしたことあたりに原因があるのかもしれませんね。
juner

2024/10/25 09:01

> これは要るんだろうかと思い92~102行をコメントにして実行したら以降のようになりました。 > 驚いたのは、コメントにしない場合と同じ結果だった事です。 これはどの様に予想していてたのかとても気になります。 (localStorage に設定されていたら初期値として設定するコードですよね?
juner

2024/10/25 09:02

@Lhankor_Mhy 上記で 明示されている 元のコードでも発生しているので 単に table の追加しているであろう行を削除していないから?感あります。
juner

2024/10/25 09:05

一度考えを纏めて質問文に反映した方がいいやつですね……。
zawber

2024/10/25 09:08

97行目のwordはクラスのものとは別ですよね? は例であって流れが分からないって書いてあるじゃないですか。 130行はまずいですか?
juner

2024/10/25 09:12

`table.innerHTML = ...` でやっているのは table の内部のhtml として設定するって話です。なので、これによってtable 内の再描画前のクリーニング処理もやっているということです。 131行目で130行目で設定したものを更に新たな値で上書きしているので 130行目の表示を見ることはないってだけなので131行目の `=` を `+=` (※非推奨)にして既に設定されたものに結合するか、 予め文字列を結合して設定すればいいかと思われます。
Lhankor_Mhy

2024/10/25 09:21

> 130行はまずいですか まずいかどうかは、問題がなんであるかによりますよ……
Lhankor_Mhy

2024/10/25 09:22

正しい動作はあなたの頭の中にしかないのですから、しっかり表現してください。
zawber

2024/10/25 09:41

あの~ここにコードやスクリーンショットは載せれますか?
juner

2024/10/25 09:46 編集

ここの方針的には 質問文を更新してやるべきだと思います。(考えを纏める為にも(やったこととして追記するといいと思います。 コード載せるだけなら livecodes.io とか codepen.io とかに 転記して URL 載せるでもいいと思います。 (livecodes.io は URLにソースコードが含まれるので登録不要です。右上のメニューから share で共有メニュー表示して GetShortURL で短縮URLも取得できるので私はそれを共有しています。 画像は質問文に添付機能あるのでそっちでやったほうがいいです。
zawber

2024/10/25 23:39

文字数が限界なので続きの質問を立てます。 よろしければ見てやって下さい。
guest

回答1

0

ベストアンサー

> words.forEach((word) => {

の「word」はwords内にある要素を一時的にうける変数

list.push(new Word(word.en, word.ja));

の「new Word」のwordは先頭が大文字なので外側で宣言されたWordクラスのこと
そのなかのword.enやword.jaは小文字なのでforEachで取り出されたword変数に設定されたオブジェクト(?)

参考

たとえばこれ

javascript

1class hoge{}; 2[1,2,3].forEach(hoge=>{ 3 console.log(hoge); 4});

とか

javascript

1class hoge{}; 2[1,2,3].forEach(fuga=>{ 3 console.log(new hoge); 4});

は大丈夫ですが、こうはできない

javascript

1class hoge{}; 2[1,2,3].forEach(hoge=>{ 3 console.log(new hoge); 4});

投稿2024/10/25 07:00

編集2024/10/25 07:05
yambejp

総合スコア116835

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zawber

2024/10/25 07:15

const words = JSON.parse(loadData);は外では宣言されてないのでif内のみで有効なんでしょうか?
yambejp

2024/10/25 07:25

たとえば if(true){ const hoge=1; } console.log(hoge);//エラー になるとおりifブロック内で宣言したものは外であとから参照することはできません ただしvarのように宣言が有効なものがあるので注意が必要です if(true){ var hoge=1; } console.log(hoge); ※これはwindow.hogeに1を入れているので外側にまでデータが引き継がれる
zawber

2024/10/25 08:11

今回のケースはどうですか? 有効でも無効でもどうしたら良いか分かりませんが
yambejp

2024/10/25 08:15

ifブロックでconstで宣言していれば持ち出せません。 ちょっと今回のソースは微妙(というかバグってる)なので もうすこしリファクタリンした方がよい気がします
zawber

2024/10/25 08:38

3カ月目の者としては荷が重いです。 元がバグだったら困ります。
zawber

2024/10/25 23:40

文字数が限界なので続きの質問を立てます。 よろしければ見てやって下さい。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問