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

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

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

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

Q&A

解決済

3回答

3448閲覧

jsで独自データ属性の値を取り出す処理について教えて下さい。

退会済みユーザー

退会済みユーザー

総合スコア0

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

0グッド

0クリップ

投稿2015/11/14 11:32

要素にホバーするとその要素が持つ独自データ属性の値を取り出す処理を作っています。
アイコン要素に各独自データ属性を付け、hoverfuncというクラスを付けて、イベントを呼び出します。
そこで5つの星の内、左から2番めの星をホバーした時だけnullになってしまうのですが、何故だか教えて下さい。
よろしくお願いします。

html

1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4 <meta http-equiv="Content-type" content="text/html; charset=UTF-8" /> 5 <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet"> 6 <title>teratail</title> 7 </head> 8 <style type="text/css"> 9 .fa { 10 font-size: 40px; 11 color: #FACC2E; 12 } 13 .star-content { 14 position: relative; 15 width: 200px; 16 height: 50px; 17 background-color: #fafafa; 18 } 19 .position2-1,.position2-2,.position2-3,.position2-4,.position2-5 { 20 position: absolute; 21 color: #BDBDBD; 22 } 23 .position2-1 { 24 top: 0; 25 left: 0%; 26 } 27 .position2-2 { 28 top: 0; 29 left: 20%; 30 } 31 .position2-3 { 32 top: 0; 33 left: 40%; 34 } 35 .position2-4 { 36 top: 0; 37 left: 60%; 38 } 39 .position2-5 { 40 top: 0; 41 left: 80%; 42 } 43 </style> 44 <body> 45 <div class="star-content"> 46 <i class="fa fa-star-o position2-1 hoverfunc" data-num="1"></i> 47 <i class="fa fa-star-o position2-2 hoverfunc" data-num="2"></i> 48 <i class="fa fa-star-o position2-3 hoverfunc" data-num="3"></i> 49 <i class="fa fa-star-o position2-4 hoverfunc" data-num="4"></i> 50 <i class="fa fa-star-o position2-5 hoverfunc" data-num="5"></i> 51 </div> 52 </body> 53 <script type="text/javascript"> 54 window.addEventListener('load', function(){ 55 56 for(var i=0; i < document.getElementsByClassName('hoverfunc').length; i++){ 57 document.getElementsByClassName('hoverfunc')[i].addEventListener('mouseover', function(evn){ 58 alert(evn.target.getAttribute('data-num')); 59 },false); 60 } 61 }); 62 </script> 63</html>

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

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

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

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

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

guest

回答3

0

以下のコードを実行して、コンソールを確認します。

html

1<!DOCTYPE HTML> 2<html lang="ja-JP"> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <span id="dom" data-example='1'>dom</span> 9 </body> 10 <script type="text/javascript"> 11 var dom = document.getElementById('dom'); 12 dom.addEventListener('mouseover', function (evn) { 13 console.log(evn); 14 }, false); 15 </script> 16</html>

イメージ説明

すると、target > attributes > 0 > nodeName に data-example
target > attributes > 0 > nodeValue に 1 が入っていることが確認できるので、以下のようなコードでアクセスすることができるとわかります。

html

1<!DOCTYPE HTML> 2<html lang="ja-JP"> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <span id="dom" data-example='1'>dom</span> 9 </body> 10 <script type="text/javascript"> 11 var dom = document.getElementById('dom'); 12 dom.addEventListener('mouseover', function (evn) { 13 var attr = evn.target.attributes; 14 for (var i = 0; i < evn.target.attributes.length; i++) { 15 if (attr[i].nodeName == 'data-example') { 16 console.log(attr[i].nodeValue); 17 } 18 } 19 }, false); 20 </script> 21</html>

また、target 以下に method も見ることができます。
イメージ説明
すると、getAttribute() というメソッドがあるので、evn.target.getAttribute()でアクセスできそうです。以下のコードォ実行します。

html

1<!DOCTYPE HTML> 2<html lang="ja-JP"> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <span id="dom" data-example='1'>dom</span> 9 </body> 10 <script type="text/javascript"> 11 var dom = document.getElementById('dom'); 12 dom.addEventListener('mouseover', function (evn) { 13 var val = evn.target.getAttribute(); 14 console.log(val); 15 }, false); 16 </script> 17</html>

イメージ説明

TypeError: Not enough arguments to Element.getAttribute.

Not enough arguments -> 「引数が充分じゃない」とのことなので、

html

1<!DOCTYPE HTML> 2<html lang="ja-JP"> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <span id="dom" data-example='1'>dom</span> 9 </body> 10 <script type="text/javascript"> 11 var dom = document.getElementById('dom'); 12 dom.addEventListener('mouseover', function (evn) { 13 var val = evn.target.getAttribute('data-example'); 14 console.log(val); 15 }, false); 16 </script> 17</html>

すると…でた!

イメージ説明

こんな感じで、「開発ツール」と仲良くすると、いいことあります。

投稿2015/11/14 13:11

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2015/11/14 18:03

ありがとうございます。ブラウザツールの使い込みが甘く、原因の特定ができませんでした。いつもchromeのデベロッパツールを使っているのですが、他ブラウザのデベロッパツールはDOMをここまで細かく辿れるんですね。驚きました。 載せて頂いた上記の画像で使用しているデベロッパツールはfirefoxではないようですが、どのブラウザのものですか? 使ってみたいので教えて下さい。
guest

0

ベストアンサー

そこで5つの星の内、左から2番めの星をホバーした時だけnullになってしまうのですが、何故だか教えて下さい。

そのコードでそうなる事はありません(再現できません)が、getAttribute() は対象の属性が存在しない場合に null を返す仕様ですので対象の要素ノードが data-num 属性を持っていないのでしょう。
null を返す時の「対象の要素ノード」を console.log や breakpoint で確認してみて下さい。

getElementsByClassName を何度も呼ぶのは効率が悪いので書き直してみました。

(2015/11/14 22:23追記)
あくまで可能性ですが、i 要素内に別の要素が挿入された場合には event.target<i> でなくなる為、再現可能です。
実際には別のスクリプトが入っていて影響している可能性がありそうです。

投稿2015/11/14 13:15

編集2015/11/14 13:23
think49

総合スコア18156

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

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

退会済みユーザー

退会済みユーザー

2015/11/14 17:03

>null を返す時の「対象の要素ノード」を console.log や breakpoint で確認してみて下さい。 これからは対象のノードをブラウザツールを使ってnodeNameにdata-num属性を持っているか確認してみます。デバッグツールの使い込みが甘かったです。 >あくまで可能性ですが、i 要素内に別の要素が挿入された場合には event.target が <i> でなくなる為、再現可能です。 質問する前の未添削のコードでは<i>の中に別の要素は入れていませんでした。 また、シンプルな実行環境でテストしたため、他のスクリプトは使用していません。
退会済みユーザー

退会済みユーザー

2015/11/14 17:28

コード訂正していただき感謝致します。 いただいたコードの方がシンプルでスマートでいいですね。 ひとつ気になったのですが、 event.target.querySelector('.star-content').addEventListener('mouseover', function (event) { var li = event.target; のところで、event.targetが<i>要素を指すのは何故ですか? targetは発火元となった要素を返すものであるはずですから、この場合「ホバーした要素」つまりstar-contentを指すと思うのですが。 不思議なので教えて下さい。
退会済みユーザー

退会済みユーザー

2015/11/14 17:35

失礼しました。 var li = event.target.className; console.log(li); で確認した所、結果がstar-contentでした。すみません。 不思議なのはそこではなくて、<div class="star-content">を2つ作り、 var li = event.target.className; console.log(li); を実行すると、1つ目のstar-contentクラスの要素にホバーした時にしか結果を返さないのですが、何故だか教えて下さい。
退会済みユーザー

退会済みユーザー

2015/11/14 17:58

元々このコードを書こうと思った目的は、評価項目に対する星形の評価UIだったので、 星のグループ(☆アイコン1〜5を包括したdiv要素star-content)をいくつも作りたかったのです。 一つ上のコメントへの補足です。 querySelectorはクラスを指定しても最初に出現した要素しか返さないんですね。 querySelectorAllで対応し、以下のコードで複数の星のグループにも対応出来ました。 for(var i=0; i < event.target.querySelectorAll('.star-content').length; i++){   event.target.querySelectorAll('.star-content')[i].addEventListener('mouseover', function (event) {   var li = event.target;     if (li.classList.contains('hoverfunc')) {       console.log(li.getAttribute('data-num'));     }   }, false); } 先が見えてきました。本当に有難うございます。
think49

2015/11/15 00:40

To: morikz さん > targetは発火元となった要素を返すものであるはずですから、この場合「ホバーした要素」つまりstar-contentを指すと思うのですが。 .star-content を返すのは event.currentTarget ですね。 mouseover した際の event.target は「mouseover されている要素ノード」を返します。 つまり、div もしくは i 要素ノードを返すはずです。 div要素ノードは [data-num] を持たない為、.hoverfunc な要素になるよう classList で限定しています。 (ちなみに、classList のコードを削除すると event.target が div 要素ノードになる場合に getAttribute() は null を返します。) > querySelectorAllで対応し、以下のコードで複数の星のグループにも対応出来ました。 動作的には問題ありませんが、querySelectorAll を何度も呼んでいる事と .star-content の数だけ無名関数を生成している点で非効率ですね。 同じ対象を何度も参照する場合は変数にキャッシュする事をお勧めします。 http://jsfiddle.net/jodfynpa/2/
guest

0

うちのローカル環境にコピペして動かしてみたら、
ちゃんと2のアラートが出ましたよ。
ブラウザキャッシュが効いてないか等の確認をお願いします。

投稿2015/11/14 12:35

miyabi-sun

総合スコア21158

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

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

退会済みユーザー

退会済みユーザー

2015/11/14 16:50

ありがとうございます。実は質問する前に分かりやすいよう、コードを添削していたんですが、どういうわけか質問に使用したコードをコピペしたら期待通りの動きしました・・・。 chromeのキャッシュも削除し暫く添削前のコードで実行してたのですが、結局nullでした。 これまたどういうわけか時間を置いてコピペしたコードを動かしたら無事うごきましたね。 原因不明で腑に落ちませんが、実行くださってありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問