Сравнение исходного массива элементов Dom с сортировкой массива элементов Dom и проверка, отличаются ли они

У меня есть структура динамических элементов DOM, которые я постоянно оцениваю с помощью цикла for и setInterval. В течение этого интервала я сортирую массив, а затем изменяю dom с помощью функции JQuery Sort, чтобы упорядочить структуру DOM на лету.

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

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

    setInterval(function () {       
    //Incoming Chat Structure Variables
    var $incomingChatsTable, $incomingChatsRows, $incomingChatTags
    $incomingChatsTable= $("div[__jx__id*='incoming_list__list_content_container']")
    $incomingChatsRowsContainer=$("div[__jx__id='___$_194__visitor_list__incoming_list__list__content']")
    $incomingChatsRows = $("div[class*='renderers_Incoming']")
    $incomingChatTags = $( "div[__jx__id*='incoming_list__list__content'] div[class*='renderers_Incoming'] .visitorlist_tags .jx_ui_html_span:last-child .tag").toArray()        
    $popupTrigger = $("div[jx\\:list\\:rowid]") 
    //Assigning Priorities Function
    function assignPriority(arrayParent) {
        for ( var i=0; i <= arrayParent.length; i++) {
            var actualRow = $(arrayParent[i])
            var minutesInQueue = $(actualRow).find('.time_cell').text().substr(0,2)
            var priorityVal = parseInt(minutesInQueue)
            var actualRowTags = $( actualRow ).find('.tag').toArray()
            $(actualRow).addClass('priorityRow')               
            for (var k=0; k <= actualRowTags.length; k++) {
                let normalHolderTag = $(actualRowTags[k]).text().toLowerCase()
                if (normalHolderTag === 'vip') {
                    priorityVal += 30
                    $(actualRow).attr('data-priority', priorityVal)                    
                } else if ( normalHolderTag === 'rg' ) {
                    priorityVal += 20
                    $(actualRow).attr('data-priority', priorityVal)
                } else if ( normalHolderTag === 'accountclosure' ) {
                    priorityVal += 10
                    $(actualRow).attr('data-priority', priorityVal)                    
                } else {
                    $(actualRow).attr('data-priority', priorityVal)   
                } 
                //$(actualRow).find('.numbers_cell').text(priorityVal)
            }
        }     
    }   
    //Sorting Incoming Chats By Priority
    function orderByPriority(container) {
        myArray = container.find('.priorityRow')
        var changed = false
        myArray.sort(function(a,b){
            contentA = parseInt( $(a).data('priority') )
            contentB = parseInt( $(b).data('priority') )
            if ( (contentB - contentA) * ( myArray.indexOf(b) - myArray.indexOf(a) ) > 0 ){
                changed = true
            }                     
            return (contentB - contentA)                             
        })
        if(changed) {
            $(sortedArray).prependTo( container )
        } else{
            console.log('No need To Sort')
        }
    }
    setInterval(function () {
        assignPriority( $incomingChatsRows )
        orderByPriority( $incomingChatsRowsContainer )
    }, 500)
}, 1000) 

ОБНОВЛЕНИЕ:

myArray теперь является глобальной переменной, я добавил оператор IF, оценивающий результат функции сортировки и умножающий этот результат на индексы a, b. Если это значение больше 0, я изменяю значение моей измененной переменной на true, НО я получаю сообщение об ошибке myArray.indexOf is not a function.


person Lowtrux    schedule 16.07.2020    source источник


Ответы (1)


Вы можете добавить строку кода в свою функцию сортировки orderByPriority, которая устанавливает переменную в значение true, только если она действительно что-то меняет:

function orderByPriority(container) {
        var myArray = container.find('.priorityRow')
        var changed = false
        myArray.sort(function(a,b){
            contentA = parseInt( $(a).data('priority') )
            contentB = parseInt( $(b).data('priority') )
            if((contentB - contentA)*(myArray.index(b)-myArray.index(a))>0){ 
            //check if these have the same sign, i.e. something has changed
            changed = true;
            }
            return (contentB - contentA)                              
        })
        if(changed){}//do something to modify DOM
    }

Функция сортировки имеет три возможных выхода, которые определяют, нужно ли сортировать два входа:

  • Больше 0: отсортировать a по индексу больше b
  • Меньше 0: отсортировать b по индексу больше, чем a
  • Равно 0: не менять порядок

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

  • Выход больше 0, а индекс a в настоящее время меньше индекса b
  • Выведите меньше 0, и индекс a в настоящее время больше, чем индекс b

Мы можем представить разницу между двумя индексами как index(b)-index(a). Если индекс a в настоящее время меньше, чем индекс b, это значение будет положительным. В противном случае значение будет отрицательным.
Таким образом, мы видим, что приведенные выше условия на самом деле говорят:

  • если выход и index(b)-index(a) имеют один и тот же знак, нужно что-то менять.

Мы можем проверить, имеют ли они одинаковый знак, умножая их друг на друга и проверяя, больше ли результат 0. Это означает, что что-то изменилось, поэтому внутри условия if мы устанавливаем changed на true

person Leaf the Legend    schedule 16.07.2020
comment
спасибо @Leaf the Legend. Я получаю сообщение myArray.indexOf не является ошибкой функции, вы знаете, что происходит? Пытаясь понять логику вашего ответа, можете ли вы немного развить свой оператор if? Огромное спасибо ! - person Lowtrux; 16.07.2020
comment
Привет @Lowtrux, я отредактировал свой ответ, чтобы объяснить логику оператора if. Надеюсь, теперь это имеет смысл. Что касается того, почему indexOf не является функцией, единственная причина, о которой я мог подумать, заключается в том, что myArray не определено в функции сортировки. Я думаю, проблема в том, что функция сортировки технически имеет другую область действия, чем функция orderByPriority, поэтому объявление var на нее не распространяется. Чтобы исправить это, вы можете сделать myArray глобальной переменной, либо удалив ключевое слово var, либо объявив его вне вашей функции. Надеюсь, это сработает! - person Leaf the Legend; 17.07.2020
comment
БОЛЬШОЕ спасибо за ваше объяснение. Я попытался сделать myArray глобальной переменной, удалив ключевое слово var, по-прежнему дает мне ту же ошибку, что myArray.indexOf не является функцией. Любая другая идея, почему? и еще раз Большое Спасибо! - person Lowtrux; 17.07.2020
comment
Это странно. Вы можете ознакомиться с документацией по indexOf, что может помочь вам устранить неполадки. В противном случае я бы попробовал стандартные методы устранения неполадок, такие как console.log(myArray), и посмотрел, действительно ли это массив той формы, которую вы ожидаете. Может быть, также попробовать явно объявить var myArray; вне функции? Однако удаление ключевого слова var должно было помочь. Если это действительно просто не сработает, я уверен, что есть другие способы сделать то, что вам нужно. Удачи! - person Leaf the Legend; 17.07.2020
comment
@Lowtrux Я только что понял, что myArray на самом деле не массив. Я внимательно изучил ваш код и понял, что это на самом деле объект jQuery! Извини, я виноват. Я не эксперт в jQuery, но я уверен, что если вы просто замените все indexOf на index, это должно сработать. См. документацию по индексу здесь - person Leaf the Legend; 17.07.2020
comment
Спасибо @LeaftheLegend Решит ли myArray = container.find('.priorityRow').toArray() проблему? - person Lowtrux; 17.07.2020
comment
На самом деле это так, но я проверил, что изменено всегда ложно, поэтому дом никогда не меняется. - person Lowtrux; 17.07.2020
comment
Вы пробовали просто использовать index вместо indexOf? (без части toArray) - person Leaf the Legend; 17.07.2020
comment
Это на самом деле Работа. Большое спасибо ! - person Lowtrux; 17.07.2020
comment
Без проблем. Рад, что смог помочь - person Leaf the Legend; 18.07.2020
comment
Я замечаю, что скрипт глючит, как только новые элементы появляются в структуре myArray. Мне интересно, связано ли это с необходимостью какого-то setTimeout для всего скрипта. Просто хочу быть уверенным, что я получаю правильное поведение от условного оператора, который изменяет dom. Мне интересно, обновляется ли вся структура DOM myArray = container.find('.priorityRow') каждый раз, когда добавляется новый элемент, поскольку кажется, что метод сортировки не включает некоторые элементы. Надеюсь, вы снова сможете пролить свет, и большое спасибо! - person Lowtrux; 20.07.2020
comment
@Lead the Legend, есть мысли? Я бы очень хотел переделать код, чтобы он работал на 100%. Буду очень признателен за ваш совет. - person Lowtrux; 29.07.2020