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

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

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

Riot.jsは、React.jsに似たコンポーネント指向なJSフレームワークです。非常に軽量であり、コンポーネントで設計しやすいといったメリットがあります。また、MVCのように分割できることも特徴です。

Q&A

解決済

1回答

3580閲覧

【Riot.js】カスタムタグファイルに定義したselectのchangeイベントを独立させたい

nnahito

総合スコア2004

Riot.js

Riot.jsは、React.jsに似たコンポーネント指向なJSフレームワークです。非常に軽量であり、コンポーネントで設計しやすいといったメリットがあります。また、MVCのように分割できることも特徴です。

0グッド

0クリップ

投稿2016/12/14 17:11

質問

Riot.jsのカスタムタグファイルに定義した、selectのchangeイベントを、
独立させたいのですが、そのやり方が分かりません。

例えば、以下のカスタムタグを定義したとします。
※selectには、materializeを利用しています。

tag

1<mytag> 2 3 <div> 4 <select> 5 <optgroup label="term 1"> 6 <option value="3" selected="{opts.select == '3'}">opt1</option> 7 <option value="2" selected="{opts.select == '2'}">opt2</option> 8 <option value="-1" selected="{opts.select == '-1'}">opt3</option> 9 </optgroup> 10 <optgroup label="term 2"> 11 <option value="1" selected="{opts.select == '1'}">opt4</option> 12 <option value="0" selected="{opts.select == '0'}">opt5</option> 13 </optgroup> 14 </select> 15 </div> 16 17 18 19 20 <script> 21 this.on('update', function() { 22 $('select').material_select(); 23 }); 24 25 this.on('mount', function() { 26 $('select').material_select(); 27 }); 28 29 $("select").change(function(){ 30 var $text = $(this, "option:selected").val(); 31 alert($text); 32 }); 33 34 35 </script> 36 37 38 39</mytag> 40

これをHTML側で、

html

1<mytag></mytag> 2<mytag></mytag> 3<mytag></mytag>

と、3回呼び出したとすると、
3つのselectボックスが生成されます。(以下の図)


イメージ説明

Firefox 50.0.2 で確認したところ、

一つ目のselectボックスの選択を変更すると、
2回alertが表示され、

2つ目のselectボックスの選択を変更したところ、
1回alertが表示され

3つ目のselectボックスの選択を変更したところ、
alertは表示されませんでした。


それぞれの処理を独立させようと、
tagファイルの中のJavaScript

javascript

1$("select").change(function(){ 2 var $text = $(this, "option:selected").val(); 3 alert($text); 4});

を書いたのですが、うまく行っておりません。

この表記は間違っているのでしょうか?
間違っているとして、正解はどうなのでしょうか?

ご存じの方がいらっしゃいましたら、ご教示頂けると幸いです。
よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

一つ目のselectボックスの選択を変更すると、
2回alertが表示され、

2つ目のselectボックスの選択を変更したところ、
1回alertが表示され

3つ目のselectボックスの選択を変更したところ、
alertは表示されませんでした。

後述するので訂正しておきます。
3つ目のselectは1つ目のtagから生成されたDOMです。

JavaScript

1$("select").change(function(){ 2 var $text = $(this, "option:selected").val(); 3 alert($text); 4});

このトリガーは既存のDOMに対してセットするものになります。
恐らく、タグからDOMを生成した際にscriptが先に走り対象となるDOMが存在しない為、
何も発生しないのでしょう。

2回3回と生成するとトリガーが重複して、
3個目のtagから生成したDOMには2個のトリガーが存在するので、
2回のアラートが表示されることが考えられます。

対処法として2点あり、tagを埋め込んでいるHTMLで
以下のトリガーをセットしてあげる。

JavaScript

1$(document).on('change', 'select', function() { 2 var $text = $(this, "option:selected").val(); 3 alert($text); 4});

これはdocument要素のselectに対してのトリガーになるので、
後から要素を追加してもこのトリガーが呼ばれます。

2つ目はtag内で以下を記述する。

JavaScript

1this.on('mount', function() { 2 $('select').off().on('change', function() { 3 var $text = $(this, "option:selected").val(); 4 alert($text); 5 }); 6});

これは一度セットしたトリガーを削除して新たに設定する
無理やりで汚いですが、多分動きます。
注意するのはmountだったりupdateの中に書かないと、
1個だけtagを生成した場合、イベントは発生しません。

投稿2016/12/15 04:17

mukkun

総合スコア882

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

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

nnahito

2016/12/15 09:21

ご回答ありがとうございます。 無事動きました。 >注意するのはmountだったりupdateの中に書かないと、1個だけtagを生成した場合、イベントは発生しません なるほど、覚えておきます。 >$('select').off().on これなのですが、selectに有るイベントを一度全部キャンセルしてから、changeイベントを発火させているということでしょうか?
mukkun

2016/12/15 09:37

一度全部キャンセルではなく、 すでに存在する要素のイベントハンドラーを削除後、 メソッドチェーンでselectに対し新たにイベントハンドラーを定義するという意味になります。
nnahito

2016/12/15 13:41

ご回答ありがとうございます。 >すでに存在する要素のイベントハンドラーを削除後、 >メソッドチェーンでselectに対し新たにイベントハンドラーを定義する つまり、 (1)セレクトにより発火したイベントを一旦削除 (2)新しく、セレクトのイベントを発火 と言うかたちでしょうか? 語句を理解していなくて申し訳ありません……
nnahito

2016/12/15 16:54

ご返信ありがとうございます。 なんとなくですが、理解できました! ありがとうございます! もっと勉強していきたいと思います。 ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問