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

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

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

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

iframe

HTMLのタグ<iframe>です。<iframe>は、ドキュメント内に""inline frame""を作るHTML要素で、同じページでセパレートしているドキュメントが表示されるようにします。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

4回答

8147閲覧

iframeの中へjqueryで動的追加した要素のクリックをトリガーにイベント発火させたい

alberorana

総合スコア52

HTML5

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

iframe

HTMLのタグ<iframe>です。<iframe>は、ドキュメント内に""inline frame""を作るHTML要素で、同じページでセパレートしているドキュメントが表示されるようにします。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2019/03/14 02:09

編集2019/03/14 03:07

スマートフォンUIのまま編集できるWYSIWYGエディタを開発しています。
要件的な問題で iframeの中へ動的にボタンを追加し、 追加したボタンをクリックすると発火するような仕組みを開発しています。
その際にどうしても発火しないのですが、解決策をご存知ではないでしょうか?

コードとしては、まずiframeがあり、iframe中のsectionsに対して、 <label>ラベル</label> を付与しています。

javascript

1 //非表示ラベルの付与 2 $('#edit-iframe').contents().find('section').each(function(i) 3 { 4 if($(this).attr('class')!='js-no-hidden') 5 { 6 $(this).append(`<label class="js-section-hidden js-remove-element hidden-btn" data="section-${i}">このエリアを非表示にする</label>`); 7 } 8 });

そして、 js-section-hiddenクラスに対して、クリックファンクションを設定しておりますが、発火せず、

javascript

1$('#edit-iframe').contents().find('.js-section-hidden').on('click', function(e) { 2 alert('test'); 3});

おそらく動的に追加した要素なので、 .on('click', クラス名, function(e) { とする必要があり、 $('#edit-iframe').contents().find('.js-section-hidden').on('click',$('#edit-iframe').contents().find('.js-section-hidden'), function(e) { このようにしてみたのですが、うまく行かなかったため行き詰まっています。

この問題の解決策をご存知の方がいらっしゃいましたら、ご回答いただけますと幸いです。

同じシステム(ドメイン)の /example/ID/ID をiframeのsrcにしています。

php

1<!--{layout_header}--> 2<link href="/sass/css/edit.css" rel="stylesheet"> 3<link href="/css/huebee.css" rel="stylesheet"> 4<script> 5 window.vars = []; 6 window.user = <?= $json_user ?> ; 7 window.templateId = <?= $user['template_id'] ?> ; 8</script> 9<!--{/layout_header}--> 10 11<!--{layout_footer}--> 12<script src="/plugins/jQueryUI/jquery-ui.min.js"></script> 13<script src="/js/HP/edit.js"></script> 14 15 16<a href="/view/<?= $this->current_user->id ?>" class="mb10" style="display: block;" target="_blank">実際のページを確認</a> 17 18<button class="js-edit-submit save-button">保存 <br><i class="fas fa-save mt5"></i></button> 19<button class="js-edit-section section-button">パーツ<br> 追加 <br><i class="fas fa-save mt5"></i></button> 20 21<? if($source): ?> 22 <iframe src="/view/<?= $user['id'] ?>" width="99%" height="80%" class="js-iframe" id='iframe' device="pc"></iframe> 23 <iframe src="/view/<?= $user['id'] ?>" width="99%" height="80%" id='edit-iframe' device="pc" contenteditable="true"></iframe> 24<? else: ?> 25 <iframe src="/example/<?= $user['template_id'] ?>/<?= $user['id'] ?>" width="99%" height="80%" class="js-iframe" id='iframe'device="pc"></iframe> 26 <iframe src="/example/<?= $user['template_id'] ?>/<?= $user['id'] ?>" width="99%" height="80%" id='edit-iframe' device="pc" contenteditable="true"></iframe> 27<? endif; ?>

edit.js

1var protocol = location.protocol; 2var url = location.host; 3window.editingDom = null; 4 5//要素の中身変更 6$(window).on("load", function(){ 7 $('#edit-iframe').contents().find('head').append('<link rel="stylesheet" href="/sass/css/edit-iframe.css" type="text/css" />'); 8//保存ボタン 9$(document).on("click", ".js-edit-submit", function () { 10 //画像変更だけした場合の対策 11 //初回に文言だけ変更して保存した場合の分岐 12 console.log(window.editingDom); 13 if(window.editingDom) 14 { 15 if(window.editingDom.prop('tagName') != 'img') 16 { 17 var childVar= {'html_id': window.editingDom.attr('id'), 'content': window.editingDom.html(), 'image_flag': '0'}; 18 console.log('childVar'); 19 console.log(childVar); 20 window.vars.push(childVar); 21 } 22 } 23 //編集のための要素を削除してから、本番ソースにする 24 $('#edit-iframe').contents().find(".js-remove-element").remove(); 25 $('#edit-iframe').contents().find(".is-hidden").remove(); 26 $('#edit-iframe').contents().find(".js-section-hidden").each(function(i){ 27 $(this).remove(); 28 }); 29 $('#edit-iframe').contents().find(".js-section-appear").each(function(i){ 30 $(this).remove(); 31 }); 32 //bodyのcontenteditableを削除 33 var iframe = $('#edit-iframe')[0]; 34 iframe.contentDocument.body.contentEditable = false; 35 iframe.designMode = 'off'; 36 37 console.log($('#edit-iframe').contents().find('html').html()); 38 commit($('#edit-iframe').contents().find('html').html(), window.vars); 39 40 //以下編集を解除する処理 41 unEdit(); 42 //updatePreview(); 43 //window.updatePreviewImage(); 44 window.vars = []; 45 alert('保存が完了しました。'); 46 location.reload(); 47}); 48 49function commit(source,vars=null) 50{ 51 //source = source.replace( /このエリアを非表示にする/g , "" ) ; 52 //ソースコード自体を保存する処理 53 console.log(source); 54 //return false; 55 $.ajax({ 56 url:protocol + '//' + url + '/api/v1/source/commit' , 57 type: 'POST', 58 dataType: 'json', 59 data: {'source' : source}, 60 success: function(response){ 61 62 }, 63 error : function(XMLHttpRequest, textStatus, errorThrown) { 64 65 } 66 });//AJAX 67 //文言と画像をまとめてインサート 68 var i; 69 for(i=0;i<vars.length;i++) 70 { 71 console.log(vars[i]); 72 if(vars[i].content && vars[i].html_id) 73 { 74 $.ajax({ 75 url:protocol + '//' + url + '/api/v1/' + vars[i].html_id + '/commit' , 76 type: 'POST', 77 dataType: 'json', 78 data: {'content' : vars[i].content, 'image_flag': vars[i].image_flag}, 79 success: function(response){ 80 81 }, 82 error : function(XMLHttpRequest, textStatus, errorThrown) { 83 84 } 85 });//AJAX 86 }//if 87 } 88} 89 90 91 92 93 94//非表示要素の取得と適用 95$(window).on("load", function(e){ 96 //非表示要素をまとめて取得 97 $.get({ 98 url: protocol + '//' + url + '/api/v1/hiddens/get', 99 headers:{ 100 'Content-Type': 'application/json' 101 }, 102 type: 'GET', 103 dataType: 'json', 104 data:JSON.stringify(), 105 success: function(response){ 106 //セクションの数だけループ 107 $('#edit-iframe').contents().find("js-edit-window section").each(function(i){ 108 //hidden要素の数だけループし、その中で一致するものがあれば非表示要素にチェンジ! 109 console.log('hidden'); 110 for(h=0; h < response.length; h++) 111 { 112 if(($(this).attr('id')== response[h].hidden_html_id)) 113 { 114 $(this).css('opacity', '0.2'); 115 $(this).addClass('js-remove-element'); 116 $(this).find('.js-section-hidden').remove(); 117 $(this).before(`<label class="js-section-appear hidden-btn hidden-btn--appear">このエリアを表示する</label>`); 118 $(this).find('js-hidden-btn').remove(); 119 $('iframe').contents().find($(this)).hide(); 120 } 121 } 122 }); 123 }, 124 125 }); 126 $('.js-edit-window').hide(); 127 //sectionの数だけ非表示ボタンを付与 128 129}); 130//非表示要素の取得と適用ここまで 131 132 133 134//非表示決定ボタンとDBへのインサート 135// iframeRef($('#edit-iframe')).on("input", function() { 136// alert('test'); 137// }) ; 138$('#edit-iframe').contents().find('.js-section-hidden').on('click',$('#edit-iframe').contents().find('.js-section-hidden'), function(e) { 139 alert('test'); 140}); 141$('#edit-iframe').contents().find('.js-section-hidden').on("input", function() { 142 alert('aaa'); 143//$(document).on('click', '.js-section-hidden', function hiddenSection(){ 144 $(this).parent().css('opacity', '0.2'); 145 //ソースをDBにインサート前に削除対象とするためにクラス付与 146 $(this).parent().addClass('js-remove-element'); 147 hiddenAjax($(this).parent().attr('id')); 148 $(this).parent().before(`<label class="js-section-appear js-remove-element hidden-btn hidden-btn--appear">このエリアを表示する</label>`); 149 $(this).remove(); 150}); 151 152$(document).on('click', '.js-section-appear', function appearSection(){ 153 $(this).next('section').css('opacity', '1'); 154 //ソースをDBにインサート前に削除対象外とするためにクラス削除 155 $(this).next('section').removeClass('js-remove-element'); 156 hiddenAjax($(this).next('section').attr('id')); 157 $(this).next('section').append('<label class="js-section-hidden js-remove-element hidden-btn">このエリアを非表示にする</label>'); 158 $(this).remove(); 159}); 160//非表示決定ボタンとDBへのインサートここまで 161// 162//プレビュー or 編集モード切り替え 163$(".js-hp-edit").on("click", function(){ 164 state = $(this).attr('state'); 165 if(state=="preview") 166 { 167 $('#edit-iframe').show(); 168 $('#iframe').hide(); 169 $('#edit-iframe').contents().find('head').append('<link rel="stylesheet" href="/sass/css/edit-iframe.css" type="text/css" />'); 170 $('#edit-iframe').contents().find('head').append('<link rel="stylesheet" href="/sass/css/sections.css" type="text/css" />'); 171 //$('#edit-iframe').contents().find('head').append('<script src="/js/HP/edit-iframe.js" type="text/javascript" />'); 172 var iframe = $('#edit-iframe')[0]; 173 iframe.contentDocument.body.contentEditable = true; 174 iframe.designMode = 'on'; 175 $(this).html('編集中 <i class="fas fa-desktop"></i>(クリックで戻る)'); 176 $(this).addClass('hp-edit__edit--now'); 177 $(this).attr('state', 'edit'); 178 $('#edit-iframe').contents().find('article').attr('id', 'sortable'); 179 $('section').addClass('js-droppable'); 180 $('.js-edit-submit').show(); 181 $('.js-edit-section').show(); 182 //非表示ラベルの付与 183 $('#edit-iframe').contents().find('section').each(function(i) 184 { 185 if($(this).attr('class')!='js-no-hidden') 186 { 187 $(this).append(`<label class="js-section-hidden js-remove-element hidden-btn" data="section-${i}">このエリアを非表示にする</label>`); 188 } 189 }); 190 191 $(".js-add-section").each(function(i){ 192 //hidden要素の数だけループし、その中で一致するものがあれば非表示要素にチェンジ! 193 $(this).addClass('js-remove-element'); 194 $(this).before(`<label class="js-section-remove js-remove-element hidden-btn hidden-btn--appear">この要素を削除</label>`); 195 $(this).find('js-hidden-btn').remove(); 196 $('iframe').contents().find($(this)).hide(); 197 }); 198 sortable(); 199 }else{ 200 $('.js-edit-window').hide(); 201 $('.js-iframe').show(); 202 $(this).html('このページを編集する <i class="far fa-desktop"></i>'); 203 $(this).removeClass('hp-edit__edit--now'); 204 $(this).attr('state', 'preview'); 205 $('article').attr('id', ''); 206 $('.js-edit-submit').hide(); 207 $('.js-edit-section').hide(); 208 //↓ プレビューに戻した際に変更点をアップデート 209 $(".js-remove-element").remove(); 210 //window.updatePreview(); 211 //window.updatePreviewImage(); 212 //window.changeColor(); 213 } 214}); 215

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

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

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

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

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

kei344

2019/03/14 02:42 編集

コードの流れがわかりません。なるべく全体を、せめて書かれている状況が再現できるだけのHTML/JavaScriptを提示してください。(質問文は編集できますので、質問文に追記してください)
alberorana

2019/03/14 02:49

ご回答していただく立場で指摘いただきありがとうございます。相当長いですが、今から追記いたします。
guest

回答4

0

ベストアンサー

iframe側の$(document).redyに当たる部分が無い為に、iframeの子要素のイベント判定ができていないのではないかと想像します。

下記のような方法でどうでしょうか。

$('iframe').on('load', function () { $(this).contents().on('mousemove', onMouseMove); });

投稿2019/03/14 04:11

n_takapyon

総合スコア443

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

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

alberorana

2019/03/14 10:14

おっしゃるとおりの原因だったようで、 $('#edit-iframe').on('load', function () { $(this).contents().on('click', '.js-section-hidden', function(){ alert('test"); )} )} こちらのコードで無事発火することができました! ご回答ありがとうございました。
guest

0

label要素生成されてから、イベントバインドする処理になっていないように見受けられます。
今のコードデバッグして、クリックファンクション設定しているコードでfind(.’js-section-hidden’)の戻り値でlabelアイテムが取得出来てるか確認してみてはいかがでしょうか。

投稿2019/03/14 04:08

Jan

総合スコア14

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

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

0

これでどうでしょう。

js

1$('#edit-iframe').contents().find('body').on('click', '.js-section-hidden', function(e) { 2 alert('test'); 3}); // 未検証

投稿2019/03/14 03:33

kei344

総合スコア69400

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

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

alberorana

2019/03/14 03:51

ご回答ありがとうございます。 せっかくご回答いただいたのですが、どうもイベントが取れていないようで、発火しませんでした。
guest

0

ハズレかもしれませんが・・・ (その場合はすみません)

iframe の中の document オブジェクトが取得できていますか?

以下のようなコードで iframe の document オブジェクトを取得を取得して、それに対して操作するということになると思うのですが。(引数の frameRef は getElementById で取得した iframe オブジェクトです)

// iframe 内の document オブジェクトを取得。 // contentWindow は IE 用。 // contentDocument は Firefox 用。 function iframeRef(frameRef) { return frameRef.contentWindow ? frameRef.contentWindow.document : frameRef.contentDocument; }

具体例は以下の記事を見てください。

ModalPopup を別ページから非表示
http://surferonwww.info/BlogEngine/post/2013/01/27/hide-modalpopup-by-clicking-a-button-placed-in-another-page.aspx

投稿2019/03/14 02:29

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

alberorana

2019/03/14 03:50

具体例をありがとうございます。 Documentまでは取得できたのですが、その先のイベント取得ができずなので、もう少しがんばってみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問