Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/466.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript event.target在手机上的工作方式是否不同?_Javascript_Jquery_Javascript Events - Fatal编程技术网

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

Javascript event.target在手机上的工作方式是否不同?,javascript,jquery,javascript-events,Javascript,Jquery,Javascript Events,我目前正在创建一个带有“溢出”菜单的工具栏组件。当有人在菜单外单击时,我希望菜单关闭,因此我在文档中附加了一个简单的单击处理程序,用于检查单击的目标是在菜单内还是在菜单外。支票如下所示: var eventOutsideTarget = (overflowEl[0] !== event.target) && (overflowEl.find(event.target).length === 0); 因此,这在我的电脑上的Chrome中的所有情况下都有效。如果您在菜单外

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

var eventOutsideTarget = (overflowEl[0] !== event.target) 
    && (overflowEl.find(event.target).length === 0);
因此,这在我的电脑上的Chrome中的所有情况下都有效。如果您在菜单外单击,它将设置为true。如果单击另一个菜单打开,则原始菜单将关闭,新菜单将按预期打开

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

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

这在桌面上找不到该元素,但在移动设备上,即使您在另一个菜单中单击,它也会计算为true

这对我来说似乎是一个bug,但奇怪的是,它发生在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();

        }


    };


})
angular.module('s4p.directives')。directive('s4pToolbar',function($compile,$document){
返回{
限制:'E',
作用域:{},
控制器:“s4pToolbarCtrl”,
是的,
模板:“”
'' + 
'' + 
'' +
''
,
链接:功能(范围、元素、属性、控制器、转置){
//将工具栏的内容复制到模板的两个插槽中
转移(范围、功能(克隆){
元素。查找(“[transclude main]”)。替换为(克隆);
});
转移(范围、功能(克隆){
元素。查找(“[transclude overflow]”)。替换为(克隆);
});
//处理单击页面上除溢出之外的任何位置以关闭它。
var overflowEl=element.find('s4p-toolbar-overflow-button');
var documentClickHandler=函数(事件){
var eventOutsideTarget=(overflowEl[0]!==event.target)和&(overflowEl.find(event.target).length==0);
if(事件外部目标){
作用域:$apply(函数(){
scope.overflowOpen=false;
});
}
};
$document.on(“单击”,documentClickHandler);
作用域:“$destroy”,函数(){
$document.off(“单击”,documentClickHandler);
});
//更新所有截面的可见性
controller.updateSectionsVisibility();
}
};
})

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

问题是,当您单击另一个菜单按钮时,对文档体的单击根本没有注册,尽管单击菜单按钮会触发并打开菜单,但对文档体的单击会被忽略,尽管在单击文档的其他部分时它确实起作用

问题是这条线

$document.on("click", documentClickHandler);
必须是这个

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

我仍然不完全理解为什么,或者为什么原始版本可以在页面上的大多数元素上工作(可能是没有自己事件的元素),但它可以工作。向前来寻求原始问题答案的任何人致歉。

您能创建一个JSFIDLE或plnkr来演示吗?这将非常困难,因为它是一个大型的JS应用程序。我希望有人能从我的描述中认识到这个问题。你能包括
$(document.click()
overflowEl
声明,
html
有问题的部分吗?没有试过angular.js,但注意到
$document.off(“click”,documentClickHandler)js
中进行code>和
克隆
。是
.off()
删除
单击
处理程序吗?哪里定义了
clone
?clone是提供给transclusion函数的一个参数,它基本上是呈现到HTML中的模板。禁用仅当组件从dom中删除时才删除单击处理程序,以便主体上的单击事件处理程序不会孤立。