Mouseover срабатывает на абсолютном позиционном div - PullRequest
2 голосов
/ 21 апреля 2010

Объектив

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

Частичное решение

Имеется один <span>, который абсолютно позиционирован и скрыт.Когда ячейка таблицы _previewable наведена, <span> перемещается в правильное место и отображается.Этот <span> также перемещается в DOM как дочерний элемент ячейки таблицы _previewable.Это позволяет обработчику кликов, прикрепленному к <span>, найти родителя _previewable и получить информацию из его объекта jquery data (), который используется для заполнения содержимого диалога.

Вот оченьупрощенная версия моего HTML:

<body>
    <span id="options">
        <a class="ui-state-default ui-corner-all">
            <span class="ui-icon ui-icon-search"></span>
            Preview
        </a>
    </span>
    <table>
         <tr>
             <td class="_previewable">
                 <img scr="user_1.png"/>
                 <span>Bob Smith</span>
             </td>
        </tr>
   </table>
</body>

И этот CSS:

#options {
    position: absolute;
    display: none;
}

С этим кодом jQuery:

var $options = $('#options');
$options.click(function() {
    $item = $(this).parents("._previewable");
    // Show popup based on data in $item.data("id");
    Layout.renderPopup($item.data("id"),$item.data("popup"));               
});

$('._previewable').live('mouseover mouseout',function(event) {
    if (event.type == 'mouseover') {
        var $target = $(this);
        var $parent = $target.offsetParent()[0];

        var left = $parent.scrollLeft + $target.position().left 
            + $target.outerWidth() - $options.outerWidth() + 1;
        var top = $parent.scrollTop + $target.position().top + 2;

        $options.appendTo($target);
        $options.css({
            "left": left + "px",
            "top": top + "px"
        }).show();
    }
    else {
        // On mouseout, $options continues to be a child of $(this)
        $options.hide();
    }
});     

Задача

ЭтоРешение работает отлично, пока содержимое моей таблицы не будет перезагружено или изменено через AJAX.Поскольку <span> был перемещен из <body> как дочерний элемент ячейки, он выбрасывается и заменяется во время вызова AJAX.Поэтому моя первая мысль состоит в том, чтобы переместить <span> назад к телу при наведении мыши на ячейку таблицы, например:

    else {
        // On mouseout, $options is moved back to be a child of body
        $options.appendTo("body");
        $options.hide();
    }

Однако при этом <span> исчезает, как только при наведении мыши,Кажется, что событие mouseout вызывается на _previewable, когда мышь перемещается в <span>, хотя <span> является дочерним элементом _previewable и полностью отображается в границах ячейки таблицы _previewable.На данный момент я проверил это только в Chrome.

Вопросы

  1. Почему mouseout вызывается на _previewable, когда мышь все еще находится в пределах границиз _previewable?Это потому, что <span> абсолютно позиционирован?

  2. Как я могу выполнить эту работу, не воссоздавая <span> и его обработчик кликов при каждом обновлении таблицы AJAX?

Ответы [ 2 ]

5 голосов
/ 21 апреля 2010

Если вы измените ваши события, тогда все остальное, что у вас есть (добавление к <body>), будет работать так:

$('._previewable').live('mousenter mouseleave',function(event) {

В отличие от mouseover и mouseout, события mousenter и mouseleave не будут срабатывать при переходе к ребенку или от него, поэтому они будут вести себя так, как вы хотите в этом случае.

Хотя для чистоты я бы связал .live('mouseenter) и .live('mouseleave') по отдельности и удалил if(), гораздо проще посмотреть и увидеть, что происходит, хотя может быть только я:)

1 голос
/ 21 апреля 2010

Это похоже на большую работу, просто чтобы не иметь маленькое крошечное изображение в каждой ячейке. Вы на самом деле не получаете много, «повторно» используя только один экземпляр элемента. Браузерам нужно будет загрузить изображение только один раз. А с точки зрения производительности, работа с деревом DOM требует больше ресурсов, чем просто переключение свойства отображения выделенного элемента.

Самый простой подход может заключаться в том, чтобы поместить <span> в каждую ячейку, которую вы когда-либо распечатывали, а затем использовать CSS, чтобы скрыть / отобразить.

...