Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.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 不确定单击div外部时如何隐藏div_Javascript_Angularjs_Angularjs Scope - Fatal编程技术网

Javascript 不确定单击div外部时如何隐藏div

Javascript 不确定单击div外部时如何隐藏div,javascript,angularjs,angularjs-scope,Javascript,Angularjs,Angularjs Scope,这是该问题的后续问题: 基本上,我的代码是使用AngularJS在右边弹出一个div(抽屉)来过滤一个列表。大多数情况下,用户界面被阻塞,因此点击阻塞div关闭抽屉。但在某些情况下,我们不会阻止用户界面,需要允许用户在抽屉外单击以取消搜索或在页面上选择其他内容 我最初的想法是在抽屉打开时附加一个window.onclick处理程序,如果单击抽屉以外的任何东西,它应该关闭抽屉。这就是我在纯JavaScript应用程序中的做法。但从角度来说,这有点困难 下面是一个JSFIDLE,其中包含一个基于@Y

这是该问题的后续问题:

基本上,我的代码是使用AngularJS在右边弹出一个div(抽屉)来过滤一个列表。大多数情况下,用户界面被阻塞,因此点击阻塞div关闭抽屉。但在某些情况下,我们不会阻止用户界面,需要允许用户在抽屉外单击以取消搜索或在页面上选择其他内容

我最初的想法是在抽屉打开时附加一个window.onclick处理程序,如果单击抽屉以外的任何东西,它应该关闭抽屉。这就是我在纯JavaScript应用程序中的做法。但从角度来说,这有点困难

下面是一个JSFIDLE,其中包含一个基于@Yoshi的jsBin示例的示例:

下面是这个示例中的相关代码。基本上,如果用户在抽屉外单击,我将调用$scope.toggleSearch,以便将$scope.open设置回false

代码可以工作,即使$scope.open从true变为false,它也不会修改DOM。我确信这与事件的生命周期有关,或者当我修改$scope(因为它来自一个单独的事件)时,它是一个副本而不是原始的

这方面的最终目标是使其成为最终可重用性的指导。如果有人能为我指出正确的方向,我将不胜感激

$scope.toggleSearch = function () {

    $scope.open = !$scope.open;

    if ($scope.open) {
        $scope.$window.onclick = function (event) {
            closeSearchWhenClickingElsewhere(event, $scope.toggleSearch);
        };
    } else {
        $scope.$window.onclick = null;
    }
};


抽屉未关闭,因为单击事件发生在摘要周期之外,Angular不知道$scope.open已更改。要解决此问题,可以在$scope.open设置为false后调用$scope.$apply(),这将触发摘要循环

$scope.toggleSearch = function () {
    $scope.open = !$scope.open;
    if ($scope.open) {
        $scope.$window.onclick = function (event) {
            closeSearchWhenClickingElsewhere(event, $scope.toggleSearch);
        };
    } else {
        $scope.open = false;
        $scope.$window.onclick = null;
        $scope.$apply(); //--> trigger digest cycle and make angular aware. 
    }
};
这是你的护照


我还试图为搜索抽屉创建一个指令,如果它有帮助的话(它需要一些修复:))。这是一本书

我找不到一个100%满意的解决方案,这就是我使用的:

<div class="options">
    <span ng-click="toggleAccountMenu($event)">{{ email }}</span>
    <div ng-show="accountMenu" class="accountMenu">
        <a ng-click="go('account')">Account</a>
        <a ng-click="go('logout')">Log Out</a>
    </div>
</div>
这将使用jQuery进行子检查,但如果需要的话,您可能不需要这样做


我在其他人的版本中遇到了一些严重的错误,比如试图调用$apply(),但它已经在一个周期中,我的版本阻止了传播并对$apply()进行了安全检查。我建议添加$event.stopPropagation();在视图上,在ng上单击鼠标右键。您不需要使用jQuery

<button ng-click="toggleSearch();$event.stopPropagation();">toggle</button>

如果单击按钮关闭抽屉/弹出窗口,并且按钮位于抽屉/弹出窗口之外,则接受的答案将抛出错误,因为
$apply()
将执行两次

这是一个简化版本,不需要再次调用整个
toggleSearch()
函数,并防止双重
$apply()


非常感谢@Bertrand!那美元正是我错过的!我在使用Angular(专业)的第5天-仍然是一些关键概念,我需要一段时间才能熟悉!希望我能在不久的将来回报你!我将检查该指令的JSBin,并在它完成并工作后发布结果。
$scope.accountMenu = false;
$scope.toggleAccountMenu = function(e){
    if(e) e.stopPropagation();
    $scope.accountMenu = !$scope.accountMenu;
    if ($scope.accountMenu) {
        $window.onclick = function(e) {
            var target = $(e.target);
            if(!target) return;
            if(!target.hasClass('accountMenu') && !target.is($('.accountMenu').children())){
                $scope.toggleAccountMenu();
            }               
        };
    } else if (!e) {
        $window.onclick = null;
        $scope.$apply();
    }
}
<button ng-click="toggleSearch();$event.stopPropagation();">toggle</button>
$scope.toggleSearch = function () {
    $window.onclick = null;
    $scope.menuOpen = !$scope.menuOpen;

    if ($scope.model.menuOpen) {
        $window.onclick = function (event) {
            $scope.menuOpen = false;
            $scope.$apply();
        };
    }
};
$scope.toggleSearch = function() {

  $scope.open = !$scope.open;

  if ($scope.open) {
    $window.onclick = function(event) {
      var clickedElement = event.target;
      if (!clickedElement) return;

      var clickedOnSearchDrawer = elementClasses.contains('handle-right') || elementClasses.contains('drawer-right') || (clickedElement.parentElement !== null && clickedElement.parentElement.classList.contains('drawer-right'));

      if (!clickedOnSearchDrawer) {
        $scope.open = !$scope.open;
        $window.onclick = null;
        $scope.$apply();
      }
    }
  } else {
    $window.onclick = null;
  }
};