-3

我有一个使用 jQuery 选项卡脚本的仪表板 UI。每个选项卡通过单独的 Ajax 请求加载其内容。

这是我遇到的问题:

  1. 用户将打开多个选项卡,一个接一个
  2. 创建每个选项卡并为每个选项卡发出 Ajax 请求
  3. 要创建的最后一个选项卡当前处于打开状态,一旦请求完成,每个选项卡的内容都会显示在此选项卡上
  4. 一旦用户单击任何选项卡,内容就会被设置为应有的状态。

基本上,如果用户在最近的选项卡的 Ajax 请求完成之前打开了一个新选项卡,则两个 Ajax 请求的内容都会显示在当前打开的选项卡上,直到用户单击任何选项卡,然后所有内容都会按原样显示。

我尝试设置 Ajax 调用来async: false解决问题,因为它强制 ajax 请求在允许用户打开另一个选项卡之前完成并加载到当前选项卡上,但是用户反馈是负面的,因为用户认为仪表板冻结(它有)。

我还设置了一个超时函数来加载带有加载 .gif 的选项卡,然后发出async: falseAjax 请求。用户反馈是相同的,即使使用超时功能,加载 gif 一旦发出 Ajax 请求就会停止它的动画。

Ajax 请求如下所示:

$.ajax ({
        url: report,
        cache: false,
        success: function(html) {
            $("#loading").hide();
            $("#tabcontent").append('<div id="c'+count+'" class="tabContentContainer">'+html+'</div>');
        },
        error: function(x, status, error) {
            $.ajax ({
                url: 'admin/error_notification.php',
                type: "POST",
                data:{
                    error: error
                }
            });
        },
        async:true
});
4

4 回答 4

0

我建议有一个与每个选项卡配对的单独的tabcontent div(不仅仅是一个#tabcontent div),并在切换选项卡时显示/隐藏它们。然后,如果先前的 ajax 调用稍后返回,并填充现在隐藏的 tabcontent div,则不会造成任何伤害。

function loadTab(tabName) {
    // Hide all tab content panes, then just show the one we want
    $(".tab-pane").hide();
    $("#tab-" + tabName).show();
    $.ajax ({
        ...
        success: function(html) {
            $("#loading").hide();
            $("#tab-" + tabName).append('<div id="c'+count+'" class="tabContentContainer">'+html+'</div>');
    <snip>

创建您的内容窗格,例如:

<div class="tab-pane" id="tab-firsttab"></div>

触发链接将类似于以下内容:

<a href="#" onClick="loadTab('firsttab')">First Tab</a>

我相信它会让用户快速单击多个选项卡,触发多个 ajax 调用,因为每个 ajax 调用只会将内容加载到它自己的内容窗格中。

于 2013-03-29T02:06:42.690 回答
0

我发现如果我在 Ajax 请求之前创建 tabContentContainer div,那么选项卡选择器有一个对象,然后在另一个选项卡打开时隐藏。然后,一旦加载了 Ajax 响应,它的可见性就已经设置好了。见下文:

$("#tabcontent").append('<div id="c'+count+'" class="tabContentContainer"></div>');

$.ajax ({
        url: report,
        cache: false,
        success: function(html) {
            $("#loading").hide();
            $("#c"+count+"").html(''+html+'');
        },
        error: function(x, status, error) {
            $("#tabcontent").append('<div id="c'+count+'" class="tabContentContainer"><div class="alert alert-error" style="margin-top:70px;"><button type="button" class="close" data-dismiss="alert">&times;</button><strong>Don\'t worry… It\'s not you, it\'s us.</strong> We were unable to connect to your data and deliver results. We are looking into this now.</div></div>');
            $.ajax ({
                url: 'admin/error_notification.php',
                type: "POST",
                data:{
                    error: error
                }
            });
        },
        async:true
});
于 2013-03-29T21:54:14.670 回答
0

以某种方式跟踪最后一个请求并在创建另一个请求时中止它:

var jqxhr = {abort: function () {}};
/* various other code */
function loadTabOrWhatever() {
    jqxhr.abort();
    jqxhr = $.ajax({
       /* ajax call in your question */
于 2013-03-28T22:51:35.850 回答
0

我有这样的设置。您调用下面的函数,指示您正在加载的选项卡。我确保每个新选项卡都有一个唯一 ID (UUID),并且该函数获取该 ID 以加载页面。

然而,有一个障碍——我发现如果加载的子页面包含 javascript 代码,需要在页面内部初始化对象,他们可能会因为页面是“隐藏的”而感到困惑。有时当我回到带有这些元素的选项卡时,我会发现它们的尺寸“小”。

此功能还存储提交到后端的数据,以便您轻松创建“重新加载”按钮。

function LoadView(ident, view, data) {

	var img = $('<img>', {
		src : '/images/ajax-loading.gif'
	});

	$('#' + ident).html(img);

	data.view = view;
	data.viewid = ident;

	// console.log(data);
	$.ajax({
		url : '/cgi-bin/browser.cgi',
		data : data,
		type : 'GET',
		dataType : 'html',
		timeout : 30000000,
		success : function(result) {
			$("#" + ident).html(result);
			// set data on view
			$("#" + ident).data('data', data);
		},
		error : function(xhr, status, error) {
			var img = $('<img>', {
				src : '/images/exclamation_micro.png'
			});
			$('#' + ident).html(img.html() + error);
			// alert("Error processing request " + error);
		},
		timeout : function() {
			var img = $('<img>', {
				src : '/images/exclamation_micro.png'
			});
			$('#' + ident).html(img.html() + ' Timeout');
			// alert("Timeout processing request");
		}
	});
}

function ReloadView(view, ident) {
    // Retrieve the data for the view
    var data = $('#' + ident).data('data');
    // Reload the view
    LoadView(ident, data.view, data);
}

于 2017-02-09T13:19:48.410 回答