2015-12-17 3 views
0

У меня есть таблица с большим количеством тд. Какой был бы самый эффективный способ выбрать выбор 1 для выбора 2 и все между ними?Выбирайте элементы между A и B эффективно

При выборе 1 я даю выбранный td идентификатор и по выбору 2, я даю этому выбору другой идентификатор, чтобы впоследствии искать эти идентификаторы.

Текущий код:

// small helpers 
function _for(e,f) { var i, len=e.length; for(i=0;i<len;i++){ f(e[i]); }} 
function _id(e) { return document.getElementById(e); } 

// VARs 
var main = _id('monthTables'), 
    td = main.querySelectorAll('td'), 
    go = false, 
    stop = false, 
    i = 0, 
    s1i = 0, 
    s2i = 999; 

// Loop throught td's 
_for(td, function(e){ 

    if(e.id == 'sel1') { go = 1; s1i = i; } 
    if(e.id == 'sel2') { stop = 1; s2i = i; } 

    if(s1i < s2i && go) { 
     if(go) { e.classList.add('range'); } 
    } 

    if(stop) { go = 0; } 

}) // end loop 

Живой пример (выберите две даты):
http://cdn.rawgit.com/tommiehansen/lightRange/master/test.html

+0

это выглядит хорошо. – Nirus

+0

Просто хранить результаты в массиве. Вы также можете реорганизовать своего помощника, чтобы было возможно «вернуться» раньше от вашей функции '_for' - вам не нужно ничего делать с элементами после того, как вы нашли маркер конца. –

+0

@ OlegV.Volkov 'main.querySelectorAll ('td')' - массив. Проблема с модификацией '_for' -helper заключается в том, что она является общей функцией, которая используется во всем коде для разных целей. Вы правы, что не нужно продолжать цикл, когда все условия выполнены. A 'if (! Stop) {/ * CODE * /}' в начале цикла разрешит некоторые из них, однако, если выбрать td 531, цикл все равно должен пройти через 531 элемент и проверить все условия на них. – Tommie

ответ

0

код хорошо, на мой взгляд, может быть, вы могли бы добавить несколько оптимизаций (например, остановка цикла при обнаружении второго выбранного идентификатора)

E Xample для цикла:

function _for(e,f) { 
    var i, len=e.length; 
    for(i=0;i<len;i++){ if(f(e[i]) === false) break; } 
} 

поэтому он будет ломаться, когда функция возвращает е false

// Loop throught td's 
_for(td, function(e){ 

    //... 

    if(stop) return false; 

}) // end loop 

Также я предлагаю вам использовать getElementsByTagName вместо querySelectorAll если вы хотите немного больше performance ..но может быть это злая микро оптимизация.

Другой оптимизацией было бы начать цикл из первого выбранного td, возможно storing the index, когда вы выберете td и используете это значение в tha т, вы отправили в качестве начального индекса

+0

Спасибо. Это был хороший и лаконичный способ решения проблемы «остановки цикла». Однако он не работает, поскольку 'f (e [i])' не является «правдивым» по умолчанию. Но, вероятно, будет работать модифицированный цикл. getElementsByTagName - это микро-оптимизация, но в этом случае это может иметь определенную разницу. На рабочем столе такие вещи не являются реальной проблемой, поэтому это зависит от того, насколько лучше 'getElementsByTagName' находится на слабых устройствах (мобильные телефоны и т. Д.) – Tommie

+0

вы правы, извините, я изменил условие внутри функции _for, теперь это будет работать.Другая оптимизация - начать цикл из первого выбранного td, возможно, сохранить индекс при выборе td и использовать это значение в этом коде, который вы отправили в качестве начального индекса http://www.w3schools.com/jsref/prop_tabledata_cellindex.asp – Saba

+0

Да, но с пенальти всегда проверяя это условие, но это наказание делает больше хорошего, чем плохого, так что это намного лучше, чем плохо. cellIndex не работает на нескольких таблицах? Проверьте связанную демонстрацию по адресу http://cdn.rawgit.com/tommiehansen/lightRange/master/test.html. Я могу выбрать, чтобы кешировать массив до того, как пользователь на самом деле что-то делает для того, чтобы не иметь этих накладных расходов, когда пользователь выполняет действия. Если вы проверите демоверсию, вы также увидите, что выбор необходим для ': hover'. – Tommie