ionic-framework: bug: ng-click handlers called twice on IE

Type: <span ionic-type>bug</span>

Platform: <span ionic-platform>windows</span>

<span ionic-description>To reproduce the duplicate handlers on Internet Explorer, open http://codepen.io/vjrantal/pen/GgNdVj with IE11 and click the show/alert/confirm buttons. The actual (problematic) behavior is that the popups gets triggered twice, while the expected behavior is that they get triggered once.

The same actual behavior can be reproduced on desktop IE11 and the IE mobile on Windows Phone 8.1. Tip: If you don’t have Windows and IE installed, you can use https://remote.modern.ie to test on OS X, iOS or Android.

The code in the the codepen logs the events the handlers get an you see something like this in the IE F12 developer tools console:

[object MouseEvent]
[object PointerEvent]
</span>

<span is-issue-template></span>

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 23 (3 by maintainers)

Commits related to this issue

Most upvoted comments

@jdnichollsc try to add type="button" to the button element. As @cverb pointed in this SO issue the default behaviour is submit and apparently that messes with the code. At least my issue was fixed.

I confirm that the bug append in IE11. Replacing <button> by <a class="button"> works but would be better to handle it in the lib.

My solution is to overwrite the ng-click handling and simply drop the second event:

ionic.Platform.isIE = function() {
  return ionic.Platform.ua.toLowerCase().indexOf('trident') > -1;
}

if (ionic.Platform.isIE()) {
  angular.module('ionic')
    .factory('$ionicNgClick', ['$parse', '$timeout', function($parse, $timeout) {
      return function(scope, element, clickExpr) {
        var clickHandler = angular.isFunction(clickExpr) ? clickExpr : $parse(clickExpr);

        element.on('click', function(event) {
          scope.$apply(function() {
            if (scope.clicktimer) return; // Second call
            clickHandler(scope, {$event: (event) });
            scope.clicktimer = $timeout(function() { delete scope.clicktimer; }, 1, false);
          });
        });

        // Hack for iOS Safari's benefit. It goes searching for onclick handlers and is liable to click
        // something else nearby.
        element.onclick = function(event) {};
      };
    }]);
}

The magic is around the clicktimer part.