从一页移动到另一页会产生错误(重复?)
Moving from page to page creates errors (duplicates?)
我正在尝试使用 OnsenUI 2(目前为 rc15)的 pushPage()
功能。除了 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 后退按钮返回 return。然后我再次单击它并收到此错误(并且随着我重复该过程而越来越多):
[index.js:450] Uncaught (in promise) pushPage is already running.
这是另一个应该加载拆分页面的函数:
$(".splitter_item").click(function () {
var address = $(this).data('address');
$('#content')[0].load(address).then(menu.close.bind($('#menu')[0]));
})
当我通过 Splitter 在两个页面之间切换时,它开始抛出这个(每次在页面之间切换时都会抛出更多)
[undefined:1] Uncaught (in promise) Splitter side is locked.
我假设正在发生的事情是我加载了一个页面,离开它,当我再次访问它时,它再次加载该页面。然而,这似乎不是 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 is the Splitter error and here 是 pushPage()
一个。 pushPage()
似乎是我的函数有问题,因为它会在我每次单击它时添加一个 pushPage()
请求,但不确定为什么。
这两个错误似乎只发生在 Ripple 模拟器中(通过 VS2015)。我似乎无法在 Android 模拟器中重现它们(但是 $(".tile_handler").on("click", ".imalink", function () {
代码无论如何都会多次触发错误)。我正在对此进行进一步测试。
你提到的这两个错误实际上是一种安全措施,例如,如果你双击 button/link,你会错误地推动或执行某些操作两次。
当您尝试在动画处于 运行 时执行操作时,它们会出现。正如您在示例中看到的,一般情况下,推送一个页面两次或更多次是没有问题的,只要您在第一次推送完成后开始第二次推送即可。
这里有演示,其中包含 splitter and navigator.
的确切代码
所以错误不是来自您提供的代码,而是来自其他地方。
我唯一能想到的是,如果由于某种原因 popPage
方法未能正确完成,您提到的行为将会出现。也许如果您向我们提供您自己的代码笔,我们可以在其中重现问题,我们可以进一步调试它。
虽然高度不推荐的替代方法是在您执行操作之前强制状态。然而,这不会解决问题,而只是掩盖它。当然,与所有黑客一样 - 它可能会在未来的版本中崩溃。
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(){ ... }
基本上每次您推送一个页面时,该页面都会触发一个 init
事件。但是 Onsen 仍然保留 dom.
中的初始页面
导航器示例(同样的逻辑适用于拆分器):
<ons-navigator>
<ons-page id="dashboard">
<div class="imalink" data-href="request_list.html"></div>
</ons-page>
</ons-navigator>
您有仪表板的初始化事件。然后单击磁贴并转到另一页。
然后 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 中删除初始页面。
替代解决方案:
只使用当前页面(e.target
)
$('selector') // instead of this
$(e.target).find('selector') // use this
这样您就只能在刚刚创建的页面中查找元素。
从一开始就启用处理程序。
由于您使用的是 jQuery 实际上有一种更简单的方法可以在不依赖 init
事件的情况下完成这些操作。
只需在任何初始化处理程序之外执行此操作:
$(document).on("click", ".tile_handler .imalink", function () { ... })
这实际上意味着处理程序附加到文档本身,并且仅当目标为 .tile_handler .imalink
时才会调用处理程序 - 因此它可以与您创建的任何未来 imalinks 一起使用。
这可能不是最有效的方法,但绝对是最简单的方法之一。
看看 .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" });
}})
我正在尝试使用 OnsenUI 2(目前为 rc15)的 pushPage()
功能。除了 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 后退按钮返回 return。然后我再次单击它并收到此错误(并且随着我重复该过程而越来越多):
[index.js:450] Uncaught (in promise) pushPage is already running.
这是另一个应该加载拆分页面的函数:
$(".splitter_item").click(function () {
var address = $(this).data('address');
$('#content')[0].load(address).then(menu.close.bind($('#menu')[0]));
})
当我通过 Splitter 在两个页面之间切换时,它开始抛出这个(每次在页面之间切换时都会抛出更多)
[undefined:1] Uncaught (in promise) Splitter side is locked.
我假设正在发生的事情是我加载了一个页面,离开它,当我再次访问它时,它再次加载该页面。然而,这似乎不是 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 is the Splitter error and here 是 pushPage()
一个。 pushPage()
似乎是我的函数有问题,因为它会在我每次单击它时添加一个 pushPage()
请求,但不确定为什么。
这两个错误似乎只发生在 Ripple 模拟器中(通过 VS2015)。我似乎无法在 Android 模拟器中重现它们(但是 $(".tile_handler").on("click", ".imalink", function () {
代码无论如何都会多次触发错误)。我正在对此进行进一步测试。
你提到的这两个错误实际上是一种安全措施,例如,如果你双击 button/link,你会错误地推动或执行某些操作两次。
当您尝试在动画处于 运行 时执行操作时,它们会出现。正如您在示例中看到的,一般情况下,推送一个页面两次或更多次是没有问题的,只要您在第一次推送完成后开始第二次推送即可。
这里有演示,其中包含 splitter and navigator.
的确切代码所以错误不是来自您提供的代码,而是来自其他地方。
我唯一能想到的是,如果由于某种原因 popPage
方法未能正确完成,您提到的行为将会出现。也许如果您向我们提供您自己的代码笔,我们可以在其中重现问题,我们可以进一步调试它。
虽然高度不推荐的替代方法是在您执行操作之前强制状态。然而,这不会解决问题,而只是掩盖它。当然,与所有黑客一样 - 它可能会在未来的版本中崩溃。
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(){ ... }
基本上每次您推送一个页面时,该页面都会触发一个 init
事件。但是 Onsen 仍然保留 dom.
导航器示例(同样的逻辑适用于拆分器):
<ons-navigator>
<ons-page id="dashboard">
<div class="imalink" data-href="request_list.html"></div>
</ons-page>
</ons-navigator>
您有仪表板的初始化事件。然后单击磁贴并转到另一页。
然后 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 中删除初始页面。
替代解决方案:
只使用当前页面(
e.target
)$('selector') // instead of this $(e.target).find('selector') // use this
这样您就只能在刚刚创建的页面中查找元素。
从一开始就启用处理程序。 由于您使用的是 jQuery 实际上有一种更简单的方法可以在不依赖
init
事件的情况下完成这些操作。只需在任何初始化处理程序之外执行此操作:
$(document).on("click", ".tile_handler .imalink", function () { ... })
这实际上意味着处理程序附加到文档本身,并且仅当目标为
.tile_handler .imalink
时才会调用处理程序 - 因此它可以与您创建的任何未来 imalinks 一起使用。这可能不是最有效的方法,但绝对是最简单的方法之一。
看看 .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" });
}})