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

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

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

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

HTML

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

Q&A

解決済

3回答

921閲覧

JavaScriptでリスト要素に対して同じ動作をする関数を書く

Yhaya

総合スコア439

JavaScript

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

HTML

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

0グッド

0クリップ

投稿2019/03/23 00:52

編集2019/03/23 04:23

環境

  • Google Chrome

やりたいこと

HTML中のリスト要素に対して、JavaScriptで定義した動作を実行したいと考えています。

イメージ的に近いのは、Twitterで、各ツイートには右上に下向きの矢印がついていて(下図の赤丸内)それをクリックすると、そのツイートをコピーしたりブロックするためのメニューが並ぶと思いますが、このように、リストをクリックするとそのリストに対して処理を行いたいと思っています。
Twitter Yahoo!ニュースのTweetから引用
このとき重要だと思っているのが、Twitterの例を使って説明すると、どのリストをクリックしても出てくるメニュー(コピーやブロック、ミュート)は同じになってほしいが、ブロックをクリックしたときには、そのリストのみに対して処理を実行したいということです。

どこまでできていて何がわからないか

いくつか頂いた回答を参考に、以下のところまでは理解できています。

例えば、

html

1<ul> 2 <li class="test" id="test1"><span>abc</span></li> 3 <li class="test" id="test2"><span>def</span></li> 4 <li class="test" id="test3"><span>ghi</span></li> 5</ul>

というリストを考えて、

javascript

1(function(){ 2 // とりあえずclass名がtestのものを全部取り出す 3 var element = document.getElementByClassName("test"); 4 5 for (var i = 0; i < element.length; i++){ 6 /* クリックされたリスト要素のidと一致するものを探索してメニューを出す */ 7 } 8})();

で動作を定義しました。

コードのコメントアウトしてある部分で、「クリックされたリスト要素のidと一致するものを探索」する部分をどう書いてよいのかがわかりません。

初心者でよくわかっていないのですがよろしくお願いします。

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

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

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

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

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

guest

回答3

0

ベストアンサー

要件定義

質問の中で要件が曖昧で伝わってきません。

それぞれの要素に対して例えば、文字を変更するという動作をJavaScriptで書いた場合、

それらの処理は固有処理として定義しますか。同一処理として単一関数を定義しますか。
固有処理ならid属性を使い、同一処理ならclass属性で同じ値を指定すれば良いのではないでしょうか。(おそらく、mts10806さんも同様の指摘をしています)

くWebページでパネルがいくつも並んでいて、それぞれをクリックするとそれぞれのパネルに対応した編集画面が出るという動作があると思うのですが、

それをもっと具体的に書いてください。
teratailでは適切な質問をする為の案内が用意されていますので、下記参照の上、質問内容を編集する事を推奨します。

下記は私が独断と偏見で質問内容を想像して、回答したものです。

Document.prototype.getElementsByClassName

getElementsByClassName の返り値は配列ではありませんが、HTMLCollectionという疑似配列を返します。
配列と同様、elements[0] のように数値添え字で参照可能なので、for 文などの繰り返し処理が使えます。

NodeList.prototype.forEach

ここでは、NodeList.prototype.forEach を使いますが、前述の getElementsByClassName を使っても構いません。

HTML

1<ul> 2 <li class="test" data-replace-text="Hello">abc</li> 3 <li class="test" data-replace-text="World">def</li> 4 <li class="test" data-replace-text="JavaScript">ghi</li> 5</ul> 6 7<script> 8'use strict'; 9document.querySelectorAll('.test').forEach(li => li.addEventListener('click', event => { 10 const li = event.currentTarget; 11 12 li.textContent = li.getAttribute('data-replace-text'); 13}, false)); 14</script>

イベントバブリング

親ノードでイベント定義する事で、イベントハンドラ処理を一つにまとめます。

HTML

1<ul id="test"> 2 <li data-replace-text="Hello">abc</li> 3 <li data-replace-text="World">def</li> 4 <li data-replace-text="JavaScript">ghi</li> 5</ul> 6 7<script> 8'use strict'; 9document.getElementById('test').addEventListener('click', event => { 10 const li = event.target; 11 12 li.textContent = li.getAttribute('data-replace-text'); 13}, false); 14</script>

テキストノード値を編集する

くWebページでパネルがいくつも並んでいて、それぞれをクリックするとそれぞれのパネルに対応した編集画面が出るという動作があると思うのですが、

編集した結果が不明ですが、Excelのような入力した結果、そのまま出力されるUIと勝手に想像します。
入力を行うには、input要素、textarea要素などの入力可能なパーツが必要です。
例えば、次の処理工程が考えられます。

  1. addEventListenerclick イベントハンドラを定義
  2. click イベントハンドラから既存のテキストノードを createElelement で生成したinput要素ノードと replaceChild を使って、入れ替える(テキストノードは変数 textNode に保存しておく)
  3. blur, submit イベント等で入力確定タイミングを捕捉
  4. 入力内容を HTMLInputElement.prototype.value で参照し、textNode.data = value でテキストノード値に代入
  5. removeChild でinput要素ノードとテキストノード(変数 textNode)を入れ替える

これまでの説明が「まるで意味が分からない」という状況であれば、まずはDOMについて学習して下さい。

更新履歴

  • 2019/03.23 12:10 「テキストノード値を編集する」節を replaceChild を使った処理工程に変更(Excel入力UI)

Re: Yhaya さん

投稿2019/03/23 02:52

編集2019/03/23 03:11
think49

総合スコア18164

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

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

Yhaya

2019/03/23 05:01

ありがとうございます。リンクも非常に参考になりました
guest

0

sample

html

1<!doctype html> 2<html lang="ja"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 </head> 7 <body> 8 <ul> 9 <li class="test"><span>abc</span></li> 10 <li class="test"><span>def</span></li> 11 <li class="test"><span>ghi</span></li> 12 </ul> 13 <script> 14 let elements = document.getElementsByClassName("test"); 15 for (let i = 0; i < elements.length; i++) { 16 elements[i].addEventListener('click', function(e) { 17 window.alert(this.getElementsByTagName('span')[0].innerText); 18 }); 19 } 20 </script> 21 </body> 22</html>

投稿2019/03/23 02:47

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

classであれば同じ名前を振ればそれでエレメントは取得できますが、メソッド名が間違ってます。
getElementsByClassName()

よく間違われますが、
classは1画面に複数振ることができるので複数系です。
上記のようなドキュメントは必ず確認しましょう(私もコピペで使います)

ただ複数系であるため、要素も配列で取得されます。例え1つしか振ってなくても配列なので注意が必要です。
取得後はforなどでループさせてそれぞれ処理を仕込むのが一般的です。
要素を取得したらその変数をconsole.log()で確認してください。正しく取れているか、何が使えるかが分かります。

投稿2019/03/23 01:06

編集2019/03/23 01:10
m.ts10806

総合スコア80850

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

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

Yhaya

2019/03/23 01:24

すみません。getElementsByClassNameは誤植です。最終的にはこのリスト要素をクリックしたときにJavaScriptが動くようにしたいのですが、test1、test2、test3のどれがクリックされたか判別するためにはJavaScript側のメソッドもリスト要素の数だけ書かなければならないのでしょうか?
m.ts10806

2019/03/23 01:52

ですから、別で同名クラスをつけてそのクラスに対してクリックイベントを付与。 あとはクリックイベント内でthisから識別できる情報を取得するように書けばメソッドは1つです。 今回はtest1とか2とかはclassよりもidの方が適切ですね。
Yhaya

2019/03/23 02:15 編集

すみません、初心者でいまいちピンときていないのですが、class名をtestで統一して、getElementsByClassNameで全部取得して、その中からid(test1やtest2)で目的の要素を探すということだと思うのですが、クリックされた要素のidがそもそもどれなのかと言うのはどうしたら取得できるのでしょうか。何もわかっていなくて申し訳ありません。
m.ts10806

2019/03/23 02:35

おおよそ理解はあってます。 あとは1つずつコードに興していく作業ですが・・・ 少々お待ちください。ざっくりコード回答に追記します。
Yhaya

2019/03/23 02:38

すみません。ありがとうございます
m.ts10806

2019/03/23 02:46

あ。あと。 >よくWebページでパネルがいくつも並んでいて、それぞれをクリックするとそれぞれのパネルに対応した編集画面が出るという動作がある これ、ものによって違います。 実際に見られたサイトのURLを質問本文に追記された方が良いかもしれません。 html、JavaScriptであればだれでもコードを追うことはできます。
m.ts10806

2019/03/23 02:58

コード、と思いましたが、既に私が書こうと思ったコードほぼそのまま別回答についたので、そちらも確認してください
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問