在页面之间移动会产生错误(重复?)

时间:2016-08-02 12:48:20

标签: javascript jquery cordova onsen-ui onsen-ui2

我试图使用OnsenUI 2的pushPage()功能(截至目前为rc15)。除了OnsenUI,我还使用了jQuery 3。

这是我的功能,点击某些元素后应该推送页面:

$(".tile_handler").on("click", ".imalink", function () {
    var link = $(this).data().href;
    if(link != null){
        document.querySelector("#myNavigator").pushPage(link, { animation: "slide-ios" });
    }
})

当我第一次推送页面时,它运行正常。我使用iOS后退按钮返回。然后我再次点击它,我得到这个错误(并且越来越多,因为我重复这个过程):

  

[index.js:450]未捕获(在承诺中)pushPage已在运行。

这是另一个应该加载拆分页面的函数:

$(".splitter_item").click(function () {
    var address = $(this).data('address');
    $('#content')[0].load(address).then(menu.close.bind($('#menu')[0]));
})

当我通过Splitter在两个页面之间切换时,它开始抛出这个(每次在页面之间切换时都会更多)

  

[undefined:1] Uncaught(承诺)Splitter方面被锁定。

我假设发生的事情是我加载页面,离开它,当我再次访问它时,它会再次加载页面。但是,这似乎不是OnsenUI示例中显示的行为as this

document.addEventListener('init', function(event) {
  var page = event.target;

  if (page.id === 'page1') {
    page.querySelector('#push-button').onclick = function() {
      document.querySelector('#myNavigator').pushPage('page2.html', {data: {title: 'Page 2'}});
    };
  } else if (page.id === 'page2') {
    page.querySelector('ons-toolbar .center').innerHTML = page.data.title;
  }
});

popPage()函数应该删除以前加载的页面并阻止这种情况。但是参考文献没有使用它,所以我假设我做错了什么。但我不知道是什么。

更新

我设法在CodePen中重现这两个问题。 Here是拆分器错误,herepushPage()错误。似乎pushPage()问题与我的功能有关,因为每次点击它都会添加pushPage()请求,但不确定原因。

这两个错误似乎只发生在Ripple仿真器中(通过VS2015)。我似乎无法在Android模拟器中重现它们(但$(".tile_handler").on("click", ".imalink", function () {代码无论如何多次触发incorreclty)。我正在进一步测试。

3 个答案:

答案 0 :(得分:2)

基本上每次推送页面时,该页面都会触发init事件。然而,Onsen仍然保留了dom中的初始页面。

导航器示例(相同的逻辑适用于拆分器):

<ons-navigator>
  <ons-page id="dashboard">
    <div class="imalink" data-href="request_list.html"></div>
  </ons-page>
</ons-navigator>

您有一个仪表板的init事件。然后单击磁贴并转到另一页。 然后request_list会触发自己的init事件。但是我们的初始页面仍在dom中。

<ons-navigator>
  <ons-page id="dashboard" style="display: none">
    <div class="imalink" data-href="request_list.html"></div>
  </ons-page>
  <ons-page id="request_list">
    ...
  </ons-page>
</ons-navigator>

你有类似的东西。然而,以下称为第二次:

$(".tile_handler").on("click", ".imalink", function () {
  ...
})

再次添加听众。 $el.on("click")就像addEventListener的别名一样,意味着您正在添加越来越多的听众。

因此,无论何时导航,都要继续添加它们,因为初始页面从未从dom中删除。

替代解决方案:

  1. 仅使用当前页面(e.target

    $('selector') // instead of this   
    $(e.target).find('selector')  // use this
    

    这样您就可以限制只查找刚刚创建的页面中的元素。

  2. 从头开始启用处理程序。 由于您使用的是jQuery,因此实际上有一种更简单的方法可以在不依赖init事件的情况下完成任务。

    只需在任何init处理程序之外执行此操作:

    $(document).on("click", ".tile_handler .imalink", function () { ... })
    

    这实际上意味着处理程序附加到文档本身,并且仅当目标是.tile_handler .imalink时才会调用处理程序 - 因此它适用于您创建的任何未来的imalink。

    这可能不是最有效的方法,但绝对是最简单的方法之一。

答案 1 :(得分:1)

如果你双击一个按钮/链接,你提到的这两个错误实际上是一个安全的措施,你可能会错误地推动或做两次动作。

当您尝试在动画运行时执行操作时,它们会出现。正如您在示例中所看到的那样,只要在完成第一次推送后开始第二次推送,将页面推送两次或更多就没有问题。

以下是包含splitternavigator确切代码的演示。

因此,错误不是来自您提供的代码,而是来自其他地方。

我唯一能想到的是,如果由于某种原因导致popPage方法无法正确完成,则会看到您提到的行为。也许如果您向我们提供您自己的codepen,可以重现该问题,我们可以进一步调试它。

另一种选择,虽然建议高度 NOT ,但在您采取行动之前强行执行此操作。然而,这不是解决问题,而只是掩盖它。当然和所有黑客一样 - 它可能会在未来的版本中破裂。

myNavigator._isRunning = false;

<强>更新

以下是您在评论中提供的两个更新的笔: https://codepen.io/IliaSky/pen/YWOOkW?editors=1010 https://codepen.io/IliaSky/pen/QEVVGm?editors=1010

基本上你是在init事件上添加处理程序,只要添加页面就会触发该事件。因此,根据您的逻辑,您将为每个页面添加越来越多的处理程序。只要确保你只添加一次就可以了。

添加以下内容:

if (e.target.id == 'pagename') ...

或只是

$(document).on("init", '#dashboard_page', function(){ ... }

答案 2 :(得分:0)

看看.one() from jQuery-事件处理程序将仅对每个元素执行一次,以防止发生错误:未捕获(按承诺)pushPage已在运行

$(".tile_handler").one("click", ".imalink", function () {
var link = $(this).data().href;
if(link != null){
    document.querySelector("#myNavigator").pushPage(link, { animation: "slide-ios" });
}})