Jump to content
  • 0

Варианты реализации


s0rr0w
 Share

Question

Интересует следующий вопрос

Есть код

<div id="container"></div>
<div id="itemTpl"></div>

Нужно при помощи jQuery

1. Создать 10000 клонов "itemTpl", удалить из каждого клона id, в клон вставить итерацию в виде текста.

2. По клику на ссылку пройти по каждому клону и назначить ему style.color = "red";

Интересуют варианты реализации.

Link to comment
Share on other sites

Recommended Posts

  • 0

А можно без jQuery? B)

var clones = [];

function clone(elementId, count) {
var el = document.getElementById(elementId);
for (var i = 0; i < count; i++) {
var clone = el.cloneNode(false);
clone.removeAttribute('id');
clone.appendChild(document.createTextNode(i + 1));
clones.push(clone);
}
}

function colorize() {
for (var i = 0; i < clones.length; i++) {
clones[i].style.color = 'red';
}
}

Link to comment
Share on other sites

  • 0
s0rr0w обиделся что его SC унизили B)

Нет, я просто сделал один вариант, но, из-за незнания подводных камней, я решил проверить, по правильному ли я пути иду.

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

А можно без jQuery? ;)

В том то и дело, что нужно имеено jQuery.

Link to comment
Share on other sites

  • 0

Что-то jQuery гуру замолчали... задумались видать.

Вот что было у меня

var count = 10000;
for ( var i = 0; i<count; i++ ) {
tplClone = tpl.clone( true ).appendTo('#content').attr( "id", "").text ( i );
}

Этот код раза в три медленнее, чем стандартный DOM

На второй пункт я написал вот такую конструкцию

$("#content").find("div").each( function(){ $(this).css( "color", "red"); } );

Теперь проверим это все на 10000 новосозданных нодах, и сравним SC и JQ

FF3.0

Первый запуск

JQ 814

SC 810

Повторные

JQ 699, 608, 703, 713, 610, 714, 713, 709

SC 246, 317, 249, 251, 249, 252, 248, 267

Opera 9.6x

Первый запуск

JQ 438

SC 360

Опера иногда показывала странные всплески с проседанием производительности

Повторные

JQ 297 стабильно повторялось

SC 109, 140, 109, 109, 141, 109, 109, 140, 110

Safari

Первый запрос

JQ 353

SC 240

Повторные

JQ 360, 359, 328, 359, 359, 344, 359, 359

SC 109, 125, 125, 110, 125, 109, 125, 125

Сафари показал себя в JS с лучшей стороны. Реально очень быстрый JS движок (в некоторых тестах уделывает даже хром!)

Вечером выложу обновленный код SC, где добавлено кеширование обработчиков.

Link to comment
Share on other sites

  • 0

Вот. Там в примере еще есть закомментированные строчки.

sc_vs_jq.zip

Первая инициализация работает достаточно медленно, но каждая последующая не оставляет JQ шансов B)

Edited by s0rr0w
Link to comment
Share on other sites

  • 0

2sorrow, вместо

$("#content").find("div").each(function(){ $(this).css("color", "red")})

можно просто

$("#content").find("div").css("color", "red")

Но SC действительно быстрее :)

UPD Можно заменить навешивание класса на более оптимальный вариант:

$("#container").children('div').each(function(){this.style.color='red'})

А вообще, такую пакость я бы постарался написать без jQuery :)

Edited by e1f
Link to comment
Share on other sites

  • 0
2sorrow, вместо
$("#content").find("div").each(function(){ $(this).css("color", "red")})

можно просто

$("#content").find("div").css("color", "red")

Но SC действительно быстрее :)

UPD Можно заменить навешивание класса на более оптимальный вариант:

$("#container").children('div').each(function(){this.style.color='red'})

А вообще, такую пакость я бы постарался написать без jQuery :)

О! Этот вариант мне больше нравится по скорости!

А последний реально конфетка! Но вот только от JQ осталось мало...

Этот пример - вполне реальный кусок кода. Например, нужно подсветить в большой табличке с данными те строки, которые имеют ошибочные данные, мало того, еще нужно и подсветить те ячейки, которые и вызывают ошибку. Это нормально для дружественного интерфейса.

Хотите, усложним задачу?

Link to comment
Share on other sites

  • 0
Давайте :)

Возьмем теперь другой темплейт

<div id="itemTpl"><span>1</span><span>-1</span><b>2</b><u>3</u></div>

Первый span будем красить в красный цвет через style, второй спан - присвоим ему класс green, очистим содержимое b и скроем u

Сможете предоставить строку JQ для теста?

Link to comment
Share on other sites

  • 0

var cRe = /\bhideU\b/;
$("#container").children('div').each(function(){
if (!cRe.test(this.className)) this.className += ' hideU';
var fC = this.firstChild;
fC && (fC.style.color='red');
fC = fC.nextSibling;
fC && (fC.className = 'green');
fC = fC.nextSibling;
if (fC) while (fC.firstChild) fC.removeChild(fC.firstChild);
});

UPD

CSS еще:

.red { color: red }
.green { color: green }
.hideU u { display:none }

Edited by e1f
Link to comment
Share on other sites

  • 0
var cRe = /\bhideU\b/;
$("#container").children('div').each(function(){
if (!cRe.test(this.className)) this.className += ' hideU';
var fC = this.firstChild;
fC && (fC.style.color='red');
fC = fC.nextSibling;
fC && (fC.className = 'green');
fC = fC.nextSibling;
if (fC) while (fC.firstChild) fC.removeChild(fC.firstChild);
});

UPD

CSS еще:

.red { color: red }
.green { color: green }
.hideU u { display:none }

А если я начну менять в коде местами теги?

Например поставлю B перед span? Или добавлю еще один span в начало?

Link to comment
Share on other sites

  • 0
Первый span будем красить в красный цвет через style, второй спан - присвоим ему класс green...

Да, я согласен, решение приведено исключительно для этого примера. А как будет действовать Ваш SC? Запустит механизм обхода всех нод, и будет искать у них обработчики?

UPD Я к чему это спрашиваю: насколько вариант с использованием SC медленнее варианта на чистом JS?

Edited by e1f
Link to comment
Share on other sites

  • 0
Да, я согласен, решение приведено исключительно для этого примера. А как будет действовать Ваш SC? Запустит механизм обхода всех нод, и будет искать у них обработчики?

UPD Я к чему это спрашиваю: насколько вариант с использованием SC медленнее варианта на чистом JS?

Начну с последнего. Да, SC будет медленнее чистого JS, так как есть накладные расходы на первый разбор обработчиков, и на последующее формирование стека команд.

Но на втором запросе будет все быстрее. Иногда раза в 3, иногда даже больше. Зависит от задачи.

В целом, приведенный мной пример требует всего одного прохода SC, порядок нод и их количество не имеет значения, так как обработчики формируют логику, а не структура HTML. Исходя из этого, совершенно не потребуется модификация JS кода при изменении структуры HTML. Именно поэтому я хочу увидеть универсальный JQ код, который сможет повторить все преимущества SC. И сравнить потом их производительность.

Link to comment
Share on other sites

  • 0

Ну, если универсальный, то видимо что-то такое (пишу и ужасаюсь :)):

$("#container").children('div').each(function(){
$(this).addClass('hideU');
$(this).children('span:first')[0].style.color = 'red';
$(this).children('span:last')[0].addClass('green');
$(this).children('b:first').empty();
});

Edited by e1f
Link to comment
Share on other sites

  • 0
Ну, если универсальный, то видимо что-то такое (пишу и ужасаюсь :)):

$("#container").children('div').each(function(){
$(this).addClass('hideU');
$(this).children('span:first')[0].style.color = 'red';
$(this).children('span:last')[0].addClass('green');
$(this).children('b:first').empty();
});

<div id="itemTpl"><b>2</b><span>1</span><span>-1<u>3</u></span></div>

С этой заготовкой ваш код справится?

Link to comment
Share on other sites

  • 0

Ступил-с, писал не проверяя :)

$("#container").children('div').each(function(){
$(this).addClass('hideU');
$(this).children('span:first')[0].style.color = 'red';
$(this).children('span:last').addClass('green');
$(this).children('b:first').empty();
});

Сразу замечу, что работать будет ну ОЧЕНЬ небыстро :)

Link to comment
Share on other sites

  • 0
Ступил-с, писал не проверяя :)


<style type="text/css">
.red { color: red }
.green { color: green }
.hiddenBlock { display: none }
</style>

Темплейт
<div id="itemTpl"><span SC="sc_style:exec">1</span><span SC="sc_class:exec">-1</span><b SC="sc_clear:exec">2</b><u SC="sc_hide:exec">3</u></div>

Обработчики
var sc_style = function ( controller, node, scData, execOptions ) {
try {
node.style.color = "red";
} catch ( e ) { }
};
var sc_class = function ( controller, node, scData, execOptions ) {
try {
$applyClassName( node, "green", true );
} catch ( e ) { }
};
var sc_clear = function ( controller, node, scData, execOptions ) {
try {
node.innerHTML = "";
} catch ( e ) { }
};
var sc_hide = function ( controller, node, scData, execOptions ) {
try {
$applyClassName( node, "hiddenBlock", true );
} catch ( e ) { }
};

Вызов функции запуска на обход остается тот же
GSC_launch( "container", "exec" );

По-моему комментарии излишни?

Link to comment
Share on other sites

  • 0

Да, что-то в этом есть :) В принципе, насколько я понимаю, в данном случае что SC, что jQuery делают примерно одно и тоже? То есть ползают по чайлдам контейнера, у них что-то меняют, только SC для изменения использует данные из атрибута элемента, так?

Делал я тут профайлинг (не только этого примера, но и компоненты грида, самописной, на jQuery). Поглядел на вызовы каких-то левых непонятных функций из фреймворка, почесал репу... переписал без jQuery. Скорость увеличилась в разы.

Основная потеря скорости идет от огромного количества вызовов .css(), .empty(). .empty() вообще крут -- он еще и анбинды делает, там вообще все небыстро. Если повесить хоть что-то (с помощью jQuery.bind()) на удаляемые элементы, скорость упадет еще больше, будет просто кошмар какой-то.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy