最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to prevent ng-click's triggering twice on label tag? - Stack Overflow

programmeradmin1浏览0评论

Angular's ng-click gets triggered twice when I click label which has input inside in it. I've tried $event.stopPropagation(); but didn't work. How do I solve this?

I've checked this question also: Angular.js ng-click events on labels are firing twice

<div class="list-group-item" ng-repeat="item in model.data">
  <form role="form" name="selectForm" novalidate>
    <label ng-click="$event.stopPropagation(); updateSelected();">
      <input type="checkbox" ng-model="chechkedSkins[item.id]" />
      <span>{{item.name}}</span>
    </label>
  </form>
</div>

Angular's ng-click gets triggered twice when I click label which has input inside in it. I've tried $event.stopPropagation(); but didn't work. How do I solve this?

I've checked this question also: Angular.js ng-click events on labels are firing twice

<div class="list-group-item" ng-repeat="item in model.data">
  <form role="form" name="selectForm" novalidate>
    <label ng-click="$event.stopPropagation(); updateSelected();">
      <input type="checkbox" ng-model="chechkedSkins[item.id]" />
      <span>{{item.name}}</span>
    </label>
  </form>
</div>
Share Improve this question edited Oct 30, 2019 at 12:31 Adrian Mole 51.8k191 gold badges58 silver badges94 bronze badges asked Sep 1, 2015 at 11:10 Barlas ApaydinBarlas Apaydin 7,31511 gold badges58 silver badges88 bronze badges 3
  • could you replicate the same on jsfiddle,jsfiddle.net – dreamweiver Commented Sep 1, 2015 at 11:13
  • $event.preventDefault(); ? – Claudio Bredfeldt Commented Sep 1, 2015 at 11:14
  • @ClaudioBredfeldt preventDefault breaks more mate, Adrian solved my problem, check the answers below. – Barlas Apaydin Commented Sep 1, 2015 at 11:22
Add a comment  | 

3 Answers 3

Reset to default 8

Use ng-change="updateSelected"

Use this only on the input since the change is triggered even if you click the label.

Well thats because label is the parent or container for the checkbox, so the click handler is attached to the complete container in your case, thereby whenever either label or checkbox is clicked, event is triggered.


Whats wrong with your approach:

  • Firstly never insert the input tags inside the label, thats not a good way to construct markup in html.In Angular.js this behaviour causes the click event to be triggered for both the tags. so to add a binding between input tag & label use the for attribute of label.
  • Using $event.stopPropagation() inside label actually stops all events from propagating/boiling to the top of the DOM from the label. this will not serve any purpose because the event would still propagate to the input with in the label.

I hope you can visualise what i'm saying.

What I have done:

  • Use for attribute to bind the input to the label & add a click event to prevent the default functionality.
  • Add the click handler to the respective input tag & not the label

    <label for="username" ng-click="$event.preventDefault();">Click me</label> <input type="text" id="username" ng-click="updateSelected();">

Live Demo @ JSFiddle

This way you don't have to worry about any conflicts in event handling,also its neat way to maintain the HTML code :)

I'm using the latest version of Angular Material 1.0.3 and still having this issue when clicking on labels that are configured as buttons on Android. I don't have the problem on IOS or the browser (cordova app). The following resolved it for me.

my html:

 <label class="btn btn-primary" ng-click="vm.goAbout()">About</label>

my controller:

 vm.goAbout = debounceFn(function(){
        //show dialog here, and now it only pops up once
    }, 250, false);

The debounce function:

function debounceFn(func, wait, immediate){
       var timeout;
       var deferred = $q.defer();
       return function() {
            var context = this, args = arguments;
            var later = function() {
              timeout = null;
              if(!immediate) {
                deferred.resolve(func.apply(context, args));
                deferred = $q.defer();
              }
            };
            var callNow = immediate && !timeout;
            if ( timeout ) {
              $timeout.cancel(timeout);
            }
            timeout = $timeout(later, wait);
            if (callNow) {
              deferred.resolve(func.apply(context,args));
              deferred = $q.defer();
            }
            return deferred.promise;
       }
  }
发布评论

评论列表(0)

  1. 暂无评论