0

それぞれ Vimeoiframeプレーヤーを含む 2 つのテンプレートがあります。FlowRouter を使用し{{> Template.dynamic template=main}}て、メイン レイアウトでテンプレートをレンダリングしています。

両方のテンプレートで、ビデオ イベントのリスナーを追加します。onCreated

Template.view.onCreated( function() {
    var self = this;

    if (window.addEventListener) {
        window.addEventListener('message', function(event) {
            viewMessageReceived(event, self)}, false);
    } else {
        window.attachEvent('onmessage', function(event){
            viewMessageReceived(event, self)}, false);
    }
});

そしてそれらを破壊するonDestroyed

Template.view.onDestroyed( function() {
    if (window.removeEventListener) {
        console.log('view remove');
        window.removeEventListener('message', function(event) {
            viewMessageReceived(event, self)}, false);
    } else {
        window.detachEvent('onmessage', function(event){
            viewMessageReceived(event, self)}, false);
    }
});

そして、匿名イベント ハンドラーによって呼び出される関数を次に示します。

function viewMessageReceived(event, self) {
// Handle messages from the vimeo player only
    if (!(/^https?:\/\/player.vimeo.com/).test(event.origin)) {
        return false;
    }

    if (self.playerOrigin === '*') {
        self.playerOrigin = event.origin;
    }

    var data = JSON.parse(event.data);

    switch (data.event) {
        case "ready":
            initializePlayer(self);
            break;
        case "playProgress":
            self.playerTime.set(data.data.seconds);
            if (self.duration === '*') self.duration = data.data.duration;
            break;
        case "play":
            self.playerStatus.set("playing");
            break;
        case "pause":
            self.playerStatus.set("paused");
            break;
    }
}

別のテンプレートに切り替えると、期待どおりにonDestroyed実行され、console.log('view remove')発火します。

しかし、ビデオ プレーヤーで他のテンプレートをロードするページに移動すると、Vimeo の「playProgress」が到着し、以前messageのビデオ テンプレートのイベント ハンドラーによって受信されます。これは、少し前に削除されたはずです。以前のテンプレートが破棄されているため、これはエラーをスローします。

Uncaught TypeError: Cannot read property 'contentWindow' of undefined

これは、この関数の最後の行から来ています:

function post(template, action, value) {
    console.log('view action: %s value: %s', action, value);
    var data = {method: action};
    if (value) data.value = value;
    var message = JSON.stringify(data);
    template.player[0].contentWindow.postMessage(message, template.playerOrigin);
}

ビデオを含むテンプレートにはそれぞれ独自の .js ファイルがあるため、それぞれに独自のpost関数宣言があります。私の理解では、関数を定義すると、関数の範囲がページだけに限定されるということです。

間違ったプレイヤーに届くメッセージは 1 つだけです。その後、現在ロードされているプレーヤーに到着します。

テンプレートを破棄した後、別のプレーヤーに移動したときに、Vimeo メッセージ イベントが到着または処理されるのはなぜですか?

4

1 に答える 1

0

メソッドに関する W3Schools Web サイトからの引用removeEventListener():

// Attach an event handler to <div>
document.getElementById("myDIV").addEventListener("mousemove", myFunction);

// Remove the event handler from <div>
document.getElementById("myDIV").removeEventListener("mousemove", myFunction);

注: イベント ハンドラーを削除するには、addEventListener() メソッドで指定された関数は、上記の例のように外部関数 (myFunction) である必要があります。

「element.removeEventListener("event", function(){ myScript });」などの匿名関数 動作しないでしょう。

これを機能させるには、関数定義をonRenderedandonDestroyedイベントの外に移動し、関数名を add/remove イベント リスナーに渡すだけです。

于 2016-02-03T21:19:39.797 に答える