【monaca】pushPageで遷移後、ons-gesture-detectorで取得できるイベントの挙動について

投稿者: Anonymous

表題の件につきましてOnsenUI最小テンプレを例に記述いたします。

まずindex.htmlを以下のように設定し、

<ons-navigator var="myNavigator" page="page1.html" ng-controller="navControlle">
</ons-navigator>

page2.htmlを以下のように設定しています。

<ons-page ng-controller="page2Controlle">
<ons-toolbar>
    <div class="left"><ons-back-button>Back</ons-back-button></div>
    <div class="center">Page 2</div>
</ons-toolbar>

<div style="text-align: center">

    <h1>Page 2</h1>
    <ons-button
        onclick="myNavigator.popPage()">
      Pop Page
    </ons-button>

</div>
<ons-list>
    <ons-gesture-detector>
        <ons-list-item class="hold" modifier="tappable">
            <p>リスト1</p>
        </ons-list-item>
        <ons-list-item class="hold2" modifier="tappable">
            <p>リスト2</p>
        </ons-list-item>
    </ons-gesture-detector>
</ons-list>

コントローラーを以下のように設定しています。

<script>
    app = ons.bootstrap();

    app.controller('navControlle', function($scope) {
        $(document).on('hold', '.hold', function(){
            console.log("hoge");
        });
    });

    app.controller('page2Controlle', function($scope) {
        $(document).on('hold', '.hold2', function(){
            console.log("fuga");
        });
    });
</script>

page2.htmlに初めて遷移したときの「リスト1」「リスト2」を長押しした際の挙動は同じで、それぞれconsole.logが1回よばれるのですが、
page2からpage1に戻って、再度page2に遷移したときに「リスト2」を長押しすると、holdが2回連続で呼ばれます。この時「リスト1」は1回しか呼ばれません。

再度page1にもどってpage2に、と繰り返して「リスト2」をクリックすると、今度はholdが3呼ばれ、どんどん呼ばれる回数が追加される挙動となります。

実際にはholdイベントにてpopupを表示する仕組みにしているのですが、連続的にイベントが発生してしまうため、呼び出される回数分popupが瞬間的に表示されてしまい困っております。

最悪navControlle内で処理すれば良いと思っていますが、できればページ毎にcontrollerを設定したいと考えております。

この事象の原因及び回避策についてご存知の方はいらっしゃいますでしょうか?

解決

page2.htmlを開くたびにdocumentに対してイベントリスナが追加されていることが原因です。documentではなく$elementから辿るようにしてはどうでしょうか。$elementはpopPage時に破棄されるため、リスナが残存することはありません。

_x000D_

_x000D_

ons.bootstrap()_x000D_
.controller('navController', function($scope) {_x000D_
  $(document).on('hold', '.hold', function(){_x000D_
    alert("hoge");_x000D_
  });_x000D_
})_x000D_
.controller('page2Controller', function($scope, $element) {_x000D_
  $element.on('hold', '.hold2', function(){_x000D_
    alert("fuga");_x000D_
  });_x000D_
});

_x000D_

<link href="https://cdn.rawgit.com/OnsenUI/OnsenUI/1.3.8/build/css/onsen-css-components.css" rel="stylesheet"/>_x000D_
<link href="https://cdn.rawgit.com/OnsenUI/OnsenUI/1.3.8/build/css/onsenui.css" rel="stylesheet"/>_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>_x000D_
<script src="https://cdn.rawgit.com/OnsenUI/OnsenUI/1.3.8/build/js/angular/angular.min.js"></script>_x000D_
<script src="https://cdn.rawgit.com/OnsenUI/OnsenUI/1.3.8/build/js/onsenui.min.js"></script>_x000D_
_x000D_
<ons-navigator var="myNavigator" page="page1.html" ng-controller="navController">_x000D_
</ons-navigator>_x000D_
_x000D_
<ons-template id="page1.html">_x000D_
  <ons-button style="margin: 100px;" ng-click="myNavigator.pushPage('page2.html')">Push</ons-button>_x000D_
</ons-template>_x000D_
_x000D_
<ons-template id="page2.html">_x000D_
<ons-page ng-controller="page2Controller">_x000D_
<ons-toolbar>_x000D_
    <div class="left"><ons-back-button>Back</ons-back-button></div>_x000D_
    <div class="center">Page 2</div>_x000D_
</ons-toolbar>_x000D_
_x000D_
<div style="text-align: center">_x000D_
_x000D_
    <h1>Page 2</h1>_x000D_
    <ons-button_x000D_
        onclick="myNavigator.popPage()">_x000D_
      Pop Page_x000D_
    </ons-button>_x000D_
_x000D_
</div>_x000D_
<ons-list>_x000D_
    <ons-gesture-detector>_x000D_
        <ons-list-item class="hold" modifier="tappable">_x000D_
            <p>リスト1</p>_x000D_
        </ons-list-item>_x000D_
        <ons-list-item class="hold2" modifier="tappable">_x000D_
            <p>リスト2</p>_x000D_
        </ons-list-item>_x000D_
    </ons-gesture-detector>_x000D_
</ons-list>_x000D_
</ons-page>_x000D_
</ons-template>

_x000D_

_x000D_

_x000D_

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *