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

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

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

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Q&A

解決済

1回答

1425閲覧

javascript or TypeScriptのカスタムイベント

eojvkx2

総合スコア3

JavaScript

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

0グッド

0クリップ

投稿2020/10/27 09:10

編集2020/10/28 06:36

カスタムイベントでイベントを検知する方法を教授お願いします。
ソースはこんな風にできればいいなと思い書いています。
どの様に実現するのが定石なのでしょうか。

class xxx{ //XMLHttpRequestでデータ取得 public xmldataget() { let cxhr = new Cls_Xhr let url = "http://xxx/xxx.txt" //データ受信要求 cxhr.XhrGet(url) //データ受信完了(■この様な形でイベントを受信したい!!!) cxhr.xxxonload = function(getdata){ let xxx xxx = getdata //取得したxxx.txtの内容 } } }
class Cls_Xhr { //********************************************************* //XMLHttpRequestデータ取得関数 //********************************************************* public XhrGet(url:string) { let xhr = new XMLHttpRequest() let getdata //■URLを指定 xhr.open('GET', url, true) xhr.send() //■ダウンロード完了 xhr.onload = function() { //データ取得完了 getdata = xhr.responseText //カスタムイベント作成 let evonload = new Event("xxxonload"); //イベント結び付け addEventListener("xxxonload", xxxonload.bind (ctlelm, getdata), true) //発火 dispatchEvent(evonload) } } }

戻り値が複数ある場合、detailの部分をクラス指定したいの
ですが方法はありますでしょうか。
(※VS TyepScriptでインテリセンスを使用したいためです)

const events = new CustomEvent("xxxonload", { detail: { dt : xhr.responseText, x : 100, y : 200, } }) //戻り値用のクラス class xxxOnloadEvent { public dt : string public x : number public y : number } //イベントリスナー addEventListener("xxxonload", aaakansuu.bind (evt), true) //イベント受信関数 //★★evt:xxxOnloadEventと型を指定したいです!!! public aaakansuu(evt: xxxOnloadEvent): void { let getdt let getx let gety let aaa:any //aaa = evt //getdt = evt.detail.dt ←■これだとインテリセンスでない。 //getx = evt.detail.x //gety = evt.detail.y getdt = evt.dt getx = evt.x gety = evt.y }

教授の通りインターフェイスを作り、
インターフェイスのクラスclsOnloadEventを作りました。
すると、どばっと色々でてきました・・・

質問① まず、どばっと色々出てくるのはしょうがないのでしょうか。
出てこなくする方法はあるものでしょうか。

そしてCustomEventは下記の様にしました。

const events = new CustomEvent("xxxonload", { detail:clsOnloadEvent //←■ここの書き方は正しいでしょうか? })

質問②clsOnloadEventに戻り値をセットしようとするとエラーになってしまいます。

let vvv = new clsOnloadEvent vvv.detail.dt = xhr.responseText //←■ここでUndefinedでエラーとなってしまいます
class clsOnloadEvent implements xxxOnloadEvent{ detail: xxxOnloadDetail; initCustomEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, detailArg: any): void { throw new Error("Method not implemented."); } bubbles: boolean; cancelBubble: boolean; cancelable: boolean; composed: boolean; currentTarget: EventTarget; defaultPrevented: boolean; eventPhase: number; isTrusted: boolean; returnValue: boolean; srcElement: Element; target: EventTarget; timeStamp: number; type: string; composedPath(): EventTarget[] { throw new Error("Method not implemented."); } initEvent(type: string, bubbles?: boolean, cancelable?: boolean): void { throw new Error("Method not implemented."); } preventDefault(): void { throw new Error("Method not implemented."); } stopImmediatePropagation(): void { throw new Error("Method not implemented."); } stopPropagation(): void { throw new Error("Method not implemented."); } AT_TARGET: number; BUBBLING_PHASE: number; CAPTURING_PHASE: number; NONE: number; } class C_Xhr { public XhrGet(url:string) { let vvv = new clsOnloadEvent vvv.detail.dt = xhr.responseText //←■ここでUndefinedでエラーとなってしまいます vvv.detail.x = 100 vvv.detail.y = 200 const events = new CustomEvent("xxxonload", { detail:clsOnloadEvent }) dispatchEvent(events) } }

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

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

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

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

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

guest

回答1

0

ベストアンサー

単に cxhr.xxxonload を処理終了時点で呼び出したいのであれば、

ts

1// function() {} だと this が xhr になってしまうのでアロー関数必須 2xhr.onload = () => { 3 // 最新ブラウザなら this.xxxonload?.(xhr.responseText) でも可 4 // もっとも最新ブラウザなら XHR じゃなくて fetch を使いましょう 5 if (this.xxxonload) { 6 this.xxxonload(xhr.responseText); 7 } 8}

だけで良いのではないでしょうか。

DOMイベントと同じように addEventListenerdispatchEvent を使いたいのなら、 EventTarget を継承する必要があります。

ts

1class Cls_Xhr extends EventTarget { 2 public XhrGet(url:string) { 3 xhr.onload = () => { 4 this.dispatchEvent(new CustomEvent('xxxonload', { detail: xhr.responseText })); 5 } 6 } 7}

なおこの方法では addEventListener で登録したイベントリスナは呼び出されますが、 cxhr のプロパティに設定したイベントハンドラは呼び出されません。ブラウザ組み込みのDOMのクラスなどは内部的にオブジェクトのプロパティに設定されたイベントハンドラが呼び出される仕組みを持っていますが、ユーザー定義のクラスで同じことはできません。

追記部分に関してですが、まず

ts

1//戻り値用のクラス 2class xxxOnloadEvent { 3 public dt : string 4 public x : number 5 public y : number 6}

これはクラスではなくインターフェイスで定義しましょう。

ts

1interface xxxOnloadDetail { 2 dt: string; 3 x: number; 4 y: number; 5} 6interface xxxOnloadEvent extends CustomEvent { 7 detail: xxxOnloadDetail; 8}

それから、

ts

1addEventListener("xxxonload", aaakansuu.bind (evt), true)

の部分ですが、 addEventListener の使い方がおかしいです。これだと window.addEventListener が呼び出されてしまいます。必要なのは cxhr インスタンスにイベントリスナを追加することだと思うので、 cxhr.addEventListener() を呼びましょう。
また、 bind をするのもおかしいです。そもそも bind の第一引数は thisObj ですし、イベントオブジェクトはイベントを発行する側が作成するものです。

再追記に関して。
clsOnloadEvent のようなクラスの定義は不要です。

ts

1interface xxxOnloadDetail { 2 dt: string; 3 x: number; 4 y: number; 5} 6type xxxOnloadEvent = CustomEvent<xxxOnloadDetail>; // 先の回答ではinterfaceを継承しましたがCustomEventはジェネリクスなのでこれだけで良かった 7 8const events: xxxOnloadEvent = new CustomEvent("xxxonload", { detail: { dt: 'foo', x: 0, y: 0 } });

これだけで十分です

投稿2020/10/27 16:12

編集2020/10/29 05:08
kazatsuyu

総合スコア158

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

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

eojvkx2

2020/10/28 04:07

回答いただきありがとうございます。もう1つ質問なのですが、 戻り値が複数ある場合、detailの部分をクラス指定する方法は できるのでしょうか。 (※VS TyepScriptでインテリセンスを使用したいためです) ソース追記編集していますので教授していただけましたら幸いです。
eojvkx2

2020/10/28 06:30

もう少しお付き合いお願いいたします。 interface追加してみましたが・・・です。 ソース追記編集しています。 よろしくお願いします。
eojvkx2

2020/10/29 06:33

色々最後まで教授いただきありがとうございました。 カスタムイベント,インターフェイスと勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問