Возможно ли, что я мог бы использовать квад-дерево или что-то еще и сегментировать страницу, чтобы цикл работал быстрее?
Просто сделайте шаг назад, осознайте, насколько мала проблема, и что чем сложнее вы попытаетесь выполнить более сложный ответ, который вы будете использовать.
Теперь вам нужно создать 4 элемента для выделения. Они образуют пустой квадрат, и поэтому ваши события мыши могут стрелять. Это похоже на это overlay example, которое я сделал.
Разница в том, что вам нужны только четыре элемента (без маркеров изменения размера), а размер и положение четырех ящиков немного отличаются (чтобы имитировать красную рамку). Затем вы можете использовать event.target
в обработчике событий, поскольку по умолчанию он получает реальный верхний элемент.
Другой подход - это скрыть элемент exra, получить elementFromPoint
, рассчитать, а затем вернуть его обратно.
Они быстрее света, я могу вам сказать. Даже Эйнштейн согласен :)
1.) elementFromPoint наложения/границы - [Demo1]FF нужен v3.0 +
var box = $("<div class='outer' />").css({
display: "none", position: "absolute",
zIndex: 65000, background:"rgba(255, 0, 0, .3)"
}).appendTo("body");
var mouseX, mouseY, target, lastTarget;
// in case you need to support older browsers use a requestAnimationFrame polyfill
// e.g: https://gist.github.com/paulirish/1579671
window.requestAnimationFrame(function frame() {
window.requestAnimationFrame(frame);
if (target && target.className === "outer") {
box.hide();
target = document.elementFromPoint(mouseX, mouseY);
}
box.show();
if (target === lastTarget) return;
lastTarget = target;
var $target = $(target);
var offset = $target.offset();
box.css({
width: $target.outerWidth() - 1,
height: $target.outerHeight() - 1,
left: offset.left,
top: offset.top
});
});
$("body").mousemove(function (e) {
mouseX = e.clientX;
mouseY = e.clientY;
target = e.target;
});
2.) наведения мыши границы - [Demo2 ]
var box = new Overlay();
$("body").mouseover(function(e){
var el = $(e.target);
var offset = el.offset();
box.render(el.outerWidth(), el.outerHeight(), offset.left, offset.top);
});
/**
* This object encapsulates the elements and actions of the overlay.
*/
function Overlay(width, height, left, top) {
this.width = this.height = this.left = this.top = 0;
// outer parent
var outer = $("<div class='outer' />").appendTo("body");
// red lines (boxes)
var topbox = $("<div />").css("height", 1).appendTo(outer);
var bottombox = $("<div />").css("height", 1).appendTo(outer);
var leftbox = $("<div />").css("width", 1).appendTo(outer);
var rightbox = $("<div />").css("width", 1).appendTo(outer);
// don't count it as a real element
outer.mouseover(function(){
outer.hide();
});
/**
* Public interface
*/
this.resize = function resize(width, height, left, top) {
if (width != null)
this.width = width;
if (height != null)
this.height = height;
if (left != null)
this.left = left;
if (top != null)
this.top = top;
};
this.show = function show() {
outer.show();
};
this.hide = function hide() {
outer.hide();
};
this.render = function render(width, height, left, top) {
this.resize(width, height, left, top);
topbox.css({
top: this.top,
left: this.left,
width: this.width
});
bottombox.css({
top: this.top + this.height - 1,
left: this.left,
width: this.width
});
leftbox.css({
top: this.top,
left: this.left,
height: this.height
});
rightbox.css({
top: this.top,
left: this.left + this.width - 1,
height: this.height
});
this.show();
};
// initial rendering [optional]
// this.render(width, height, left, top);
}
'$ (this) .closest ('body> *')' should g Являюсь вам самым главным предком 'этого', это то, что вы хотите?или ваш макет, чтобы элементы не всегда находились внутри их предка? – tobyodavies
Есть ли причина, по которой вы не можете просто использовать 'e.currentTarget' вместо цикла для поиска элемента? – Guffa
@toby: Это расширение Chrome. Может быть запущен на любой странице. Не знаю, как будет выглядеть разметка. Под «самым верхним» я имею в виду самый высокий z-индекс ... там могут быть менее глубоко вложенные элементы, которые стилизованы, чтобы появляться над другими. – mpen