事件处理程序即使有事件委托也无法处理动态内容

问题描述 投票:0回答:1

我有两个 ModalPopups 第一个打开并有一个工具提示文本,用户可以使用“mouseenter”事件侦听器查看更多详细信息。 一旦用户通过三个按钮之一单击关闭模式,第二个 ModalPopup 将打开并显示另一个工具提示文本。 “mouseenter”上的工具提示文本在第二个 ModalPopup 中不起作用。 这是一个全新的 Modalpopup,尽管我尝试使用相同的模式但它仍然不起作用。

所以流程是: 用户单击按钮 -> 加载 -> 带有工具提示的 ModalPopup -> 用户单击 3 个选项中的 1 个按钮 -> Modalpopup 关闭 -> 加载 -> 带有工具提示的 ModalPopup 2 -> 等等...

所以它加载动态内容,然后使用委托来设置工具提示侦听器,然后关闭/删除该内容,然后加载更多动态内容,并再次尝试第二次使用委托的工具提示侦听器。

我试过在每个模态加载时完全删除工具提示,在重新绑定之前取消绑定模态加载上的所有内容,在重新绑定之前在工具提示代码中取消绑定,等等

有趣的是,当第二个模式弹出窗口打开时,如果我使用 chrome“检查元素”,工具提示将再次开始工作。

提示代码:

(function ($) {
    'use strict';
    $.fn.extend({
        jqToolTip: function () {
            var opts = {
                tooltipDiv: 'tooltipbox',
                tooltipFadeOut: 'tooltipFadeOut',
                tooltipBoxTop: 'tooltipbox-top',
                tooltipBoxRight: 'tooltipbox-right',
                tooltipBoxLeft: 'tooltipbox-left',
                tooltipBoxBottom: 'tooltipbox-bottom',
                tooltipBoxRed: 'tooltipbox-red',
                tooltipBoxBottomRed: 'tooltipbox-bottom-red',
                tooltipBoxTopRed: 'tooltipbox-top-red',
                tooltipBoxLeftRed: 'tooltipbox-left-red',
                tooltipBoxRightRed: 'tooltipbox-right-red'
            };
            const classSelector = $(this).attr("class").split(/\s+/).find(x => x.includes("tooltip"));

            $(document.body).live('mouseenter', `.${classSelector}`, function (e) {
                var color = $(this).data("tooltip-color");
                var arrowOffsetx = $(this).data("tooltip-arrow-offset-x");
                var arrowOffsety = $(this).data("tooltip-arrow-offset-y");
                var helptext = $(this).data("tooltip");
                var direction = $(this).data("tooltip-direction");
                if (direction == null) direction = 'right';
                var top = $(this).offset().top;
                var left = $(this).offset().left;
                var offsetX = $(this).data("tooltip-offset-x");
                if (offsetX == null) offsetX = 0;
                var offsetY = $(this).data("tooltip-offset-y");
                if (offsetY == null) offsetY = 0;
                //console.log(top,left,$(this).width());
                var cssAdd = '';
                var cssColorAdd = '';
                $('.' + opts.tooltipDiv).removeClass(opts.tooltipFadeOut + ' '
                    + opts.tooltipBoxBottom + ' '
                    + opts.tooltipBoxRight + ' '
                    + opts.tooltipBoxTop + ' '
                    + opts.tooltipBoxLeft + ' '
                    + opts.tooltipBoxRed + ' '
                    + opts.tooltipBoxBottomRed + ' '
                    + opts.tooltipBoxTopRed + ' '
                    + opts.tooltipBoxLeftRed + ' '
                    + opts.tooltipBoxRightRed).html(helptext);
                switch (direction) {
                    case 'top': // top
                        top = top - 48 + offsetY;
                        left = left + $(this).width() / 2 - 25 + offsetX;
                        cssAdd = opts.tooltipBoxTop;
                        cssColorAdd = opts.tooltipBoxTopRed;
                        break;
                    case 'right': // right
                        top = top + $(this).height() / 2 - 13 + offsetY;
                        left = left + $(this).width() + 20 + offsetX;
                        cssAdd = opts.tooltipBoxRight;
                        cssColorAdd = opts.tooltipBoxRightRed;
                        break;
                    case 'bottom': // bottom
                        top = top + $(this).height() + 14 + offsetY;
                        left = left + $(this).width() / 2 - 28 + offsetX;
                        cssAdd = opts.tooltipBoxBottom;
                        cssColorAdd = opts.tooltipBoxBottomRed;
                        break;
                    case 'left': // left
                        top = top + $(this).height() / 2 - 13 + offsetY;
                        left = left - $('.' + opts.tooltipDiv).width() - 16 + offsetX;
                        cssAdd = opts.tooltipBoxLeft;
                        cssColorAdd = opts.tooltipBoxLeftRed;
                        break;
                }
                //console.log(left);
                if (color == 'red') {
                    $('.' + opts.tooltipDiv).addClass(opts.tooltipBoxRed);
                    $('.' + opts.tooltipDiv).addClass(cssColorAdd);
                }
                if (typeof(arrowOffsetx) != "undefined" && arrowOffsetx.length > 0) {
                    $('.' + opts.tooltipDiv)
                        .addClass('tooltipBoxArrowOffsetX')
                        .append('<style>.tooltipBoxArrowOffsetX::after,.tooltipBoxArrowOffsetX::before{left:' + arrowOffsetx + ' !important;}</style>')
                }
                if (typeof (arrowOffsety) != "undefined" && arrowOffsety.length > 0) {
                    $('.' + opts.tooltipDiv)
                        .addClass('tooltipBoxArrowOffsetY')
                        .append('<style>.tooltipBoxArrowOffsetY::after,.tooltipBoxArrowOffsetY::before{left:' + arrowOffsety + ' !important;}</style>');
                }
                $('.' + opts.tooltipDiv).addClass(cssAdd).css({ left: left, top: top }).fadeIn();
            })
            $(document.body).live('mouseleave', `.${classSelector}`, function (e) {
                $('.' + opts.tooltipDiv).addClass(opts.tooltipFadeOut);
            })
            $(document.body).live('click', `.${classSelector}`, function (e) {
                var ishide = $(this).data("tooltip-onclickhide") == '1';
                if (ishide) $('.' + opts.tooltipDiv).addClass(opts.tooltipFadeOut);
            })

            return this;
        },
    })
})(jQuery);
javascript jquery event-handling mouseenter dynamic-html
1个回答
0
投票

“mouseenter”和“mouseleave”事件的事件委托只能在捕获阶段完成。

替换

$(document.body).live('mouseenter', `.${classSelector}`, function (e){}

document.body.addEventListener('mouseenter', function(e) {
    if (e.target.matches(`.${classSelector}`)) {
        // code here
        // use e.target instead of this
    }
}, true);

同样适用于“mouseleave”。

© www.soinside.com 2019 - 2024. All rights reserved.