実現したいこと
Ajaxで動的に生成した<button>
に対して、そのdata-name
に応じたテキストを挿入したいです。
たとえばこちらの<butotn>
が生成されるのですが、
<button data-name="<!--いろんな値-->" type="button"><!--空っぽ--></button>
この「空っぽ」の部分に「いろんな値」に応じたテキストを、jQueryで挿入したいという感じです。
発生している問題
下記の【check.php】【ajax.js】【ajax.php】という流れで、Ajax後に<butotn>
が生成されるのですが、その<butotn>
のテキストが「試したこと」のjQueryでは挿入できません。
該当のソースコード
まず下記がボタンを生成する前のHTMLです。
後述のAjaxでは、このvalue
に応じたdata-name
を持つ<button>
を、チェックボックスの下に生成します。
【check.php】
<input type="checkbox" value="jon">
<!-- ここに<button>が生成される -->
<input type="checkbox" value="kelly">
<!-- ここに<button>が生成される -->
そして下記が<button>
を生成するajaxです。
【ajax.js】
$(document).on('change','input', function(){
var this = $(this)
var checkedVal = this.val();
$.ajax({
url: "ajax.php",
type: 'POST',
data: {
checkedVal: checkedVal,
}
cache: false,
success: function(button){
this.after(button);
},
error: function(xhr, textStatus, errorThrown){
alert('Error! ' + textStatus + ' ' + errorThrown);
}
});
});
さいごに下記がajaxで読まれるPHPです。
これが生成する<button>
は事情によってテキストが空っぽになっています。
なので、この<button>
の生成後に、data-name
に応じてテキストを挿入したいというのが実現したいことになります。
【ajax.php】
$checkedVal = $_POST['checkedVal'];
echo '<button data-name="'.$checkedVal.'" type="button"><!--空っぽ--></button>';
試したこと
まず「.each」が使えるかと思って下記のように試したのですが、動的に追加された要素には通用しないみたいでした。
$(document).on("each", "button", function(){
var name = $(this).attr("data-name");
if( name=='jon' ){
$(this).text('男性');
}
else if( name=='kelly' ){
$(this).text('女性');
}
});
もちろん、【ajax.js】のsuccess
の中に上の$(this).text('男性');
とかを書けばいい話ではあります。
しかしそれよりも、動的に追加された要素に「.each」を効かせるような方法があればもっと手っ取り早いと感じたので、そのような方向で質問させて頂きました。
何か不足した情報などございましたら随時ご指摘ください。
質問は以上になります。どうぞご指導宜しくお願い申し上げます。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
- メールアドレスの認証
メールアドレスの認証
- 質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+2
jqueryメソッドを拡張ちて、カスタムイベントを登録したでちゅ。
(function()
{
// ajaxエミュレーション用データ
var idx = 0;
var key = ["aaa", "bbb", "ccc", "ddd", "eee"];
$(document).ready(function()
{
// buttonにカスタムイベントコールバックを定義するのでちゅ。
$(document).bind("custom-append", "button", function(e)
{
$(e.data).text( $(e.data).attr("data-name") );
});
// jQueryメソッドの拡張
var jquery_original_after = $.fn.after;
$.fn.after = function()
{
// jQueryのafterメソッドを使うと、custom-appendイベントが発生するのでちゅ。
return jquery_original_after.apply(this, arguments).trigger("custom-append");
};
// チェックボックスイベントコールバック
$(document).on("change", "input[type=checkbox]", function()
{
if(!$(this).prop("checked"))
{
$(this).siblings("button").remove();
return true;
}
// 以下、ajaxをエミュレート
var self = $(this);
setTimeout(function()
{
var button = $("<button/>").attr("type", "button").attr("data-name", key[idx++]);
self.after(button);
idx %= key.length;
}, 1000);
});
});
})();
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+2
こんにちは
ご質問にある要件を満たす方法として、指定したコールバックを DOM の変更時に実行させる、 MutationObserver を使ってみる、というのが考えられます。
以下、その使用例のサンプルです。
追加される複数のボタン全体を囲む <div>
を以下のように用意しておきます。
<div id="buttons-area"></div>
次に、上記の#buttons-area
の子ノードを検知するように、MutationObserver
を設定する関数を以下
const setupObserver = function() {
const callback = function(mutationsList, observer) {
for(var mutation of mutationsList) {
if (mutation.type == 'childList') {
const button = $(mutation.addedNodes[0]);
button.text(button.data('name'));
}
}
};
const observer = new MutationObserver(callback);
const targetNode = document.getElementById('buttons-area');
observer.observe(targetNode, { childList: true });
};
のように作っておき、これをdocument が readyになったときに使います。
$(function() {
setupObserver();
// ・・・
});
以下は、上記のサンプルです。
- 動作確認用サンプル: https://jsfiddle.net/jun68ykt/9amtjyf7/6/
このサンプルは以下のように動作します。
- チェックボックスをチェックすると、 AJAXでリクエストを送ります。(チェックを外すときはリクエストされません)
- 疑似APIっぽく見せるために、レスポンスが返されるまでに約1秒、遅延するようにしています。
- レスポンスは以下のようなHTMLです。
<button data-name="PAVCJNVQ" type="button"><!--空っぽ--></button>
- 上記で、
data-name
属性の値は、リクエストごとに生成されるランダムな英数字8文字の文字列になります。 - AJAXのsuccess時のハンドラでは、このHTMLから作られる、テキストが空のボタンを
#buttons-area
に追加します。 - ボタンが追加されると、
MutationObserver
に設定されたコールバックが呼ばれて、以下の処理
const button = $(mutation.addedNodes[0]);
button.text(button.data('name'));
が行われ、ボタンのテキストが data-name
属性の値に変更されます。
以下の画像は、チェックボックスをチェックする、外すという操作を繰り返して、3回AJAXでリクエストを送信した後に表示されるボタンと、console です。
consoleには、各AJAXによるリクエストで返されるレスポンスHTMLが表示されています。
以上、MutationObserver をお使いになってみてはいかがでしょう、というご提案の回答になります。
参考になれば幸いです。
投稿
score 3975
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
-1
別の質問に回答した通り $('button').each()
で処理すればOKでしょう。
https://teratail.com/questions/188785#reply-280264
ご記載の方法だと、documentのeachイベントの発火を待つ意味になります。そんなイベントは起きないので動きません。
投稿
score 792
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
質問への追記・修正、ベストアンサー選択の依頼
Lhankor_Mhy
2019/05/11 16:04
これ、動作します……?
Lhankor_Mhy
2019/05/11 16:52
this は予約語だから、$thisとかにしないとまともに動かないブラウザもあるんじゃないかなあ……?