Эффективный способ изменения цвета фона элемента в CSS3 или HTML5

0

Мне нужно изменить каждый цвет элемента в списке после изменения порядка или удаления одного элемента, теперь я использую метод jquery css, как показано ниже

$('li').css('background-color', color);

Он работает, но ужасно медленный, и иногда страница будет отображать цвет неправильно, даже в Chrome, который должен быть быстрым. В списке нет много элементов, ниже 10, обычно 5 - 7. Таким образом, эта производительность неприемлема. Поэтому я хочу знать, есть ли лучший, более быстрый способ в CSS3 или HTML5. Если нет, если есть решение или какое-то решение jquery?

Код для обновления цвета элементов списка выглядит следующим образом. Индекс может определяться функцией, и цвет может определять цвет. Основная проблема, по-моему, заключается в том, что изменение фонового цветового триггера происходит или, возможно, реверсирование.

function refreshListItemColor(liElements, colorGetter, indexGetter) {
        colorGetter = colorGetter || (function (color) {
            return color;
        });
        indexGetter = indexGetter || (function (liElement, index) {
            return index;
        });
        liElements.each(function (index, liElement) {
            index = indexGetter(liElement, index);
            var data = ko.dataFor(liElement);
            var indexColor = colorForIndex(index);
            indexColor = colorGetter(indexColor, data);
            if (indexColor !== $(liElement).css('background-color')) {
                $(liElement).css('background-color', indexColor);
            }
        });
}

Обновление: использование element.style ['background-color'] не будет выполнено. Вопрос все еще остается. Другим возможным объяснением отставания является то, что каждый элемент списка имеет около 10 дочерних элементов, что делает цвет элемента списка изменений особенно дорогостоящим.

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

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

var delay = 100, step = 100;
liElements.each(function (index, liElement) {
    index = indexGetter(liElement, index);
    var data = ko.dataFor(liElement);
    var indexColor = colorForIndex(index);
    indexColor = colorGetter(indexColor, data);
    if (indexColor !== $(liElement).css('background-color')) {
        setTimeout(function () {
            liElement.style['background-color'] = indexColor;
        }, delay);
        delay += step;
    }
});

Похоже, это может облегчить эту проблему. Я думаю, это не решит проблему, но уменьшит воздействие до приемлемого уровня.

  • 1
    Можете ли вы поделиться некоторыми из вашего кода .. чтобы помочь вам ...
  • 0
    Это быстро для меня. «Медленный» субъективен. Вы не должны видеть задержку, если это действительно небольшой список и HTML-документ. Кроме того, я не понимаю, как медлительность может привести к ложной цветопередаче. Если вы действительно видите неожиданные цвета, у вас есть и другая проблема.
Показать ещё 11 комментариев

6 ответов

2
Лучший ответ

Не могли бы вы использовать селектор атрибутов в таблице стилей?

[data-row="1"][data-col="3"]{
    background-color: blue;
}

Я заметил, что если вы хотите выбрать целую строку или столбец, вы должны использовать !important

[data-col="3"]{
    background-color: blue !important;
}

Изображение 174551


(редактировать) Добавление стилей динамически
Создайте пустой тег стиля с помощью div

<style type="text/css" id="dynamicstyle"></style>

и просто добавьте к нему, как и любой другой тег

$("#dynamicstyle").append('[data-row="0"]{background-color:red !important;}');

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

$(function () {
var maxRows = 0;
$("ul").bind("DOMSubtreeModified", updateStyleSheet);

function updateStyleSheet() {
    var childCount = $("ul").children().length;
    if (maxRows < childCount) {
        maxRows = childCount;
        var newRule = [
            '[data-row="',
        maxRows,
            '"]{background-color:', ((maxRows % 2) ? "red" : "blue"),
            ' !important;}'].join('')
        $("#dynamicstyle").append(newRule);
    }
}
});

http://jsfiddle.net/PgAJT/126/

Строки FizzBuzz http://jsfiddle.net/PgAJT/127/

  • 0
    Нет, я не могу, так как может быть много строк, и пользователь может добавить или удалить элемент в списке. Но это отличный ответ. Есть ли способ динамически добавлять CSS-файлы?
  • 0
    @imgen добавлен в редактирование
Показать ещё 1 комментарий
2

Удалите "if", что может заставить браузер перерисовать/перекомпилировать/обновить последнее значение CSS.

if (indexColor !== $(liElement).css('background-color')) {

Да, чтение выполняется медленно, и они блокируют write-comb.

  • 0
    Это на самом деле хорошо, так как изначально нет оператора if, но все еще медленно. Так что, хотя это хорошее предложение, оно не решит проблему
  • 0
    Вы получаете доступ к ЛЮБОМУ атрибуту элемента dom в ваших indexGetter и colorGetter?
Показать ещё 1 комментарий
1

Я создал простой тест с 10 элементами списка, каждый из которых имеет 12 детей и каждый раз задавал цвет фона для каждого элемента, когда запускается событие Gridster draggable.stop. Изменения в значительной степени мгновенно в IE11 и Chrome.

Для меня это говорит о том, что медленная работа CSS-рендера, но, возможно, вычисления, определяющие, какие цвета для каких элементов.

Это JavaScript, который я использовал:

var colors = ['#000', '#001', '#002', '#003', '#004', '#005', '#006', '#007', '#008', '#009', '#00a', '#00b'];

$('.gridster ul').gridster({
    widget_margins: [10, 10],
    widget_base_dimensions: [120, 120],
    draggable: {
        stop: function (e, ui, $widget) {
            refreshListItemColor();
        }
    }
});

function refreshListItemColor() {
    var sortedElements = [];
    $('ul > li:not(.preview-holder').each(function () {
        sortedElements.push([this, this.getAttribute('data-col'), this.getAttribute('data-row')]);
    });

    sortedElements.sort(function (a, b) {
        return a[1] - b[1] || a[2] - b[2];
    });

    for (var i = sortedElements.length - 1; i >= 0; i--) {
        sortedElements[i][0].style.backgroundColor = colors[i];
    }
}

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

  • 0
    Определение цвета очень простое, у меня есть цветовой массив с 7 элементами, и я использую простой индекс% 7, чтобы определить, какой цвет использовать, очень простой и не должен вызывать проблем с производительностью вообще.
1

Привет, я только что попробовал Wat U, нужно просто проверить это.

http://jsbin.com/awUWAMeN/7/edit

function change()
{
  var colors = ['green', 'red', 'purple'];
alert(colors)
$('.sd-list li').each(function(i) {
    var index = $(this).index();

        $(this).css('background-color', colors[index]);

});

}
  • 0
    Привет, это на самом деле не то, что мне нужно. Я использую подобный код, просто у меня проблема с производительностью. Но все равно спасибо.
  • 0
    так сколько записей вы загружаете в список .. список динамический ..
Показать ещё 1 комментарий
1

Предположительно, цвет определяется положением элемента в списке.

Используйте селектор nth-child или nth-of-type в таблице стилей.

  • 1
    Я думаю, что это разумное предположение, хотя, к сожалению, я не могу использовать эту технику, так как порядок списка контролируется не их порядком в DOM, а атрибутом, использующим абсолютную позицию, поэтому эта техника не будет работать. Но грамотное предположение и хороший ответ в любом случае.
0

Я быстро нашел способ создать класс с атрибутами css, которые вы хотите, а затем добавить этот класс в элемент dom, к которому вы хотите применить атрибут css. Правила CSS появляются без обновления.

CSS:

.bg-green{
background:green;
}

ЯШ:

$("#someDomId").toggleClass('bg-green','add');

Классный способ обработки списков - индексировать идентификатор каждого элемента списка при его создании/изменении:

Создать список:

for (i=0;i=m;i++){
var listElement = "<li id='"+i+">Some Content</div>";
$('ul').append(listElement);
}

Затем вместо итерации через элемент dom (что дорого) вы можете запустить другой цикл и изменить каждый элемент списка, выбрав его id.

for (i=0;i=m;i++){
$("#"+i).toggleClass('bg-green','add');
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню