2009-08-10 3 views
7

Я пытаюсь показать небольшое загрузочное изображение во время медленной работы с jQuery и не могу понять это правильно. Это большая таблица с тысячами строк. Когда я устанавливаю флажок «mostrarArticulosDeReferencia», он удаляет «скрытый» класс из этих строк. Эта операция занимает пару секунд, и я хочу дать некоторую обратную связь. «загрузка» является ДИВЫМ с небольшим анимированным GIFjQuery show "loading" во время медленной работы

Вот полный код

jQuery(document).ready(function() { 
jQuery("#mostrarArticulosDeReferencia").click(function(event){ 
    if(jQuery("#mostrarArticulosDeReferencia").attr("checked")) { 
     jQuery("#loading").show(); //not showing 
     jQuery("#listadoArticulos tr.r").removeClass("hidden"); //slow operation 
     jQuery("#loading").hide(); 
    } else { 
     jQuery("#loading").show(); //not showing 
     jQuery("#listadoArticulos tr.r").addClass("hidden"); //slow operation 
     jQuery("#loading").hide(); 
    } 
}); 
jQuery("#loading").hide(); 
}); 

Похож JQuery является «оптимизация» этих 3 линий

 jQuery("#loading").show(); //not showing 
     jQuery("#listadoArticulos tr.r").removeClass("hidden"); 
     jQuery("#loading").hide(); 

И никогда не показывает загрузку дела. Любые идеи?

Бонус: Есть ли более быстрый способ сделать это шоу/скрыть предмет? Выяснилось, что переключение происходит медленнее.

UPDATE: Я попробовал этот

jQuery("#mostrarArticulosDeReferencia").click(function(event){ 
    if(jQuery("#mostrarArticulosDeReferencia").attr("checked")) { 
      jQuery("#loading").show(); //not showing 
      jQuery("#listadoArticulos tr.r").removeClass("hidden"); //slow operation 
      setTimeout("jQuery('#loading').hide()", 1000); 
    } else { 
      jQuery("#loading").show(); //not showing 
      jQuery("#listadoArticulos tr.r").addClass("hidden"); //slow operation 
      setTimeout("jQuery('#loading').hide()", 1000); 
    } 
}); 

Вот что я получаю

  1. нажмите на флажок
  2. ничего не происходит в течение 2/3 секунды (обработка)
  3. страница обновляется
  4. Загрузка div отображается в течение секунды с интервалом

ОБНОВЛЕНИЕ 2: У меня есть рабочее решение. Но почему я должен использовать SetTimeout, чтобы сделать его работу за меня ...

jQuery("#mostrarArticulosDeReferencia").click(function(event){ 
    if(jQuery("#mostrarArticulosDeReferencia").attr("checked")) { 
      jQuery("#loading").show(); 
      setTimeout("jQuery('#listadoArticulos tr.r').removeClass('hidden');", 1); 
      setTimeout("jQuery('#loading').hide()", 1); 
    } else { 
      jQuery("#loading").show(); 
      setTimeout("jQuery('#listadoArticulos tr.r').addClass('hidden');", 1); 
      setTimeout("jQuery('#loading').hide()", 1); 
    } 
}); 

UPDATE 3: Просто найти лучшее решение для данного конкретного случая.

//mostrar u ocultar articulos de referencia 
$("#mostrarArticulosDeReferencia").click(function(event){ 
    if($("#mostrarArticulosDeReferencia").attr("checked")) 
     $("tr.r").css({'display':'table-row'}); 
    else 
     $("tr.r").css({'display':'none'}); 
}); 

Использование .css ({ «отображение»: «Нет»}) оказывается намного быстрее, чем шкура(), поэтому нет необходимости для загрузки анимации ...
Эта статья показала мне свет : show/hide performance.

+0

Вы хотите, чтобы это выполнялось во время загрузки страницы? $ (document) .ready() срабатывает, когда все вниз и загружено – AutomatedTester

+0

Не нужно, мне нужно только это во время операции show/hide. Просто вставил весь скрипт –

+1

Как раз мысль, вы пробовали использовать контексты? Если вы укажете второй аргумент в инструкции селектора, это может помочь ускорить работу. –

ответ

2

Я пробовал все, и я должен сделать вывод, что это продукт мозгового мозга браузера.

  1. JQuery сообщает браузеру, чтобы показать/скрыть загрузки DIV
  2. JQuery указывает браузеру, чтобы добавить/удалить скрытый класс из строк
  3. JQuery сообщает браузеру, чтобы показать/скрыть загрузки DIV
  4. браузер делает все вышеуказанные шаги в неправильном порядке (2 в первую очередь)

«SetTimeout» в моем последнем обновлении заставляет браузер Тхо выполнить все шаги в правильном порядке. Это отстой, не элегантный, но по крайней мере он работает ...

Обновление: setTimeout необходимо, потому что jquery «упрощает» цепочку команд. Если я скажу ему, чтобы скрыть один элемент и показать его снова, он просто проигнорирует команду, потому что конечный результат будет таким же, как ничего не делать ...

+0

Я думаю, я добавил комментарий, в котором говорится, что этот ответ вводит в заблуждение правильный ответ и что отчасти часть браузера не является мозговой картой - это библиотека jquery и ее отсутствие calback для обратного вызова removeClass (что кажется естественно). Я не знаю, почему он был удален. –

0

Вы пробовали использовать ajaxStart для запуска функции обновления?

+0

Как вы бы хотели его использовать? не могу заставить его работать –

+0

проверить этот вопрос: http://stackoverflow.com/questions/1191485/how-to-call-ajaxstart-on-specific-ajax-calls – Jason

0

Я думаю, что он работает правильно. Эта операция:

jQuery("#listadoArticulos tr.r").removeClass("hidden"); 

не так уж медленно, и это выполняется в нескольких мс вершинах, так что вы не видите информацию загрузки, потому что это просто там в течение очень короткого промежутка времени.

+0

У меня ТЫСЯЧ строк, требуется 2 или 3 секунды. И это очень раздражает –

+0

Что делать, если вы прокомментируете инструкции hide и removeeclass, вы видите загрузку div тогда? – RaYell

+0

Что-то вроде того, что вы говорите? \t JQuery ("# mostrarArticulosDeReferencia"). Нажмите (функция (событие) { \t \t если (JQuery ("# mostrarArticulosDeReferencia"). Атр ("проверено")) { \t \t \t \t JQuery ("# загрузки") .show(); // не показывать \t \t \t \t // JQuery ("# listadoArticulos tr.r") removeClass ("скрытый");. // медленная операция \t \t \t \t // JQuery ("# загрузка "). hide(); \t \t} else { \t \t \t \t jQuery ("# ​​loading"). Show(); // не отображается \t \t \t \t // jQuery ("# ​​listadoArticulos tr.r"). addClass ("hidden"); // slow operation \t \t \t \t // jQuery ("# ​​loading"). hide(); \t \t} \t}); Да, я вижу загрузочный div, но я замалчивал его потом ... –

1

Я думаю, что вы хотите делать

jQuery("#listadoArticulos tr.r").removeClass("hidden"); 

внутри функции обратного вызова для показа.

Посмотрите на метод документации здесь: http://docs.jquery.com/Effects/show

Вы можете достичь того же «мгновенный демонстрационный» эффект, вызывая show(0);

Но вы хотите сделать обратный вызов? Нет проблем, сделайте это:

show(0, function() { jQuery("#listadoArticulos tr.r").removeClass("hidden"); }); 

Простой! :)

+0

Выполнение этого Я получил то же поведение, что и раньше 1. нажмите на флажке 2. ничего не происходит в течение 2/3 сек (обработка) 3.страница обновляется 4. загрузка div отображается в течение секунды секунды И я должен использовать settimeout, чтобы скрыть div. Если я его не использую, div никогда не показывает ... –

+0

У вас есть живой пример, с которым я мог бы сыграть? Я думаю вместо того, чтобы менять каждую отдельную строку, если у вас есть полный набор, вы можете вместо этого изменить тег tbody. –

0

Я тоже видел это поведение, и это зависит от используемого браузера. Наиболее уязвимым является IE. Причина не в том, что jQuery медленный, хотя JavaScript работает медленнее в IE, но больше из-за рендеринга нового HTML. Причина setTimeout() заключается в том, что он выполняет первое действие и только когда браузер выполнен с визуализацией нового HTML, вторая часть выполнена. Вся операция работает медленнее, но обратная связь делает ее более приятной.

Один из способов продемонстрировать это, спрятав длинный стол и запустив тот же код. Он будет делать то же самое, но поскольку таблица невидима и не делает все действие намного быстрее.

Существует несколько способов обойти это.

  1. Старайтесь избегать таблиц и вместо этого выбирайте схему DIV. Таблицы отображаются медленно, и в зависимости от браузера таблица может стать видимой, а затем полностью отображенной.
  2. Если вы должны использовать таблицу, подумайте о том, чтобы использовать несколько таблиц из 100 строк, склеенных вместе. Таким образом, страница начинает рендеринг, как только первая таблица будет переформатирована.
  3. Если одна большая таблица - единственный способ пойти, и вы знаете, что пользователь может видеть только верхние строки, вы можете выполнить это действие дважды, первый раз в верхних строках и второй раз на всех строках. Это самое медленное и наименее оптимальное решение, но его можно легко реализовать, добавив в действие фильтр jQuery.
+1

Почему вы рекомендуете divs для табличных данных? Почему вы рекомендуете разбить данные? Вы заботитесь о семантике? –

+1

ИЛИ доступность в этом отношении? –

+0

Главным образом из-за скорости рендеринга таблицы в браузере. Использование div и css - хорошая альтернатива. Конечно, есть возможность использовать фиксированную таблицу-макет, которая также поможет. См. Http://stackoverflow.com/questions/1046035/why-is-ie7-so-slow-compared-to-safari. – Maurice

0

Это не дает ответа на исходный вопрос, но это быстрее, чтобы использовать правило CSS для класса на самой таблице:

#listadoArticulos.hideCertainRows tr.r { display: none } 

и переключать дисплей так:

jQuery("#listadoArticulos").addClass("hideCertainRows"); 

?

3

Видимо вы стреляли в асинхронный запрос (да, асинхронный, другими словами, он не работает синхронно с кодом!) Во время «долгого запущенного процесса». Вам нужно позвонить $('#loading').hide() в конце функции обратного вызова асинхронного запроса.

Вот отличный пример:

$('#loading').show(); 
$.getJSON('someURL', function(data) { 
    // Do slow processing. 
}); 
$('#loading').hide(); 

Это, очевидно, не будет работать. Он покажет, запустит асинхронный запрос и сразу же скроется. Вам нужно переписать код, как:

$('#loading').show(); 
$.getJSON('someURL', function(data) { 
    // Do slow processing. 
    $('#loading').hide(); 
}); 
+0

Иногда очень простые вещи оказываются ответом. Спасибо за пример BalusC. – Chris

1

Только примечание - я разработал plugin для создания наложения DIV с загрузкой графики в нем.

1

Поместите DIV на странице где-нибудь так:

<div id="spinner" class="spinner" style="display:none;"> 
    <img id="img-spinner" src="@Url.Content("~/images/loading.gif")" alt="Loading"/> 
</div> 

Затем крючок шоу и скрываемой ajaxStart, ajaxStop и события ajaxError так:

$("#spinner").bind("ajaxSend", function() { $(this).show(); }) 
$("#spinner").bind("ajaxStop", function() { $(this).hide(); }) 
$("#spinner").bind("ajaxError", function() { $(this).hide(); }); 
0

Попробуйте использовать функцию обратного вызова «полный» метода показа, js в основном основан на асинхронных событиях, и эти три строки:

jQuery("#loading").show(); //not showing 
jQuery("#listadoArticulos tr.r").removeClass("hidden"); 
jQuery("#loading").hide(); 

g чтобы вы выполнялись без ожидания, так что вы показываете, добавляете класс и сразу скрываете div, поэтому вы не можете видеть div, вы скрываете его без ожидания, чтобы его показывали, и он появляется и исчезает очень быстро или даже он может никогда не появиться (не знаю о какой-либо оптимизации этого типа).

Если вы добавите два последних числа внутри всех обратных вызовов, это будет работать, более http: //api.jquery.ком/шоу /:

jQuery("#loading").show(400, function(){ 
    jQuery("#listadoArticulos tr.r").removeClass("hidden"); 
    jQuery("#loading").hide(); 
}); 

В любом случае, а также, правильный способ сделать это для запроса AJAX (я полагаю, это будет полезно для кого-то) использует ajaxStart и ajaxStop так:

$(document).ajaxStart(function() { 
    $("#loading").show(); 
}).ajaxStop(function() { 
    $("#loading").hide(); 
}); 

Дополнения для removeClass отсутствия обратного вызова:

может быть, ваша проблема заключается в том, что нет обратного вызова для removeClass, но вы можете сделать следующее:

jQuery("#loading").show(400, function(){ 
    var els = jQuery("#listadoArticulos tr.r"); 
    els.each(function(i, el) { 
     el.removeClass("hidden"); 
     if (els.length == i +1) jQuery("#loading").hide(); 
    }); 
}); 

попробовать это тоже:

var els = jQuery("#listadoArticulos tr.r"); 
els.each(function(i, el) { 
    if (i == 0) jQuery("#loading").show(); 
    el.removeClass("hidden"); 
    if (els.length == i +1) jQuery("#loading").hide(); 
}); 

Вы можете добавить проблему, если у вас есть изображения или какой-либо дополнительный код, который активирует как только вы удалите класс, не существует собственный способ, чтобы ждать их, чтобы скрыть загрузку div, поэтому, возможно, даже если вы удалите скрытый класс, нет простого способа подождать, пока объекты будут видны.

Я просто замечаю, что это было 2 года назад, возможно, вам это больше не нужно.

Смежные вопросы