开发者

Calling click from keydown, but getting the correct checkbox checked property

This isn't a jQuery only question as it has to do with events and order of operation. Consider the following code, which is based on jQuery multiSelect plugin (please post citation if you can find it):

Fiddle with it here

var debug     = $('#debug');
var updateLog = function (msg){
    debug.prepend(msg + '\n');
};

var title     = $('#title').focus();
var container = $('#container');

title.keydown(function(e){
   // up or down arrows
   if (e.keyCode == 40 || e.keyCode == 38) {
    
      var labels  = container.find('label');
      var idx_old = labels.index(labels.filter('.hover'));
      var idx_new = -1;
    
      if (idx_old < 0) {
         container.find('label:first').addClass('hover');
      } else if (e.keyCode == 40 && idx_old < labels.length - 1) {
         idx_new = idx_old + 1;
      } else if (e.keyCode == 38 && idx_old > 0) {
         idx_new = idx_old - 1;
      }
    
      if (idx_new >= 0) {
         jQuery(labels.get(idx_old)).removeClass('hover');
         jQuery(labels.get(idx_new)).addClass('hover');
      }
    
      return false;
   }
    
   // space/return buttons
   if (e.keyCode == 13 || e.keyCode == 32) {
      var input_obj = container.find('label.hover input:checkbox');
      input_obj.click();          
      return false;
   }
});


// When the input is triggered with mouse
container
    .find('input:checkbox')
    .click(function(){
       var cb    = $(this);
       var class = "checked";
    
       if (cb.prop(class)){
           cb.parent('label').addClass(class);
       } else {
           cb.parent('label').removeClass(class);
       }
    
       updateLog( cb.closest('label').text().split(/[\s\n]+/).join(' ') + ': '
                + this.checked + ' , '
                + cb.prop(class));
        
       title.focus();
    })
;开发者_开发百科

Notice the difference in the checkbox value for when you click directly on the checkbox, versus when you select the checkbox with the space/enter key. I believe this is because it's calling click during the keydown event, so the value of the checkbox is not yet changed; whereas if you actually click the input, the mouseup event occurs before the click (?), so the setting is applied.

The multiselect plugin does not call the click event, it has almost duplicate code. I'm curious if it would be better to pass a parameter to the click event (or use a global) to detect if it issued by the keyboard or mouse, or if it is better to just do what the plugin did and have the code inside the keydown function.

Obviously, if the log were after the click() runs, the keydown would return trues, but there are things that happen inside of click that are based on the input's checked status.


Changed it to use the change event instead of the click event for the checkboxes http://jsfiddle.net/QJsPc/4/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜