简体   繁体   中英

How to close div when div loses focus?

I made a simple plunkr here http://plnkr.co/edit/zNb65ErYH5HXgAQPOSM0?p=preview

I created a little datepicker I would like this to close itself when you focus out of it (focusout of datepicker) if I put blur on input I'm unable to use the datepicker, if I put focusout event on datepicker it doesn't works

I also tried:

angular.element(theCalendar).bind('blur', function () {
    $scope.hideCalendar();
});

but it doesn't work.

Any clue?

this is because you are removing the item before you get a chance to do anything, here is a working example:

http://plnkr.co/edit/mDfV9NLAQCP4l7wHdlfi?p=preview

just add a timeout:

thisInput.bind('blur', function () {
  $timeout(function(){
    $scope.hideCalendar();
  }, 200);
});

have you considered using existing datepickers? like angularUI or angular-strap: http://mgcrea.github.io/angular-strap/##datepickers

Update:

Not a complete solution, but should get you quite closer:

    angular.element($document[0].body).bind('click', function(e){
      console.log(angular.element(e.target), e.target.nodeName)
      var classNamed =  angular.element(e.target).attr('class');
      var inThing = (classNamed.indexOf('datepicker-calendar') > -1);
      if (inThing || e.target.nodeName === "INPUT") {
        console.log('in');
      } else {
        console.log('out');
          $timeout(function(){
            $scope.hideCalendar();
          }, 200);
      }
    });

http://plnkr.co/edit/EbQl5xsCnG837rAEhBZh?p=preview

What you want to do then is to listen for a click on the page, and if the click is outside of the calendar, then close it, otherwise do nothing. The above only takes into account that you are clicking on something that has a class name which includes datepicker-calendar, you will need to adjust it so that clicking within the calendar doesn't close it as well.

How about closing on mouseout?

You need to cancel the close if you move to another div in the calendar though:

    //get the calendar as element
    theCalendar = element[0].children[1];

    // hide the calendar on mouseout
    var closeCalendarTimeout = null;
    angular.element(theCalendar).bind('mouseout', function () {
      if ( closeCalendarTimeout !== null )
        $timeout.cancel(closeCalendarTimeout);
      closeCalendarTimeout = $timeout(function () {
        $scope.hideCalendar();
      },250)
    });
    angular.element(theCalendar).bind('mouseover', function () {
      if ( closeCalendarTimeout === null ) return
      $timeout.cancel(closeCalendarTimeout);
      closeCalendarTimeout = null;
    });

EDIT

Adding a tabindex attribute to a div causes it to fire focus and blur events.

, htmlTemplate = '<div class="datepicker-calendar" tabindex="0">' +

angular.element(theCalendar).bind('blur', function () {
  $scope.hideCalendar();
});

So, i know it probably is not the best practice or the best way to do this, but at the end i fixed and got what i need using this:

thisInput.bind('focus click', function bindingFunction() {

          isMouseOnInput = true;
          $scope.showCalendar();
          angular.element(theCalendar).triggerHandler('focus');
        });
        thisInput.bind('blur focusout', function bindingFunction() {

          isMouseOnInput = false;
        });

        angular.element(theCalendar).bind('mouseenter', function () {

          isMouseOn = true;
        });

        angular.element(theCalendar).bind('mouseleave', function () {

          isMouseOn = false;
        });

        angular.element($window).bind('click', function () {

          if (!isMouseOn && !isMouseOnInput) {

            $scope.hideCalendar();
          }
        });

I setted up some boolean vars to check where mouse is when you click the page and it works like a charm if you have some better solution that works , please let me know, but this actually fixed all.

I accept this as the answer but i thank all the guys on this page!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM