与jQuery Mobile的AJAX调用 - 为什么方法被调用两次?
问题描述:
我正在撕掉我的头发。我是jQuery Mobile的新手,当浏览器滚动到页面底部时,我有一个可以加载新内容的函数。与jQuery Mobile的AJAX调用 - 为什么方法被调用两次?
我也有一个<select>
在哪里你可以选择类别。它在起始页面上工作正常(即没有选择类别)。但是,只要我选择一个类别,然后滚动到底部,功能bindScroll()
就会触发两次。
我一直在为此工作近两天,试图找到一些解决方案,但没有。我还没有真正弄清楚不同的jQuery Mobile事件,因此可能存在一些问题。
请看我的代码和帮助,如果你可以。该网站建立在.NET MVC中,但问题在于jQuery。
@using Namespace.Helpers
@{
ViewBag.Title = "Home Page";
}
<!-- Get a drop down of the different categories -->
@Html.Raw(Html.GetCategories(true, "CategoryId", 0, true))
<!-- list view to append the fetched ads to -->
<ul data-role="listview" data-inset="true" id="ad-list">
</ul>
<script>
// keeps track of how many rows to skip in the db. this is passed along to the server side
var currentPos = 0;
// save the categoryId
var categoryId = $('#CategoryId').val();
$('#page-start').live('pagecreate', function() {
// load the ads for the first call
loadAds();
//handle the category drop down
$('#CategoryId').change(function() {
// clear the list of ads
$('#ad-list').empty();
// reset so we start fetching from the first row in the db, used on server side
currentPos = 0;
// update the category value to pass along to the server
categoryId = $('#CategoryId').val();
// just to know that it has a value
console.log(categoryId);
// re-load the new ads
loadAds();
});
});
// method that loads ads via AJAX
function loadAds() {
console.log('loadAds()');
$.ajax({
// method on the server that returns a partial view
url: '/Home/LoadMoreAds',
type: 'GET',
data: {
// pass along some data
currentPosition: currentPos,
categoryId: categoryId
},
success: function (result) {
// add the result to the ad-list
$('#ad-list').append(result);
$('#ad-list').listview('refresh');
// once again, bind the scroll event
$(window).scroll(bindScroll);
},
error: function (data, textStatus, jqXHR) {
alert(textStatus);
}
});
}
// method that checks if the scroll is near the bottom of the page
function bindScroll() {
if($(document).height() > $(window).height())
{
if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
$(window).unbind('scroll');
// just to know that the method has run
console.log('bindScroll()');
// update counter to skip the already loaded rows
currentPos++;
// load new ads
loadAds();
}
}
}
</script>
编辑答案: -------------------------------------- ---------
我从Mike C的建议去绑定和重新绑定滚动事件。页面初始化时只有一个绑定。 然后我用这个代码:
// method that checks if the scroll is near the bottom of the page
var scrollHappening = false;
function bindScroll() {
if (scrollHappening) {
return false;
} else {
if ($(document).height() > $(window).height()) {
if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
// just to know that the method has run
console.log('bindScroll()');
// update counter to skip the already loaded rows
currentPos++;
// load new ads
loadAds();
scrollHappening = true;
}
}
}
}
而在Ajax调用的success:
设置scrollHappening = false
。似乎工作相当不错!
答
选择一个类别后,您在此位置重新绑定bindScroll,因此它会被调用两次!即当你选择一个类别,你做()调用LoadAds其中有这样的:
success: function (result) {
// add the result to the ad-list
$('#ad-list').append(result);
$('#ad-list').listview('refresh');
// once again, bind the scroll event
$(window).scroll(bindScroll);
},
每次调用LoadAdds(),这个函数增加了一个额外的事件调用bindscroll。
- LoadAdds()你现在有1级的事件势必在滚动滚动页面 - > bindscroll == 1个事件势必
- LoadAdds()现在有2个事件势必 所以滚动 - > bindscroll == 2事件绑定
当您实际上滚动时,如果您有2个事件绑定到bindscroll,它会在解除绑定发生之前调用这两个事件是我的猜测。
我认为你真正的解决方法是不绑定和解绑。绑定一次,不要使用bind/unbind来玩这个游戏。修改您的代码以使用单个绑定。在底部,有一个变量来标记你是否已经在底部,如果你是在退出函数。或类似的东西。这个绑定/解绑绑业务让您头疼。
感谢您的努力,但这不利于我们。奇怪的是,滚动事件不应该重新绑定,直到ajax成功的方法,但不知何故它被触发。另外奇怪的是,它只出现在我选择了一个类别时,否则它运行平稳。 – 2013-02-28 14:10:58
啊,你为什么不这么说!现在看来更加明显。我编辑了我的答案。 – 2013-02-28 14:15:10
我不明白。这与原始代码完全相同。 当bindScroll()运行时,我取消绑定滚动并加载广告,并且在广告加载到列表中后,我重新绑定滚动。或者至少这是我的意图。让我生气的是,当我显示“所有类别”时它工作正常。 – 2013-02-28 15:24:50