Затенить всю страницу, отобразить выбранные элементы при наведении

Я пытаюсь сделать инструмент проверки страницы, где:

  • Вся страница заштрихована
  • Наведенные элементы не затенены.

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

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

$(function() {
    window.alert('started');
    $('<div id="overlay" />').hide().appendTo('body').fadeIn('slow');


    $("p").hover(
        function () {
            $(this).css( {"z-index":5} );
        }, 
        function () {
            $(this).css( {"z-index":0} );
        }
    );

В качестве альтернативы JQueryTools имеет инструмент «разоблачения» и «маски», который я пробовал с кодом ниже:

$(function() {
    $("a").click(function() {
         alert("Hello world!");
    });

    // Mask whole page
    $(document).mask("#222");

    // Mask and expose on however / unhover 
    $("p").hover(
        function () {
            $(this).expose();
        }, 
        function () {
            $(this).mask();
        }
    );

}); 

Наведение не работает, если я не отключу начальную маскировку страницы. Любые мысли о том, как лучше всего добиться этого, с помощью простого JQuery, инструментов JQuery или какой-либо другой техники? Спасибо!


person mikemaccana    schedule 13.01.2011    source источник


Ответы (2)


Что вы можете сделать, так это сделать копию элемента и вставить его обратно в DOM за пределами вашего наложения (с более высоким z-индексом). Для этого вам нужно рассчитать его положение, но это не так уж сложно.

Вот рабочий пример.

При написании этого я заново узнал тот факт, что что-то с нулевой непрозрачностью не может вызвать событие. Поэтому вы не можете использовать .fade(), вы должны специально установить непрозрачность на ненулевое, но очень маленькое число.

$(document).ready(function() { init() })

function init() {
    $('.overlay').show()
    $('.available').each(function() {
       var newDiv = $('<div>').appendTo('body');
       var myPos = $(this).position()  
       newDiv.addClass('available')
       newDiv.addClass('peek')
       newDiv.addClass('demoBorder')                
       newDiv.css('top',myPos.top+'px')
       newDiv.css('left',myPos.left+'px')
       newDiv.css('height',$(this).height()+'px')
       newDiv.css('width',$(this).width()+'px')  
       newDiv.hover(function()
          {newDiv.addClass('full');newDiv.stop();newDiv.fadeTo('fast',.9)},function()
          {newDiv.removeClass('full');newDiv.fadeTo('fast',.1)})   
    })  
}
person Diodeus - James MacFarlane    schedule 13.01.2011
comment
Спасибо. Но как я могу навести курсор на элемент, если наложение блокирует выделение? - person mikemaccana; 13.01.2011
comment
Когда вы загружаете страницу, найдите все элементы, подходящие для эффекта. Создайте пустой DIV поверх оверлея в той же позиции с теми же размерами. Подключите к ним событие, которое раскроет содержимое. - person Diodeus - James MacFarlane; 13.01.2011
comment
Ага. Поместите границу на них, чтобы проверить, чтобы вы могли сказать, где они находятся. - person Diodeus - James MacFarlane; 13.01.2011
comment
Я думаю, что я не совсем понимаю, как div верхнего уровня — тот, который будет перехватывать события наведения — может прикреплять эти события к соответствующему слою нижнего уровня. Должна ли быть копия 1:1 каждого элемента нижнего уровня поверх оверлея? Спасибо за ваши мысли. - person mikemaccana; 14.01.2011
comment
Вот, я думал, что на самом деле построю его, просто для удовольствия. jsfiddle.net/ByEt5/1 - person Diodeus - James MacFarlane; 14.01.2011
comment
Спасибо, код делает его более понятным. Хотите добавить его в свой ответ, чтобы другие могли увидеть его в будущем? Тогда я вознагражу вас вкусной кармой, добрый господин. - person mikemaccana; 15.01.2011

Извините за синтаксис прототипа, но это может дать вам хорошую идею.

function overlay() {
  var div = document.createElement('div');
  div.setStyle({
    position: "absolute",
    left: "0px",
    right: "0px",
    top: "0px",
    bottom: "0px",
    backgroundColor: "#000000",
    opacity: "0.2",
    zIndex: "20"
  })
  div.setAttribute('id','over');
  $('body').insert(div);
}

$(document).observe('mousemove', function(e) {
  var left = e.clientX,
      top = e.clientY,
      ele = document.elementFromPoint(left,top);
      //from here you can create that empty div and insert this element in there
})

overlay();
person Madison Williams    schedule 13.01.2011
comment
Спасибо. Оверлейная часть очевидна, но не могли бы вы объяснить остальное? Что заставляет движение мыши определяться как воздействующее на элемент, а не на оверлей? - person mikemaccana; 13.01.2011