Можно разбить на два этапа:
1) Сначала подготавливаем массив элементов, - а именно считаем прямоугольную область каждого элемента. Теперь у нас массив прямоугольников. Исходя из того, что области меняться не будут, делаем кое-какие дополнительные вычисления для оптимизации этапа №2.
2) При каждом выделении мышкой, решаем геометрическую задачу по поиску пересечений прямоугольников, которая уже не имеет прямого отношения к HTML, DOM и т.д.
Навскидку могу предложить такое решение:
Режем экран в виде невидимой сетки. Размеры ячеек вы выбираете сами. Пусть это будет сетка 10х10 ячеек. Для каждого элемента заранее считаем, в какие ячейки он попадает. То есть каждая ячейка - это массив ссылок на элементы, которые в неё попадают.
Теперь, если юзер выделяет прямоугольником область, которая касается четырёх ячеек (2х2), то нам нужно перебирать не вообще все элементы, а лишь те, которые в этих ячейках.
Если же юзер выбирает область побольше, которая касается уже ячеек 4х4, то элементы из внутренних ячеек автоматически попадают в результат без проверок границ.
И, наконец, когда юзер выделяет слишком большую область, которая ложится на 9х10 ячеек, то уже выгоднее искать те прямоугольники, которые могут не попасть в результат, то есть которые в ячейках 2х10. А все оставшиеся непроверенные автоматически попадают в результат.
Это был пример простой оптимизации, далёкой от совершенства.