单击 div 的 OUTSIDE 时不确定如何隐藏 div [英] Not sure how to hide a div when clicking OUTSIDE of the div

查看:27
本文介绍了单击 div 的 OUTSIDE 时不确定如何隐藏 div的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是这个问题的后续问题:带有焦点的AngularJS输入会杀死列表的ng-repeat过滤器

This is a follow-up question to this question: AngularJS input with focus kills ng-repeat filter of list

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

Basically my code is using AngularJS to pop-out a div (a drawer) on the right for filtering a list of things. Most times this is used the UI is blocked so clicking on that blocking div closes the drawer. But in some cases we don't block the UI and need to allow the user to click outside of the drawer to cancel the search or select something else on the page.

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

My initial thought was to attach a window.onclick handler when the drawer opens and if anything is clicked other than the drawer it should close the drawer. That's how I would do it in a pure JavaScript app. But in Angular it is being a bit more difficult.

这是我基于@Yoshi 的 jsBin 示例的 jsfiddle 示例:http://jsfiddle.net/tpeiffer/kDmn8/

Here is a jsfiddle with a sample that I based on @Yoshi's jsBin example: http://jsfiddle.net/tpeiffer/kDmn8/

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

The relevant piece of code from this sample is below. Basically if the user clicks outside of the drawer I invoke $scope.toggleSearch so that $scope.open is set back to false.

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

The code works, and even though the $scope.open goes from true to false it doesn't modify the DOM. I'm sure this has something to do with the lifecycle of events or perhaps when I modify $scope (since it is from a separate event) that it is a copy and not the original...

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

The ultimate goal on this will be for it to be a directive for ultimate reusability. If anyone can point me in the right direction to do that I would be grateful.

$scope.toggleSearch = function () {

    $scope.open = !$scope.open;

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

function closeSearchWhenClickingElsewhere(event, callbackOnClose) {

    var clickedElement = event.target;
    if (!clickedElement) return;

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

}

推荐答案

抽屉没有关闭,因为单击事件发生在摘要循环之外,而 Angular 不知道 $scope.open 已更改.要修复它,您可以在 $scope.open 设置为 false 后调用 $scope.$apply(),这将触发摘要循环.

The drawer is not closing because the click event occurs outside the digest cycle and Angular doesn't know that $scope.open has changed. To fix it you can call $scope.$apply() after $scope.open is set to false, this will trigger the digest cycle.

$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. 
    }
};

这是您的小提琴.

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

I was also trying to create a directive for the search drawer, if it helps (it needs some fixes :)). Here is a JSBin.

这篇关于单击 div 的 OUTSIDE 时不确定如何隐藏 div的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆