Подтвердить что ты не робот

Событие Mouseover не гранулируется на IE9 для подэлементов, событие не запускается на IE8

Мы адаптировали метод, размещенный здесь выделили элемент DOM на мыши, например, проверили на НЕ использовать jQuery.

Мы придумали это решение: http://jsfiddle.net/pentium10/Q7ZQV/3/

Этот шов работает на Chrome и Firefox, но не работает в IE.

  • В IE9, например, подсветка не встречается на младших элементах, таких как строка тегов, например: javascript, html, dom или верхняя строка, например: chat, meta, faq

    Когда я нажимаю над тегом javascript, большой div является highligthed, и это неверно, и это должно быть как мы видим в Firefox

  • В IE8 и 7 он не запускается, так что это еще одна проблема, нам нужно исправить

4b9b3361

Ответ 1

Оказывается, что в IE элементы, которые не имеют фона (т.е. background: transparent) и Gradient filter, не принимают события мыши, Демо

Это счастливое совпадение, поскольку вы используете цвет фона RGBa для своего наложения и один из обходных решений для цветов RGBa в IE является фильтром градиента.

Установив эти стили на оверлей (для IE):

background: transparent;
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#7F000000,endColorstr=#7F000000)"; /* IE8 */
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#7F000000,endColorstr=#7F000000);   /* IE6 & 7 */
zoom: 1;

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

Другие проблемы, которые присутствуют в IE7/8:

  • При использовании element.attachEvent для имени события должно быть префикс "on":

    document.body.attachEvent('onmouseover', function(e) { ... })
    
  • Чтобы найти цель события, вам нужно получить доступ к event.srcElement вместо event.target.

  • Как упоминалось Rodneyrehm, Array.indexOf не поддерживается.

Итак, вот версия вашего решения, которая также работает в IE 7-9: http://jsfiddle.net/jefferyto/Q7ZQV/7/

(BTW Выделение неверно для встроенных элементов, которые охватывают более одной строки, например, ссылку "спросить свой собственный вопрос" в строке "Обзор других вопросов...".)

Ответ 2

Я думаю, что я нашел проблему в вашей реализации. Но прежде чем мы доберемся до этого, вы можете исправить себя из-за утечки глобального уровня, который вы представляете в строке 45. Существует точка с запятой, где вам, вероятно, нужна запятая:

var target = e.target,
    offset = findPos(target),
    width = target.offsetWidth;//target.outerWidth(),
    height = target.offsetHeight;//target.outerHeight();

Вам также может быть интересно узнать Array # indexOf поддерживается с IE9, поэтому ~no.indexOf(e.target) завершится с ошибкой в ​​IE8 и ниже.

Теперь к вашей проблеме. Текущие браузеры (включая Firefox) знают pointer-events:none. Даже поддержка IE10 еще неизвестна. Любой браузер, не поддерживающий указатели-события, никогда не запускает событие mouseenter для элементов, которые покрываются вашим наложением.

С поддержкой IE7 + document.elementFromPoint() вы можете привязать к mousemove, скрыть слой, обнаружить элемент под курсором, запустить mouseover if необходимо. Если вы идете по этой дороге, рассмотрите возможность дросселирования событий mousemove (см. limit.js).

Что-то вроде this.

Update:

Я не сравнивал производительность document.elementFromPoint() vs pointer-events:none. Текущие браузеры (Firefox, Chrome,...) могут иметь дело с обоими, Internet Explorer может работать только с подходом document.elementFromPoint(). Чтобы все было просто, я не реализовал альтернативный маршрут pointer-events:none для современных браузеров.

Ответ 3

Используя специальную процедуру для Internet Explorer (протестированную в IE9, не протестированную в IE8), я придумал this. Тем не менее, это еще не идеально. При перемещении мыши внутри одного и того же элемента происходит мерцание, поскольку процедура запускается несколько раз (и иногда наложение полностью исчезает). Я надеюсь, что скоро это удастся.

Рутинное:

  • Я специально проверил, был ли браузер IE и выполнил следующие действия:
  • Я назначил событие mousemove функции, которая использует document.elementFromPoint(x, y).
  • Я назначил mouseover функции очистки, которая немедленно удаляет накладку. (Это вызывает мерцание и возможное полное удаление наложения, даже если мышь все еще находится на элементе.)

Элемент из функции точки

function ep(e)
{
    var ev = {target:document.elementFromPoint(e.clientX, e.clientY)};
    handler(ev);
}

Функция очистки

function clear(e)
{
   cur = null;
   overlay.style.display='none';
}

Обратная связь и предложения приветствуются. Я все еще работаю над этим, и я опубликую обновленные ссылки JSFiddle.

Ответ 4

Вы могли избежать перехвата событий мыши с помощью наложения путем изменения его свойств, а именно, сделав его прозрачным и полагаясь на outline или, с корректировками расчета размера, border:

background:transparent;
outline:1px dotted red;

Fiddle'd

В качестве альтернативы вы не можете полагаться на оверлей, но вместо этого переключаете класс на самом элементе всякий раз, когда "перебираете". Если вы кешируете ссылку на него, вы можете удалить класс, когда "вымыть", прополоскать, повторить. Я буду играть с идеей немного больше, чтобы понять, насколько она жизнеспособна.

Ответ 5

Я быстро посмотрел на вашу скрипку и развернул версию, которая работает на IE8, которую можно найти здесь. Как оказалось, indexOf, особенно в сочетании с побитовым ~, похоже на то, что IE, похоже, не очень увлекается, поэтому самое быстрое исправление кажется простым for(i=0;i<no.length;i++){}.

Как указывалось ранее, e.target не будет работать в IE, поскольку JScript вызывает это свойство srcElement. Это имеет смысл, поскольку события IE всегда появляются в документе, поэтому все события имеют источник, а не цель.

Самое большое различие можно найти в вашем CSS: снова IE - это боль: MS считает, что rgba не подходит по какой-либо причине. Кажется, они предпочитают писать CSS, о которых никто на земле не может понять:

filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0.3,startColorstr='#4c333333', endColorstr='#4c666666');

дает полупрозрачное серое наложение. Честно говоря, я нашел эту часть своего ответа здесь.

Когда дело доходит до событий указателя, единственный способ обойти это AFAIK - это еще один прослушиватель событий, который обрабатывает событие onclick:

function noClick(e)
{
    e = e || window.event;
    if (e.preventDefault)
    {
        e.preventDefault();
        e.stopPropagation();
        return false;
    }
    e.returnValue = false;
    e.cancelBubble = true;
    return false;
}

Надеюсь, это поможет вам на вашем пути...