jQuery показать / скрыть столбец на большой производительности таблицы - PullRequest
7 голосов
/ 29 июня 2010

У меня есть HTML-таблица с около 30 столбцами и где-то между 10 и 500 строк. Я хотел бы показать / скрыть набор столбцов o нажатием кнопки.

Я пробовал 2 подхода

  1. перебираем thead th таблицы и выполняем .show () или .hide () для TH и TD.
  2. переберите thead th таблицы и измените класс, чтобы показать / скрыть TH и TD.

функция реализована в следующем фрагменте. Тем не менее, производительность не так уж велика. Показать / Скрыть, скажем, 20 столбцов занимает около 5 ~ 10 секунд, может быть, 80 ~ 120 строк данных.

Мне просто интересно, можем ли мы что-нибудь сделать, чтобы это ускорилось.

function ToggleHeadVisibility(showHide) {

    var index = 0;

    $('#' + gridViewName + ' thead th').each(function(index) {
        index++;
        if (showHide == "SHOW") {
            /*
            $('#' + gridViewName + ' th:nth-child(' + (index) + ')').show();
            $('#' + gridViewName + ' td:nth-child(' + (index) + ')').show();
            */
            $('#' + gridViewName + ' th:nth-child(' + (index) + ')').removeClass('columnHide');
            $('#' + gridViewName + ' td:nth-child(' + (index) + ')').removeClass('columnHide');
        } else if (showHide = "HIDE") {
            /*
            //if (showColumnArray.has($(this).get(0).innerHTML)) {
            if (showColumnArray.has($(this).attr('title'))) {
            $('#' + gridViewName + ' th:nth-child(' + (index) + ')').show();
            $('#' + gridViewName + ' td:nth-child(' + (index) + ')').show();
            }
            else {
            $('#' + gridViewName + ' th:nth-child(' + (index) + ')').hide();
            $('#' + gridViewName + ' td:nth-child(' + (index) + ')').hide();
            }
            */
            if (showColumnArray.has($(this).attr('title'))) {
                $('#' + gridViewName + ' th:nth-child(' + (index) + ')').removeClass('columnHide');
                $('#' + gridViewName + ' td:nth-child(' + (index) + ')').removeClass('columnHide');
            } else {
                $('#' + gridViewName + ' th:nth-child(' + (index) + ')').addClass('columnHide');
                $('#' + gridViewName + ' td:nth-child(' + (index) + ')').addClass('columnHide');
            }

        }
    });
}

Ответы [ 6 ]

9 голосов
/ 29 июня 2010

Некоторые предложения:

  1. При создании таблицы добавьте классы CSS, такие как col1, col2, col3 и т. Д., В заголовок и ячейки данных. Тогда вы можете просто сделать $("td.col1").hide();, чтобы скрыть соответствующий столбец. Это быстрее, чем n-й дочерний селектор.

  2. В IE и Firefox вы можете установить visibility: collapse для элемента col, чтобы свернуть весь столбец. Это будет намного быстрее. К сожалению, не поддерживается в браузерах Webkit http://www.quirksmode.org/css/columns.html. Вы могли бы разветвлять свой код на основе браузера, чтобы он был быстрым по крайней мере в IE и Firefox.

  3. Если ваша таблица имеет table-layout: fixed, это может значительно повысить производительность, поскольку ваш браузер не должен продолжать вычислять ширину столбцов при каждом касании таблицы, как в автоматическом режиме.

  4. Рассмотрите возможность удаления таблицы из дерева DOM (через .remove()), выполните массовую операцию показа / скрытия и вставьте ее обратно. Это общее правило, когда вы хотите выполнить массовую операцию в дереве DOM.

1 голос
/ 29 июня 2010

Очевидно, эта альтернатива немного хитрее для отображения и скрытия элементов:

.css({'display':'none'}) & .css({'display':'block'});

http://www.learningjquery.com/2010/05/now-you-see-me-showhide-performance

Но я подозреваю, что ваша настоящая проблема в том, что петля.

0 голосов
/ 29 июня 2010

Могу ли я предложить что-то подобное?

$(function() {
    $('#show').click(function() {
        var i;
        for (i = 0; i < titles.length; i++)
        {
            ToggleHeadVisibility('SHOW', titles[i]);
        }
    });

    $('#hide').click(function() {
        var i;
        for (i = 0; i < titles.length; i++)
        {
            ToggleHeadVisibility('HIDE', titles[i]);
        }
    });
});

var titles = ['one', 'three', 'five'];

function ToggleHeadVisibility(showHide, title)
{
    var x = $('th[title=' + title + ']').index();
    var selectString = 'th:nth-child(' + (x + 1) + '), td:nth-child(' + (x + 1) + ')';
    var $set = $(selectString);

    if (showHide === "SHOW")
    {
        $set.show();
    }
    else if (showHide === "HIDE")
    {
        $set.hide();
    }
}

Я думаю, что на самом деле проблема заключается в вашей петле. Вы перебираете все th в таблице. Если вы хотите найти только конкретные, почему бы не выполнить итерацию по тем, которые вы хотите найти?

Итак, что здесь происходит, именно это. При нажатии кнопки «показать» (или «скрыть») мы перебираем массив заголовков, вызывая ToggleHeadVisibility.

В этой функции мы получаем индекс первого элемента с заданным заголовком, а затем показываем или скрываем узлы nth-child (x).

Я запустил его в таблице с 6 столбцами, показывающими и скрывающими по 3, и более 1000 строк. Это довольно быстро, для того, что он делает.

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

0 голосов
/ 29 июня 2010

Итерации по строкам и столбцам всегда замедляют процесс.Попробуйте манипулировать правилами CSS напрямую, чтобы избежать итерации в вашем JavaScript и заставить браузер сделать это за вас.

Извлечь плагины jQueryRule и jQueryCSSRule .

Манипулирование правилами CSS напрямую может быть полезным, если вы объедините все правила.Вот быстрый тест с 500 строками и 50 столбцами.Большая часть времени уходит на повторный рендеринг, а время, потраченное на функцию JavaScript, дает мне в среднем 200-300 ms в Chrome и 0 ms в Firefox.В настоящее время он использует стандартные API-интерфейсы, но тривиально расширить его до IE.

Он работает путем создания нового узла <style> внутри документа и добавления всех манипуляций с колонками.Основная идея заключается в объединении всех правил в одно при скрытии определенных столбцов.Поэтому вместо того, чтобы делать:

table tr :nth-child(1) { display: none; }
table tr :nth-child(4) { display: none; }
table tr :nth-child(7) { display: none; }

, он делает:

table tr :nth-child(1), table tr :nth-child(4), table tr :nth-child(7) {
    display: none;
}

Когда все столбцы должны быть отображены обратно, удалите это одно правило выше, которое скрывает определенные столбцы.

0 голосов
/ 29 июня 2010

Вы могли бы многое сделать в области кеширования. Для начала кешируйте свой контейнер gridView:

var gridView = $('#' + gridViewName);

И впоследствии строка может быть кэширована:

var row[0] = gridView.find('tr:nth-child(0)'); // Not sure the path is right, but you get the idea...

Кроме того, выполняйте фактическое скрытие, используя набор, а не .each ()

row[0].addClass('columnHide'); // Calls addClass() on each element in the set

Кэширование наборов элементов заранее, а не многократный запрос DOM с помощью $, и выполнение действий с наборами элементов, а не с циклами, может существенно повлиять на производительность.

0 голосов
/ 29 июня 2010

это код, который я использовал, чтобы скрыть "n-й" столбец в моей сетке ...

  if (true) {
      $('th:nth-child(' + c + ')').show();
      $('td:nth-child(' + c + ')').show();                           
  }
  else {
      $('th:nth-child(' + c + ')').hide();
      $('td:nth-child(' + c + ')').hide();                          
  }

Очень похоже на ваше, за исключением того, что я использовал jQuery для переключения "show / hide";

кажется, чтобы показать / скрыть столбец из 400 строк менее чем за 1 секунду ...

Борик

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...