1

I'm trying to add a click listener to the document when a dropdown is open, so that when you click anywhere else in the document it closes the dropdown and unbinds the click listener. I'm using some code from https://stackoverflow.com/a/17342418

I've discovered an issue though.

Binding:

$(document).bind('click', $scope.remindersDropdownHandler(event));

Handler:

$scope.remindersDropdownHandler = function(event) {
        var element = $("#remindersDropdown");
        var isClickedElementChildOfPopup = element
            .find(event.target)
            .length > 0;

        var buttonElement = $("#remindersButton");
        var isbuttonElement = buttonElement
            .find(event.target)
            .length > 0;

        if (isClickedElementChildOfPopup || isbuttonElement) {
            return;
        }

        $scope.openReminders = false;
        // $(document).unbind('click', $scope.remindersDropdownHandler);
    }

The handler itself is working just fine, however it only ever executes once! And that's immediately when you click the button that opens the drop-down and adds the bind. After that no matter where you click it never fires the listener again. (Trust me I've done a lot of debugging with console.log() over the past hour.)

However, if instead of referencing a function for the handler, I instead write it like such:

$(document).bind('click', function() {
                var element = $("#remindersDropdown");
                var isClickedElementChildOfPopup = element
                    .find(event.target)
                    .length > 0;

                var buttonElement = $("#remindersButton");
                var isbuttonElement = buttonElement
                    .find(event.target)
                    .length > 0;

                if (isClickedElementChildOfPopup || isbuttonElement) {
                    return;
                }

                $scope.openReminders = false;
            });

That works, and each time I click somewhere on the document it correctly executes the handler and closes the drop-down. The problem is because I haven't referenced the handler via a variable, I can't unbind it, so the handler is permanently attached. I need to be able to unbind it so that my site doesn't get overloaded with click listeners on the document.

So my issues are:

1) When I reference $scope.remindersDropdownHandler() as the handler for my click listener, why does it only fire once and then never again?

2) How can I fix up my code so that I bind the appropriate function for the click listener, and then unbind it when I choose to do so?

Note: In the example code I'd commented out the // $(document).unbind('click', $scope.remindersDropdownHandler); just to reinforce that there was no code that was immediately unbinding my click listener.


Solved: A user on Reddit pointed out that removing (event) from the specified handler in the bind would allow it to work. https://www.reddit.com/r/angularjs/comments/3fypck/help_issue_with_binding_and_unbinding_a_click/cttr0bw

I.e. converting

$(document).bind('click', $scope.remindersDropdownHandler(event));

to

$(document).bind('click', $scope.remindersDropdownHandler);
Cœur
  • 37,241
  • 25
  • 195
  • 267
  • It was calling the function, not passing it as parameter ... And as this function return nothing, it was not binding anything on the `click` . You can see how you wrote the `unbind` in the first code snippet. – Hacketo Aug 07 '15 at 07:42
  • That kinda makes sense, thank you. – Simon Hales Aug 08 '15 at 02:00

0 Answers0