我正在开发一款应用并试图将Facebook行为用于AJAX请求。在Facebook中,您可以在触发AJAX请求的图标旁边获得一个很好的加载图像。好吧,如果页面中有1-2个元素,那么实现起来非常简单。
我想让它变得通用,并希望每当任何元素触发AJAX请求时,我想在它旁边显示一个小GIF。为此,我认为jQuery的AjaxSend事件已经足够好了,但是它没有给我一个触发AJAX调用的对象的句柄。我想知道是否可以通过jQuery的某些方法知道哪个元素触发了AJAX调用,并且在AJAX调用完成时获得相同的句柄。
如果您认为我对问题的处理方法不正确,我很乐意听取您的建议。
答案 0 :(得分:11)
另一种需要最少设置的通用方法是使用事件目标的activeElement
属性:
$(document).ajaxStart(function (e) {
try {
var $el = $(e.target.activeElement);
var isButton = $el.hasClass('btn');
// just a precautionary check
if (!isButton) {
return;
}
$el.button('loading'); // or whatever else you want to do
} catch (ex) {
console.log(ex);
}
});
$(document).ajaxStop(function (e) {
try {
var $el = $(e.target.activeElement);
var isButton = $el.hasClass('btn');
if (!isButton) {
return;
}
$el.button('reset');
} catch (ex) {
console.log(ex);
}
});
这样做的原因是因为当点击一个按钮时,它会获得焦点。 e.target
(此时为document
通过activeElement
属性告诉我们当前关注的元素。
请注意,try...catch
是完全可选的。在try...catch
中包装任何全局处理程序通常是个好主意,只是为了确保此处的任何异常都不会导致任何副作用。 console.log
会告诉您有关异常的信息(如果有),以便您以后可以修复。
答案 1 :(得分:5)
如果要使用ajax请求处理程序,则需要(手动或自动)将id分配给触发事件的元素。然后,您可以将此id作为请求中的附加键值对(element_id:THEID)发送,并使用ajax请求处理程序中的各种子字符串方法获取它。
示例:
<script type="text/javascript">
$(document).ready(function(){
$("input").click(function(){
var newid = (create a custom id with date and time);
$(this).attr("id", newid);
$.post("handler.php", {element_id : $(this).attr("id")});
});
}).ajaxSend(function(e, xhr, settings){
var start_position = settings.data.indexOf("element_id");
var equalsign_position = settings.data.indexOf("=", start_position);
var ampersand_position = settings.data.indexOf("&", start_position);
var element_id;
if(ampersand_position == -1){
element_id = settings.data.substr(equalsign_position+1);
} else {
element_id = settings.data.substr(equalsign_position+1, ampersand_position-equalsign_position-1);
}
$("#"+element_id).after("<div id='div"+element_id+"'><img src='loading_start.png' /></div>");
}).ajaxComplete(function(e, xhr, settings) {
var start_position = settings.data.indexOf("element_id");
var equalsign_position = settings.data.indexOf("=", start_position);
var ampersand_position = settings.data.indexOf("&", start_position);
var element_id;
if(ampersand_position == -1){
element_id = settings.data.substr(equalsign_position+1);
} else {
element_id = settings.data.substr(equalsign_position+1, ampersand_position-equalsign_position-1);
}
$("#div"+element_id).remove();
});
</script>
<input type="button" value="Save" />
另一种方法是处理每个事件处理程序中加载图像的出现和消失(但我似乎理解你有太多它们?),如下所示:
<script type="text/javascript">
$(document).ready(function(){
$("input").click(function(){
var element_id = (generate custom id);
$(this).after("<div id='div"+element_id+"'><img src='loading_start.png' /></div>");
$.post("handler.php", {var:"hello"}, function(){
$("#div"+element_id).remove();
});
});
})
</script>
答案 2 :(得分:2)
我还试图抓住ajax事件来动画一些按钮,我想出了:
$j('.btn').bind('click',function(){
triggerElement = $j(this);
});
$j(document).ajaxSend(function(event,xhr,options){
var userAgent = $j.browser;
if (userAgent.mozilla)
triggerElement = $j(event.target.activeElement);
if (triggerElement && triggerElement.is('.btn')){
var triggerOffset = triggerElement.offset();
genericDisabler = $j('<div></div>');
genericDisabler.addClass('generic-disabler');
$j('body').append(genericDisabler);
genericDisabler.width(triggerElement.outerWidth());
genericDisabler.height(triggerElement.outerHeight());
genericDisabler.offset({
left:triggerOffset.left,
top:triggerOffset.top
});
triggerElement.switchClass('orange','gray-ajax-gradient',25).animate({
opacity: 0.6
});
}
});
$j(document).ajaxComplete(function(event,xhr,options){
if (triggerElement && triggerElement.is('.btn')){
triggerElement.switchClass('gray-ajax-gradient','orange',25,function(){
if (genericDisabler)
genericDisabler.remove()
}).animate({
opacity: 1
});
}
triggerElement = null;
});
所以我确保获得完成点击的元素,但我保留了FF可以做得好的参考。
答案 3 :(得分:0)
我之前遇到过同样的问题......好吧它不会给你处理,看看下面的代码是否对你有用。 这是我的解决方案
$(document).click(function(event){
if(event.target.id != "comment" && event.target.id != "fb-button"){
$("#submit-button").css("display","none");
if($("#comment").val() == ""){
$("#comment").addClass("lightText").val("write a comment...");
}
}
});
只需跟踪正文上的所有点击事件并获取其来源
答案 4 :(得分:0)
我有同样的问题, 我做的是设置一个全局参数并将单击的按钮设置为它:
var btn = null;
$(document).ajaxSend(function(event, xhr, settings) {
btn.find(".ui-button-text:first").append('<div class="loading"></div>');
}).ajaxComplete(function(event,request, settings) {
$(".loading").remove();
});
只需为加载添加样式,它将为Jquery UI按钮添加一个加载指示器。
<style type="text/css">
.btn {
margin: 5px 10px 0 0;
}
.loading {
display: inline;
background: url(../images/loading.gif) center no-repeat;
margin: 0 0 0 5px;
padding: 0 0 0 16px;
}
</style>
答案 5 :(得分:0)
如何解决这个问题有很多方法。
我有多个元素可以触发AJAX事件,并希望每次发送和完成AJAX请求时都执行一些自动回调。但仅限于触发它的元素。
我最终将$ .get()方法包装到我自己的对象中:
var AJAX = {
fetch: function (url, data, targetObj) {
var oldText = ''
targetObj = (this.isDefined(targetObj) ? targetObj : null)
if (targetObj) {
oldText = targetObj.text()
targetObj.text('Loading...')
}
return $
.get(url, data)
.always(function () {
// if target object is provided, run end callbacks on it
if (targetObj) {
targetObj.text(oldText)
}
})
}
}
然后这样称呼它:
AJAX.fetch('my_script.php', {somedata: 'blabla'}, $(this))
您可以完全概括它,以便它可以运行您添加的任何回调+自动记录错误。我写了tutorial how to achieve that +你可以找到代码on GitHub。
答案 6 :(得分:0)
$(document).ajaxStart( function(e) {
var el = e.target.activeElement.id;
alert('event triggerd by : ' + el);
});
主要解决方案:e.target.activeElement.id
答案 7 :(得分:0)
这对我有用:
$(document).ajaxSend(function (e, jqXHR, ajaxOptions) {
try {
if (e.target.activeElement) {
var $el = $(e.target.activeElement);
var isButton = $el.hasClass('btn');
if (!isButton) return;
$el.prop('disabled', true);
jqXHR.complete(function () {
$el.prop('disabled', false);
});
}
} catch (ex) {
console.log(ex);
}
});