简体   繁体   中英

Does event.target work differently on mobiles?

I'm currently creating a toolbar component with an "overflow" menu. When somebody clicks outside the menu, I want the menu to close, so I've attached a simple click handler to the document which checks to see if the target of the click is inside the menu or outside of it. The check looks like this:

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

So, this works in all instances in Chrome on my PC. If you click outside of the menu it is set to true. If you click on another menu to open, then the original menu closes and the new one opens, as expected.

On Chrome Android and iOS Safari the behavior is different though. If you click anywhere on the page that is not a menu it closes any open menus; however if you click on a different menu it opens the new one, but the old one is still opening.

I suspect this is to do with the second part of the check: overflowEl.find(event.target).length === 0 .

This does not find the element on desktop, but on mobile it evaluates to true, even if you're clicking in a different menu.

This seems like a bug to me, but it is strange that it is happening on Android and iOS but not on Chrome desktop.

Any help would be greatly appreciated.

Edit: Adding a bit more of my code for completeness

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();

        }


    };


})

OK, so the answer was nothing to do with event.target, although that didn't stop me wasting 3 hours thinking it was!

The problem was that clicks on the document body simply weren't registering when you clicked on another menu button, although the click on the menu button was firing and opening the menu, the click on the document body was being ignored, despite the fact that it did work when clicking on other parts of the document.

The fix is that this line

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

needed to be this...

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

I still don't fully understand why, or why the original version worked on most elements on the page (maybe elements that didn't have their own events?), but it works. Apologies to anybody who comes here looking for an answer to the original question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM