javascript - 监听在页面上多次使用的点击外部指令

标签 javascript angularjs

我有一个自定义指令,其内部有一个弹出菜单,当我单击指令内的按钮时应显示该菜单,并且每当我单击指令外部时应关闭该菜单。

我将该指令用于列表中的多个项目,因此页面上始终会有多个该指令。

现在我有一些代码正在监听文档的点击。我已将此代码移至我的 Controller ,因为它根据页面上的指令数量被评估 x 次。

我可以做一些聪明的事情来将所有代码保留在指令中吗?

// BOTTOM OF MY CONTROLLER //

// function to be called when clicking outside the directive/menu
onDocumentClick = function(event){
// if not clicked on an .popup-btn then remove all classnames from popup-menu
activeNodes = document.getElementsByClassName("popup-menu active");
if(activeNodes.length >= 1){
    clicked_el = angular.element(event.target);
    if(!/^popup-btn|popup-menu/.test(clicked_el[0].className)){
        for (var i = 0; i < activeNodes.length; i++){
            activeNodes[i].className = "popup-menu";
            console.log(activeNodes[i]);
        }
    }
}
};

$document.on('click', onDocumentClick);
}]);

// END OF CONTROLLER //

//Directive
mealplan.directive('recipe', ['$document', function($document) {
return {
    restrict: 'AE',
    scope: {
        item: '=recipe' 
    },
    link: function(scope, elem, attrs) {
        // toggle the recipe menu
        scope.toggleMenu = function() {
            console.log("toggle menu");
            // loop throug all menus and reset their class names
            activeNodes = document.getElementsByClassName("popup-menu active");
            if(activeNodes.length >= 1){
                for (var i = 0; i < activeNodes.length; i++){
                    activeNodes[i].className = "popup-menu";
                    console.log(activeNodes[i]);
                }
            }
            // set the current 
            current = elem[0].getElementsByClassName("popup-menu")[0];
            current.className = "popup-menu active";
            console.log(current);
        };

        // initializes the states
        scope.init = function() {
            //scope.currentMenu = null;
        };

        scope.init();

    },
    templateUrl: 's/recipes/js/popupMenu-directive.html'
};
}]);

最佳答案

返回选项对象之前在指令中执行的代码将仅执行一次。

来自 Angular-UI documentation :

myApp.directive('uiJq', function InjectingFunction(){

    // === InjectingFunction === //
    // Logic is executed 0 or 1 times per app (depending on if directive is used).
    // Useful for bootstrap and global configuration
    // Do the binding here
    return {
        compile: function CompilingFunction($templateElement, $templateAttributes) {

            // Logic is executed once (1) for every instance of ui-jq

            return function LinkingFunction($scope, $linkElement, $linkAttributes) {
                // Logic is executed once (1) for every RENDERED instance.
            };
        }
    };
})

您可以在声明指令后绑定(bind)您的事件处理程序,并且它只会执行一次。

关于javascript - 监听在页面上多次使用的点击外部指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23560930/

相关文章:

javascript - $compile 不会将作用域变量插入 HTML

angularjs - 带有 AngularJS 的 KendoUI Treeview 取消选中复选框

javascript - 理解 JavaScript 语法

javascript - 如何将 DOM 状态重置为初始状态(首次收到页面时?)

javascript - angularjs - 将某些带有数据的输入正确设置为 $pristine 或未触及

java - 如何将谷歌应用程序引擎数据存储中的数据获取到客户端的 Angular js中?

javascript - 根据其他属性查询多维数组属性

javascript - AngularJS 1.2 到 1.3 clientWidth 不再正确

javascript - MongoDB 外壳 : Query BinData by Type

javascript - 如何在 Angular JS 中获得自动完成功能?