다음 코드는 요소의 경계를 x 및 y 위치의 두 목록에 저장합니다. 그런 다음 for-loop
을 사용하여 지정된 오프셋에서 시작하여 목록을 살펴볼 수 있습니다. 대답의 맨 아래에 구현이 표시됩니다.
// These arrays are going to contain many empty elements ;)
var xAxis = [];
var yAxis = [];
// Our storage. Each element looks like: [$element, top, right, bottom, left]
// Beware of cross-references! Deleted elements cannot be GCed if they're here!
var allElements = [];
/*
* @param $elem jQuery object
* @returns Object containing the jQuery object and the floored border offsets
*/
function getBorders($elem) {
$elem = $elem instanceof jQuery ? $elem.first() : $($elem);
var offset = $elem.offset(); // Properties: top, left
var width = $elem.outerWidth(); // Includes padding, border.
var leftBorder = offset.left; // Position of the left border ->|
var rightBorder = leftBorder + width; // Position of the right border |<-
var height = $elem.outerHeight(); // Includes padding, border
var topBorder = offset.top; // Position of the top border _v_
var bottomBorder = offset.top + height;// Position of the bottom border^
// Turn all numbers in integers, so that they can be used as indexes
// for arrays
// See also: http://stackoverflow.com/a/8112802/938089
return {
$elem: $elem,
top: ~~topBorder,
right: ~~rightBorder,
bottom: ~~bottomBorder,
left: ~~leftBorder
};
}
$('.widget').each(function() {
var $this = $(this);
var info = getBorders($this);
allElements.push(info);
// The positions are floored, so that they can be used as a quick reference
xAxis[info.left] = xAxis[info.right] = info;
yAxis[info.top] = yAxis[info.bottom] = info;
});
생성 된 목록을 사용하여 충돌하는 요소가 있는지 확인할 수 있습니다.
function doesItCollide($elem) {
// WeakMaps are useful. For compatibility, I don't use them.
var info$elem = getBorders($elem);
// info$elem properties: $elem, top, right, bottom, left
// Y-oriented
for (var y=info$elem.top; y<yAxis.length; y++) {
var candidate = yAxis[y];
// Not undefined, and not iself
if (candidate && candidate.$elem[0] !== info$elem.$elem[0]) {
// Check whether the element is inside the range
if (candidate.top >= info$elem.bottom &&
candidate.bottom >= info$elem.bottom) continue;
// It's here, so the top/bottom are possibly in the same range
// Check whether the x-positions are also colliding
if (candidate.left >= info$elem.left && /* Left within range? */
candidate.left <= info$elem.right || /* OR */
candidate.right <= info$elem.right && /* Right within range? */
candidate.right >= info$elem.left) {
return candidate;
}
}
}
return null;
}
예 (데모 : http://jsfiddle.net/LtJsM/) : 코드가 자주 실행되지 않는 경우
$('.widget').each(function() {
var $this = $(this);
var overlapping = doesItCollide($this);
if (overlapping) {
alert('Current element: '+this.className +
'\nColliding element: ' + overlapping.$elem[0].className);
}
});
, 당신은'html' 또는'body' 요소를 이동할 수 있습니다 예를 들어, 다음과 같은 기능을 고려 요소가 뷰포트 내에서 일시적이되도록 왼쪽/오른쪽/위/아래로 이동합니다. 다른 옵션 : 어떤 요소를 비교해야하는지 안다면'$ ('selector') .offset()'('.top'과'.left')과'.height()'/'.outerHeight)'및'.width()'/'.outerWidth()'를 사용하여 요소의 상대 위치를 계산합니다. –
@RobW : 내 문제를 진절머리 나는 모형으로 설명하려고했습니다. –
그래서 어느 요소가 서로 상대적으로 크기를 조정해야하는지 알고 있습니까? –