event.target在手机上的工作方式是否不同

Does event.target work differently on mobiles?

本文关键字:方式 是否 工作 target 手机 event      更新时间:2023-09-26

我目前正在创建一个带有"溢出"菜单的工具栏组件。当有人在菜单外单击时,我希望菜单关闭,因此我将一个简单的单击处理程序附加到文档,该处理程序检查单击目标是在菜单内还是菜单外。支票如下所示:

var eventOutsideTarget = (overflowEl[0] !== event.target) 
    && (overflowEl.find(event.target).length === 0);

因此,这适用于我PC上Chrome中的所有实例。如果在菜单外部单击,则设置为 true。如果单击另一个菜单打开,则原始菜单将关闭,新菜单将按预期打开。

在Chrome Android和iOS Safari上,行为是不同的。如果您单击页面上不是菜单的任意位置,则会关闭所有打开的菜单;但是,如果您单击其他菜单,它会打开新菜单,但旧菜单仍在打开。

我怀疑这与检查的第二部分有关:overflowEl.find(event.target).length === 0 .

这在桌面上找不到该元素,但在移动设备上,即使您单击其他菜单,它的计算结果也会为 true。

这对我来说似乎是一个错误,但奇怪的是它发生在 Android 和 iOS 上,而不是在 Chrome 桌面上。

任何帮助将不胜感激。

编辑:添加更多我的代码以保持完整性

angular.module('s4p.directives').directive('s4pToolbar', function ($compile, $document) {
    return {
        restrict: 'E',
        scope: {},
        controller: 's4pToolbarCtrl',
        transclude: true,
        template:   '<s4p-toolbar-main><div transclude-main></div></s4p-toolbar-main>' + 
                    '<s4p-toolbar-overflow-button ng-class="{&quot;is-open&quot;:overflowOpen}">' + 
                        '<s4p-button button-style="circle" icon="/images/iconSprite.svg#dot-menu" ng-click="toggleOverflow()"></s4p-button>' + 
                         '<s4p-toolbar-overflow ng-show="overflowOpen" class="ng-hide" ng-cloak><div transclude-overflow></div></s4p-toolbar-overflow>' +
                    '</s4p-toolbar-overflow-button>'

        ,
        link: function (scope, element, attrs, controller, transclude) {
            // Copy the contents of the toolbar into both slots in the template
            transclude(scope, function(clone) {
                element.find('[transclude-main]').replaceWith(clone);
            });
            transclude(scope, function(clone) {
                element.find('[transclude-overflow]').replaceWith(clone);
            });

            // Handle clicking anywhere on the page except the overflow to close it.
            var overflowEl = element.find('s4p-toolbar-overflow-button');
            var documentClickHandler = function (event) {
                var eventOutsideTarget = (overflowEl[0] !== event.target) && (overflowEl.find(event.target).length === 0);
                if (eventOutsideTarget) {
                    scope.$apply(function () {
                        scope.overflowOpen = false;
                    });
                }
            };
            $document.on("click", documentClickHandler);
                scope.$on("$destroy", function () {
                $document.off("click", documentClickHandler);
            });
            // Update the visibility of all the sections
            controller.updateSectionsVisibility();
        }

    };

})

好的,所以答案与 event.target 无关,尽管这并没有阻止我浪费 3 个小时来思考它!

问题是,当您单击另一个菜单按钮时,对文档正文的单击根本没有注册,尽管单击菜单

按钮正在触发并打开菜单,但对文档正文的单击被忽略,尽管它在单击文档的其他部分时确实有效。

解决方法是此行

$document.on("click", documentClickHandler);

需要这个...

$document.on("click touchstart", documentClickHandler);

我仍然不完全明白为什么,或者为什么原始版本适用于页面上的大多数元素(也许是没有自己事件的元素?),但它有效。向任何来这里寻找原始问题的答案的人道歉。