2016-02-26 35 views
4

我目前正在創建一個帶有「溢出」菜單的工具欄組件。當有人在菜單外單擊時,我想關閉菜單,因此我在文檔上附加了一個簡單的點擊處理程序,用於檢查點擊的目標是在菜單內還是在菜單外。檢查如下所示:event.target在手機上的工作方式有所不同嗎?

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,即使您在不同的菜單中單擊。

這對我來說似乎是一個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(); 

     } 


    }; 


}) 
+0

你可以創建一個jsfiddle或plnkr來演示嗎? – guest271314

+0

這將是非常困難的,因爲它是一個大型的Angular JS應用程序。我希望有人能從我的描述中認識到他的問題。 – jonhobbs

+0

您可以在問題中包含'$(document).click()','overflowEl'聲明,'html'部分嗎? – guest271314

回答

0

OK,所以答案是無關event.target,雖然這並不能阻止我浪費3小時認爲它是!

問題在於,當您單擊另一個菜單按鈕時,文檔正文上的點擊根本沒有註冊,但點擊菜單按鈕時點擊並打開菜單,文檔正文上的點擊被忽略,儘管在點擊文檔的其他部分時確實有效。

解決方法是此行

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

是這個必要......

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

我還是不完全理解爲什麼,爲什麼還是原來的版本上的大多數元素上工作該頁面(也許沒有自己的事件?),但它的作品。對任何來到這裏尋找原始問題答案的人道歉。

相關問題