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

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

ただいまの
回答率

90.75%

  • Angular2

    163questions

  • Angular

    78questions

動的に生成するDOM要素にイベントバインディングを割り当てたい

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,472

wizz

score 1

前提・実現したいこと

動的に生成したinputにフォーカスが当たった時にアラートを出したいと考えて入るのですが、
呼び出されません...

templateで定義した、

<button (click)="addInput()">ADD</button>


は正しく呼び出すことができるのですが、
動的に生成した、

<input type="text" (focus)="focusFunc()" />


は動作しません。

ChoromeのDeveloper Toolsで確認したところ、以下のように
なっていました。

<!-- templateで定義 -->
<button _ngcontent-c0>ADD</button>

<!-- 動的に生成 -->
<input type="text" (focus)="focusFunc()" />


イベントバインディングがそのまま表示されてしまっているので、
DOMに追加後に何か処理を行わないといけないのでしょうか?
初歩的な質問で申し訳ないのですが、アドバイスをよろしくお願い致します。

該当のソースコード

import {
  Component,
} from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
   <div id="hoge">
     <button (click)="addInput()">ADD</button>
   </div>
  `,
})

export class AppComponent {
  addInput() {
    let elm = document.getElementById('hoge');
    let divElm = document.createElement('div');
    divElm.innerHTML = '<input type="text" (focus)="focusFunc()" />';
    elm.appendChild(divElm);
  }

  focusFunc() {
    alert('focus!!');
  }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+2

動的にの意味あいにNgIfがあてはまる場合は、
以下の回答ではいかがでしょうか??
間違ってたらすいません。

import { Component } from '@angular/core';
import { NgIf } from '@angular/common';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  private show : boolean = false;

  private addInput():void{
    this.show = !this.show;
  }

  private focusFunc():void{
    alert('focus!');
  }

}
  <div class="hoge">
    <button (click)="addInput()">foo</button>
    <div *ngIf="show">
      <input
        type="text"
        (focus)="focusFunc()"
      >
     </div>

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/20 20:01 編集

    ご回答ありがとうございます。

    1つお伺いしたいのですが、
    <div *ngIf="show">...</div>
    の要素は動的に生成するのでしょうか?

    キャンセル

  • 2017/09/20 20:34

    動的に生成される意味が、
    clickのイベントでcreateElement( tagName )をし生成するですと、違うかもしれません。
    また、動的に生成がparentElementのinnerHTMLを書き換えるも入るのであれば、
    ngIfもあてはまるとと考えております。

    https://github.com/angular/angular/blob/4.4.3/packages/common/src/directives/ng_if.ts#L10-L155

    キャンセル

  • 2017/09/21 10:52

    ご回答ありがとうございます。

    私がやりたいと考えているのは、ngna様の仰る、
    "clickのイベントでcreateElement( tagName )をし生成する"
    のやり方です。

    説明がわかりにくくて申し訳ありません。
    createElementで生成した要素に設定する方法をご存知でしたらご教授いただけないでしょうか?

    キャンセル

+2

そもそもDOMをいじらないためにフレームワークを使っているので、Angularに適したアプローチに変えてください。

アプローチ例:

import {
  Component,
} from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
   <div id="hoge">
     <button (click)="addInput()">ADD</button>
     <input type="text" (focus)="focusFunc()" *ngFor="let input of inputArray">
   </div>
  `,
})

export class AppComponent {
  inputArray: boolean[];

  addInput() {
    inputArray.push(true);
  }

  focusFunc() {
    alert('focus!!');
  }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

0

TypeScriptちょっとやったことないのでできるかわからないですけど、

addEventListenerを使ってみてはどうでしょう?

// 省略
let elm = document.getElementById('hoge');
let inputElm = document.createElement('input');

inputElm.addEventListener('focus',focusFunc,false);

elm.appendChild(inputElm);
// 省略

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/20 18:43

    ご回答ありがとうございます。

    ご提案して頂いた方法を試してみましたが、
    focusFuncは呼び出されませんでした...
    TypeScriptの場合は何か特別な処理が必要なのでしょうか...

    キャンセル

  • 2017/09/20 18:54

    実はfocusイベントなのにも関わらずdivにイベントを足していたので慌てて(18:30に)コードを編集したのですが、現在のコードでもダメでしょうか?

    キャンセル

  • 2017/09/20 19:36

    ご回答ありがとうございます。
    変更後のコードを試したところ、動作しました!
    ありがとうございました!!

    キャンセル

0

focus時にalertだすとfocusが外れてしまいますがよろしいのでしょうか?
※動的な追加の部分も念の為かいておきます

HTMLElement.prototype.focusFunc=function(){
  alert("fucus!");
}
document.addEventListener('focus',function(e){
  var t=e.target;
  if(t.nodeName=="INPUT" && t.type=="text"){
    t.focusFunc();
  }
},true);
document.addEventListener('click',function(e){
  var t=e.target;
  if(t.nodeName=="INPUT" && t.type=="button" && t.value=="add"){
    var n=document.createElement('input');
    n.setAttribute("type","text");
    t.parentNode.appendChild(n);
  }
});
<div>
<input type="button" value="add">
</div>

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/20 18:50

    ご回答ありがとうございます。
    HTMLElement.prototype.focusFunc...のところで
    ” Property 'focusFunc' does not exist on type 'HTMLElement'. ”
    というエラーがでてしまいました。

    原因を調査しながら、もう少し調べてみます!

    キャンセル

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

  • ただいまの回答率 90.75%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Angular2

    163questions

  • Angular

    78questions