Объединение нескольких clientRect
Собсно надо объединить clientRect'ы нескольких элементов.
Сейчас делаю так: arr //массив элементов i //arr.length var result = {'top':[],'bottom':[],'left':[],'right':[]}, position; while(i--) { position = arr[i].getBoundingClientRect(); for(var j in result) result[j].push( position[j] ); } position = { 'top' : Math.min.apply(0,result.top), 'left' : Math.min.apply(0,result.left), 'bottom': Math.max.apply(0,result.bottom), 'right' : Math.max.apply(0,result.right) } Но как-то оно неэстетично смотрится. И чувство возникает, что можно сделать как-то красивее, без лишних телодвижений.(делаю для себя поэтому могу потратить часок другой на эстетические изыски :) ) Нужен только ff, так что можно использовать всё вплоть до js1.8.) |
Цитата:
А ваша версия кода ещё более некрасива, имхо. Да и производительность(на глаз) должна быть меньше(или нет). |
Цитата:
наверное, как-то уродливо :) но нерасширяемо, это уж точно - условие просто ппц ... а так красиво var arr = document.querySelectorAll("b"); var result = [].reduce.call(arr, function (prev, curr) { curr = curr.getBoundingClientRect(); for (var prop in curr) if (prev[prop] === null || ( (prop === "top" || prop === "left") ? (prev[prop] >= curr[prop]):(prev[prop] <= curr[prop])) ) { prev[prop] = curr[prop]; } return prev; }, { top: null, left: null, right: null, bottom: null }); <body> <b>LOL</b> <br><br> <b>LOL</b> <b>LOL</b> <br> <b>LOL</b> </body> <script> var arr = document.querySelectorAll("b"); var result = [].reduce.call(arr, function (prev, curr) { curr = curr.getBoundingClientRect(); for (var prop in curr) if (prev[prop] === null || ( (prop === "top" || prop === "left") ? (prev[prop] >= curr[prop]):(prev[prop] <= curr[prop])) ) { prev[prop] = curr[prop]; } return prev; }, { top: null, left: null, right: null, bottom: null }); var a = document.createElement("div"); a.style.cssText = "position: absolute;border: 1px green solid;"; document.body.appendChild(a); a.style.top = result.top + 'px'; a.style.left = result.left + 'px'; a.style.height = result.bottom + 'px'; a.style.width = result.right + 'px'; </script> |
Да твой быстрее моего на ~30% в общей сложности,
вариант melky - почти в 2.5 раза медленней твоего.) |
Пока тогда остановлюсь на таком:
var result = { 'left': Infinity, 'top': Infinity, 'right': -Infinity, 'bottom': -Infinity }; while (i--) { r = arr[i].getBoundingClientRect(); if (result.left > r.left) result.left = r.left; if (result.top > r.top) result.top = r.top; if (result.right < r.right) result.right = r.right; if (result.bottom < r.bottom) result.bottom = r.bottom; } Смотрится чуток эстетичнее изначально варианта от Дзен-трансгуманист, разницы в скорости нет. Но другие предложения приветствуются.) |
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
Эх, как красиво с новомодным фичами выглядела проверка текста: function isNaT( text ) { //not a text return [ /^[_a-z0-9-\.]+@[\.a-z0-9-]+\.[a-z]+$/i, //email /^[a-z]+:\/\/[^\s]+$/i, //url; /^[0-9\.,!@#\$%\^\&*\(\)`~_\-=\+|\\{}\[\]\s:;<>\?\/]+$/i //symbol ].some( function(pattern) pattern.test( text ) ) } Но оно аж в 3 раза медленней чем простое: function isNaT(text){ var pattern = [ /^[_a-z0-9-\.]+@[\.a-z0-9-]+\.[a-z]+$/i, //email /^[a-z]+:\/\/[^\s]+$/i, //url; /^[0-9\.,!@#\$%\^\&*\(\)`~_\-=\+|\\{}\[\]\s:;<>\?\/]+$/i //symbol ], i = pattern.length; while(i--) if(pattern[i].test( text )) return true; return false } а скорость, увы, всегда важна. P.S. Это абсурд: самодельная функция some работает быстрее нативной. *facepalm* |
Цитата:
|
Часовой пояс GMT +3, время: 08:44. |