Добраться туда ... еще нужно немного поработать. Я посмотрю что я могу сделать.

жный дубликат:
Как сделать этот JavaScript намного быстрее?

Я пытаюсь создать «элемент выбора» в jQuery, как Firebug. По сути, я хочу выделить элемент под мышью пользователя. Вот что у меня так далеко, но это не очень хорошо работает:

$('*').mouseover(function (event) {
    var $this = $(this);
    $div.offset($this.offset()).width($this.width()).height($this.height());
    return false;
});


var $div = $('<div>')
    .css({ 'background-color': 'rgba(255,0,0,.5)', 'position': 'absolute', 'z-index': '65535' })
    .appendTo('body');

По сути, я вставляю div в DOM, который имеет полупрозрачный фон. Затем я слушаю событие mouseover для каждого элемента, затем перемещаю div, чтобы он покрывал этот элемент.

Прямо сейчас, это просто делает всю страницу красной, как только вы наводите указатель мыши на страницу. Как я могу заставить это работать лучше?

Редактировать: Я уверен, что проблема в том, что как только моя мышь касается страницы, тело выбирается, а затем, когда я двигаю мышь, ни один из моментов не проходит через маркер, потому что он перезагружен.

поджигатель

Копаясь в исходном коде Firebug, я нашел это:

drawBoxModel: function(el)
{
    // avoid error when the element is not attached a document
    if (!el || !el.parentNode)
        return;

    var box = Firebug.browser.getElementBox(el);

    var windowSize = Firebug.browser.getWindowSize();
    var scrollPosition = Firebug.browser.getWindowScrollPosition();

    // element may be occluded by the chrome, when in frame mode
    var offsetHeight = Firebug.chrome.type == "frame" ? FirebugChrome.height : 0;

    // if element box is not inside the viewport, don't draw the box model
    if (box.top > scrollPosition.top + windowSize.height - offsetHeight ||
        box.left > scrollPosition.left + windowSize.width ||
        scrollPosition.top > box.top + box.height ||
        scrollPosition.left > box.left + box.width )
        return;

    var top = box.top;
    var left = box.left;
    var height = box.height;
    var width = box.width;

    var margin = Firebug.browser.getMeasurementBox(el, "margin");
    var padding = Firebug.browser.getMeasurementBox(el, "padding");
    var border = Firebug.browser.getMeasurementBox(el, "border");

    boxModelStyle.top = top - margin.top + "px";
    boxModelStyle.left = left - margin.left + "px";
    boxModelStyle.height = height + margin.top + margin.bottom + "px";
    boxModelStyle.width = width + margin.left + margin.right + "px";

    boxBorderStyle.top = margin.top + "px";
    boxBorderStyle.left = margin.left + "px";
    boxBorderStyle.height = height + "px";
    boxBorderStyle.width = width + "px";

    boxPaddingStyle.top = margin.top + border.top + "px";
    boxPaddingStyle.left = margin.left + border.left + "px";
    boxPaddingStyle.height = height - border.top - border.bottom + "px";
    boxPaddingStyle.width = width - border.left - border.right + "px";

    boxContentStyle.top = margin.top + border.top + padding.top + "px";
    boxContentStyle.left = margin.left + border.left + padding.left + "px";
    boxContentStyle.height = height - border.top - padding.top - padding.bottom - border.bottom + "px";
    boxContentStyle.width = width - border.left - padding.left - padding.right - border.right + "px";

    if (!boxModelVisible) this.showBoxModel();
},

hideBoxModel: function()
{
    if (!boxModelVisible) return;

    offlineFragment.appendChild(boxModel);
    boxModelVisible = false;
},

showBoxModel: function()
{
    if (boxModelVisible) return;

    if (outlineVisible) this.hideOutline();

    Firebug.browser.document.getElementsByTagName("body")[0].appendChild(boxModel);
    boxModelVisible = true;
}

Похоже, что они используют стандартный div + css для его рисования ..... просто нужно выяснить, как они обрабатывают события сейчас ... (этот файл имеет длину 28K строк)

Есть также этот фрагмент, который, я думаю, возвращает соответствующий объект ... хотя я не могу понять, как. Они ищут класс "objectLink-element" ... и я понятия не имею, что это за "repObject".

onMouseMove: function(event)
{
    var target = event.srcElement || event.target;

    var object = getAncestorByClass(target, "objectLink-element");
    object = object ? object.repObject : null;

    if(object && instanceOf(object, "Element") && object.nodeType == 1)
    {
        if(object != lastHighlightedObject)
        {
            Firebug.Inspector.drawBoxModel(object);
            object = lastHighlightedObject;
        }
    }
    else
        Firebug.Inspector.hideBoxModel();

},

Я думаю, что, возможно, когда событие mousemove или mouseover сработает для узла подсветки, я смогу каким-то образом передать его? Может быть, к узлу это охватывает ...?

Если я расположу невидимый элемент над каждым элементом с более высоким z-индексом, чем у моего маркера, но придаю моему маркеру более высокий z-индекс, чем у фактических элементов ... теоретически это должно сработать. Невидимые элементы отключают событие мыши, но эффект выделения будет по-прежнему выглядеть как переопределение фактических элементов.

Это означает, что я только удвоил элементы DOM, и расположение должно быть правильным.Если не возможно я только "поднимаю" элементы, которые маркер в настоящее время покрывает ?? Но это все же может быть каждый элемент>. <Кто-нибудь, помогите мне!

 Matt Ball15 янв. 2011 г., 07:55
Смотрите мой ответ изменить.
 mpen15 янв. 2011 г., 07:31
@Matt: Ну, как нам обойти это тогда? Разве Firebug не манипулирует DOM для рендеринга этих блоков, или у него есть собственный механизм рендеринга?
 Matt Ball16 янв. 2011 г., 05:48
+1 за копаться в исходном коде Firebug - я собирался это предложить.
 Matt Ball15 янв. 2011 г., 07:16
Есть неприятная ловушка-22, когда пытаешься делать такие вещи. По сути, как только вы рисуете что-то под мышью, в результате наведения мыши на элемент, мышь фактически покидает исходный элемент и теперь зависает надновый один.
 Matt Ball15 янв. 2011 г., 07:35
Firebug выделяет элементы на веб-странице, когда вы наводите на них курсор мыши в Firebug -отдельный, Или это надоело думать? Когда вы используете «щелчок для проверки», он только выделяет элементы, которые могут быть суть вопроса - Firebug может нарисовать 4 отдельных элемента, по одному на каждый край коробки, и в этом случае упомянутый выше улов 22 не проблема вообще.

Ответы на вопрос(5)

Javascript:

prevElement = null;
document.addEventListener('mousemove',
    function(e){
        var elem = e.target || e.srcElement;
        if (prevElement!= null) {prevElement.classList.remove("mouseOn");}
        elem.classList.add("mouseOn");
        prevElement = elem;
    },true);

Css:

.mouseOn{
  background-color: #bcd5eb !important;
  outline: 2px solid #5166bb !important;
}

чтобы он правильно изменял цвет фона после слов ...

$('body *').live('mouseover mouseout', function(event) {
    if (event.type == 'mouseover') {
        $(this).data('bgcolor', $(this).css('background-color'));
        $(this).css('background-color','rgba(255,0,0,.5)');
    } else {
        $(this).css('background-color', $(this).data('bgcolor'));
    }
    return false;
});

что вся страница становится красной, как только вы наводите курсор мыши, состоит в том, что ваш код соответствуетmouseover событие дляbody элемент. Вы можете остановить это, только выбрав детейbody.

$('body *').bind( //...

Вы столкнетесь с проблемами производительности на странице с большим количеством элементов, хотя, поскольку bind подключит слушателя для каждого соответствующего элемента. Попробуйте взглянуть на API делегирования событий jQuery (.delegate(), http://api.jquery.com/delegate/), который позволяет прослушивать события, распространяющиеся до корневого элемента, и работает также для событий мыши.

 andrewle15 янв. 2011 г., 07:40
Вы пытались проверить объект события, переданный вашему обратному вызову для currentTarget? Если currentTarget - это ваш подсвечивающий div, то вы можете просто ничего не делать.
 mpen16 янв. 2011 г., 01:46
Не имеет значения, если я ничего не сделаю, это все еще мешаетреальный элемент от получения события. (Но да, это позволило бы моему использоватьlive()... пока я могу решить другие проблемы)
 mpen15 янв. 2011 г., 07:30
Это действительно не решает проблему (используяbody *), это просто перемещает проблему к более глубокому элементу. Смотрите комментарий Мэтта. Пока не слишком беспокоюсь о производительности, я возьму все, что работает.
 mpen15 янв. 2011 г., 07:32
Кроме того, причина, по которой я не использую live () или делегат (), заключается в том, что тогда будут включены будущие элементы ... а именно, я не хочу, чтобы он начинал выбирать сам себя (именно поэтому я добавил его после того, как связал мероприятие).

► это немного менее нервный, но он не может обнаружить перемещение от родительского элемента к одному из его дочерних элементов без полного перемещения мышиот сказал родитель.

<div id="highlighter">').css({
    'background-color': 'rgba(255,0,0,.5)',
    'position': 'absolute',
    'z-index': '65535'
}).hide().prependTo('body');

var $highlit;

$('*').live('mousemove', function(event) {
    if (this.nodeName === 'HTML' || this.nodeName === 'BODY')
    {
        $div.hide();
        return false;
    }
    var $this = this.id === 'highligher' ? $highlit : $(this),

        x = event.pageX,
        y = event.pageY,

        width = $this.width(),
        height = $this.height(),
        offset = $this.offset(),

        minX = offset.left,
        minY = offset.top,
        maxX = minX + width,
        maxY = minY + height;

    if (this.id === 'highlighter')
    {
        if (minX <= x && x <= maxX
            && minY <= y && y <= maxY)
        {
            // nada
        }
        else
        {
            $div.hide();
        }
    }
    else
    {
        $highlit = $this;
        $div.offset(offset).width($this.width()).height($this.height()).show();
    }
    return false;
});

Надеюсь, что это поможет запустить мяч. Вы могли бы, вероятно, настроить то, что я написал, чтобы использоватьdocument.elementFromPoint(x, y) проверить, переместилась ли мышь в дочерний элемент выделенного элемента. Я не достаточно проснулся, чтобы понять это прямо сейчас.

С другой стороны, если изложение так же хорошо, как и выделение для вас, вы можете попробовать подход, который я упомянул в своем комментарии к вашему первоначальному вопросу. Нарисуйте 4 деления вокруг текущего элемента * - это один делитель для каждого края рамки. Нет больше элементов рисования между вами и вашим фактическим содержанием!

*Держу пари, чтоdocument.elementFromPoint(x, y) сделает получение элемента под мышкойнамного легче Вот.

 mpen15 янв. 2011 г., 08:15
Добраться туда ... еще нужно немного поработать. Я посмотрю что я могу сделать.

Как насчет простого назначенияbackground-color для всех дочерних элементов страницы, а затем, наhover(), настроитьbackground-color изэто элемент для увеличения его контраста?

$('html').children().css('background-color','rgba(0,0,0,0.2)');
$('body').children().hover(
    function(){
        $(this).css('background-color','#fff');
    },
    function(){
        $(this).css('background-color','rgba(0,0,0,0.2)');
    });

JS Fiddle demo.

 mpen16 янв. 2011 г., 02:47
Это возможно. Возможно, мне придется пойти с этим подходом, если я не могу найти решение, но этодействительно меня беспокоит, потому что я знаю, что должен быть способ сделать это.

Ваш ответ на вопрос