event.target 在手机上的工作方式是否不同?
Does event.target work differently on mobiles?
我目前正在创建一个带有 "overflow" 菜单的工具栏组件。当有人在菜单外单击时,我希望菜单关闭,因此我在文档中附加了一个简单的单击处理程序,用于检查单击目标是在菜单内还是菜单外。支票如下所示:
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
。
这在桌面上找不到该元素,但在移动设备上它的计算结果为真,即使您在不同的菜单中单击也是如此。
这对我来说似乎是一个错误,但奇怪的是它发生在 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="{"is-open":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);
我仍然不完全理解为什么,或者为什么原始版本适用于页面上的大多数元素(也许是没有自己事件的元素?),但它确实有效。对来这里寻找原始问题答案的任何人表示歉意。
我目前正在创建一个带有 "overflow" 菜单的工具栏组件。当有人在菜单外单击时,我希望菜单关闭,因此我在文档中附加了一个简单的单击处理程序,用于检查单击目标是在菜单内还是菜单外。支票如下所示:
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
。
这在桌面上找不到该元素,但在移动设备上它的计算结果为真,即使您在不同的菜单中单击也是如此。
这对我来说似乎是一个错误,但奇怪的是它发生在 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="{"is-open":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);
我仍然不完全理解为什么,或者为什么原始版本适用于页面上的大多数元素(也许是没有自己事件的元素?),但它确实有效。对来这里寻找原始问题答案的任何人表示歉意。