Javascript: обнаружение конфликтующих div

Как определить, перекрываются ли два div?

Не принимая во внимание ширину div, это, по сути, вертикальный отрезок линии. Точка (верхняя, левая) - это точка A, а нижняя (верх + высота) - это точка B и так далее. Затем я бы сравнил каждый div с другими div в массиве div, а затем создал массив сталкивающихся div. Однако я застрял в том, как это сделать программно.

Это мой массив div:

var divs = [
    {class:'A', top:0,   left:0,   height:'60px'},
    {class:'B', top:50,  left:60,  height:'60px'},
    {class:'C', top:30,  left:10,  height:'60px'},
    {class:'D', top:100, left:180, height:'60px'},
    {class:'E', top:80,  left:50,  height:'60px'},
    {class:'F', top:110, left:200, height:'60px'},
    {class:'G', top:55,  left:80,  height:'60px'}
];

Вот функция, которую я запустил:

    this.collide = function( divs )
{
    var collidingDivs = [], z = events.length;

    for(i; i<z; i++)
    {
        if
        (
           // Begin pseudocode
           ( divsB.top >= divsA.top ) && 
           ( (divsB.top + divsB.height) <= (divsA.top + divsA.height) ) 
        )
        {
            collidingDivs.push(divs[i].class);
        }
    }
    console.log(collidingDivs); // Array of divs that overlap (collide)
};

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


person JsusSalv    schedule 27.09.2011    source источник
comment
Разве вам не нужен width для каждого div ??   -  person mellamokb    schedule 28.09.2011
comment
Сначала я подумал об использовании сделки типа «точка в многоугольнике». Однако затем я понял, что все, что мне действительно нужно знать, это перекрываются ли верхняя и нижняя точки div с любыми другими верхними / нижними точками из других div в массиве. Честно говоря, неважно, как я получу результаты. Мне просто нужно выяснить, какие div перекрываются с другими div в массиве, а затем переместить их, чтобы они не перекрывались. Я целый день работал над этим и по какой-то причине застрял :(   -  person JsusSalv    schedule 28.09.2011


Ответы (1)


Вам нужно пройти через каждый div, а затем сравнить с каждым другим div во вложенном цикле. Затем используйте логику, подобную той, которую вы написали, для сравнения каждой комбинации. Вот пример, который просто распечатывает перекрывающиеся div на выходе (обратите внимание, что я изменил элемент height, чтобы он имел числовое значение, а не текст, чтобы его значение можно было использовать в вычислениях):

var divs = [
    {class:'A', top:0,   left:0,   height:60},
    {class:'B', top:50,  left:60,  height:60},
    {class:'C', top:30,  left:10,  height:60},
    {class:'D', top:100, left:180, height:60},
    {class:'E', top:80,  left:50,  height:60},
    {class:'F', top:110, left:200, height:60},
    {class:'G', top:55,  left:80,  height:60}
];

for (var i=0; i < divs.length - 1; i++)
    for (var j=i+1; j < divs.length; j++)
    {
        var I=divs[i];
        var J=divs[j];

        if ( (I.top <= J.top && (I.top + I.height) >= J.top) ||
             (J.top <= I.top && (J.top + J.height) >= I.top) )
            document.writeln(
                I.class + " collides with " + J.class + "<br />");
    }

Выход:

A collides with B
A collides with C
A collides with G
B collides with C
B collides with D
B collides with E
B collides with F
B collides with G
C collides with E
C collides with G
D collides with E
D collides with F
D collides with G
E collides with F
E collides with G
F collides with G

Пример рабочего кода: http://jsfiddle.net/QUrWM/

person mellamokb    schedule 27.09.2011
comment
Это великолепно! Именно то, что я пытался сделать. Спасибо!! - person JsusSalv; 28.09.2011
comment
Как мне установить div, которые сталкиваются друг с другом, в массив? Например, класс A сталкивается с тремя другими div. Как мне установить эти три конкретных div в массив? Как их посчитать? Что-то вроде этого ?: code var divArray = []; для (i; i ‹l; i ++) {divArray.push (arrX.id); } code ... и для подсчета будет просто code var total = divArray.length; code? - person JsusSalv; 28.09.2011
comment
Вы можете легко выгрузить результаты в массив, просто добавив I.class и J.class в массив. Более важный вопрос: чего именно вы пытаетесь достичь с помощью этих результатов? - person mellamokb; 28.09.2011
comment
тьфу, как отформатировать код в комментарии ?? Во всяком случае, да, я пробовал это, но ничего не вывел. Если только я не помещаюсь в неправильное место. Я попробую еще раз. Я поделюсь окончательными результатами, когда все получится :) - person JsusSalv; 28.09.2011
comment
По сути, я пытаюсь определить, какие div перекрываются. Те, что перекрываются, мне нужно сместить вправо. Таким образом, div больше не перекрывается. - person JsusSalv; 28.09.2011
comment
Извините, я только что понял, что это не тот ответ, который вам нужен. Я пытаюсь выяснить, сколько событий сталкивается и какие события сталкиваются с другими событиями. Затем я разделю ширину каждого события, чтобы они равномерно распределялись в основном контейнере div. Это помогает понять, чем я занимаюсь? Я просто не хочу, чтобы div визуально перекрывали друг друга. - person JsusSalv; 28.09.2011
comment
Вы можете сделать что-то вроде этого: jsfiddle.net/QUrWM/5. Я сохранил дополнительный массив collidesWith в каждом объекте div, который я заполняю коллекцией конфликтующих классов div. Затем я распечатываю список и счетчик для каждого div. Посмотрите, что вы можете на этом построить. - person mellamokb; 28.09.2011
comment
Хорошо, я создал около трех или четырех разных версий, используя различные комбинации циклов for и т. Д., И я думаю, что сузил его до наиболее оптимизированной версии. Однако теперь я застрял на смещении сталкивающихся div. Наверное, мне не хватает простого математического / логического уравнения. Можете ли вы взглянуть на то, что у меня есть? jsfiddle.net/Sj3TP/1 - person JsusSalv; 01.10.2011
comment
Разделы 1-3 сталкиваются, поэтому они должны быть равномерно распределены в основном контейнере (ширина: 400 пикселей). Левые позиции для каждого из трех должны быть смещены на величину их ширины. Дивизионы 6-7 находятся справа. Все работает нормально для первых трех, но логика непонятна по мере того, как вы продвигаетесь все дальше и дальше. Скорее всего, я использую неправильный итератор ИЛИ мне где-то не хватает другого цикла for. - person JsusSalv; 01.10.2011
comment
Может как то так? jsfiddle.net/Sj3TP/2. Я внес довольно много изменений - я не совсем понял ваш g цикл for. Я добавил параметр placed к каждому блоку div, чтобы определить, был ли он уже изменен. Если нет, то он проходит через набор (я, мои столкновения) и для каждого из них устанавливает положение рядом друг с другом и отмечает их все как размещенные. Я также преобразовал ваш display div в область регистрации внизу. Внесенные мной изменения также должны касаться ситуации, когда конфликтующие div не обязательно должны быть в порядке. - person mellamokb; 01.10.2011
comment
это гениально !!! Я работал с этим кодом и сделал несколько модов, включив его в структуру классов и т. Д. Спасибо за вашу помощь! - person JsusSalv; 04.10.2011