2011-01-24 7 views
1

私は一度に2つのことを行う必要があるページがあります。jQuery:複数のキー押しリスナーを扱う?

  • は(キーボード入力として提示)スキャナからの入力のためのすべての時間を聞くと、文字列は右の形式で入力されたときに注意してください。
  • 特定のドロップダウンに焦点を当て、イニシャルのセットを入力します。ドロップダウン内の項目のtitle属性に一致するイニシャルのセットが入力されると、そのドロップダウンに注目します。

私はこれらのことを別々に行うことはできますが、一緒に行うことはできません。コード:私は両方を持っている場合は、ユーザーがドロップダウンに焦点を当てている間に

// Listen for input when userlist is in focus. 
$("#userlist").keypress(function (e) { 
    initials += String.fromCharCode(e.which).toUpperCase(); 
    $(this).find("option").filter(function() { 
     return $(this).attr("title").toUpperCase().indexOf(initials) === 0; 
    }).first().attr("selected", true);  
    // uses timer to check for time between keypresses 
    return false; 
}); 
// Listen for scanner input all the time. 
var input = '', 
    r1 = /^~{1}$/, 
    r2 = /^~{1}\d+$/, 
    r3 = /^~{1}\d+\.$/, 
    r4 = /^~{1}\d+\.\d+$/, 
    r5 = /^~{1}\d+\.\d+~{1}$/; 
$(window).keypress(function(e) { 
    // when input matches final regex, do something 
}  

が、その後、ページがスキャナからの入力を「聞く」ことはありません。

ユーザーがドロップダウンに集中している間でも、ページをスキャナの入力に確実に反応させるにはどうすればよいですか?

答えて

0

これは、ウィンドウオブジェクトのリスナーをkeypressオブジェクトのリスナーでオーバーライドするためです。私は次のようなことをします:

var input = '', 
r1 = /^~{1}$/, 
r2 = /^~{1}\d+$/, 
r3 = /^~{1}\d+\.$/, 
r4 = /^~{1}\d+\.\d+$/, 
r5 = /^~{1}\d+\.\d+~{1}$/; 
function checkRegex(e) { /* Check */ } 

// Listen for input when userlist is in focus. 
$("#userlist").keypress(function (e) { 
     checkRegex(e); 
    initials += String.fromCharCode(e.which).toUpperCase(); 
    $(this).find("option").filter(function() { 
     return $(this).attr("title").toUpperCase().indexOf(initials) === 0; 
    }).first().attr("selected", true);  
    // uses timer to check for time between keypresses 
    return false; 
}); 
// Listen for scanner input all the time. 
$(window).keypress(function(e) { 
    checkRegex(e); 
}  
0

delegateはあなたに必要な制御を与えませんか?その後、イベントのターゲットを確認し、それに応じて対応することができますか?

すなわち:

$(window).delegate('keypress', function(e){ 
    if ($(e.target).attr('id') == 'userlist'){ 
     // something 
    }else{ 
     //something else 
    } 
}); 
0

あなたは2つのハンドラを必要としません。ただ、ウィンドウレベルで単一のハンドラを持っているし、イベントを提起している要素をチェック:

$(window).keypress(function(e) { 
    var $target = $(e.target); 
    if ($target.is("#userlist")) { 
    initials += String.fromCharCode(e.which).toUpperCase(); 
    $(this).find("option").filter(function() { 
    return $(this).attr("title").toUpperCase().indexOf(initials) === 0; 
    }).first().attr("selected", true);  
    // uses timer to check for time between keypresses 
    return false; 
    } else { 
     // when input matches final regex, do something 
    } 

}); 
0

これはおそらく、あなたがすることを希望よりも、方法がより複雑ですが、私はそれがあなたの目的に合うと思います。

jQueryプラグインのスタイルで作ってみましたが、それを特定のオブジェクトにアタッチすることができました(また、コンボボックスの場合はDOMをバブリングするのをオーバーライドする必要があります) 。必要に応じて、とにかく

、それを試してみて、あなたが何を考えて見るなど、窓を可能にするために、私は変更を加えることができ、ちょうど彼らが何であるかを知っておく必要があり

実施例:http://www.jsfiddle.net/bradchristie/xSMQd/4/

;(function($){ 
    $.keyListener = function(sel, options){ 
     // avoid scope issues by using base instead of this 
     var base = this; 

     // Setup jQuery DOM elements 
     base.$sel = $(sel); 
     base.sel = sel; 
     base.keyPresses = ''; 
     base.validater = null; 

     // add a reverse reference to the DOM object 
     base.$sel.data('keyListener', base); 

     // create an initialization function we can call 
     base.init = function(){ 
      base.opts = $.extend({}, $.keyListener.defaultOptions, options); 

      base.$sel.keypress(function(e){ 
       base.keyPresses += String.fromCharCode(e.which); 

       if (base.validator != null) 
        clearTimeout(base.validator); 
       if (base.keyPresses != '') 
        base.validator = setTimeout(base.validateInput, base.opts.callbackDelay); 

       if (base.opts.preventDefault) 
        e.preventDefault(); 
       else if (base.opts.stopPropagation) 
        e.stopPropagation(); 
      }); 
     }; 

     base.validateInput = function(){ 
      var filter = base.opts.filter; 
      var reCompare = (typeof(filter)=='object' 
          ? filter.constructor.toString().match(/regexp/i)!==null 
          : false); 

      // exception when the input is cleared out 
      var input = base.sel.constructor.toString().match(/HTMLInputElement|HTMLSelectElement|HTMLTextAreaElement/i); 
      if (input && (!base.opts.preventDefault && base.$sel.val() == '')) 
       base.keyPresses = ''; 

      // regular expression match 
      if (reCompare){ 
       if (base.keyPresses.match(filter)) 
        base.validateSuccess(); 
       else 
        base.validateFailure(); 
      // traditional string match 
      }else if (typeof(filter)=='string'){ 
       if (base.keyPresses==filter) 
        base.validateSuccess(); 
       else 
        base.validateFailure(); 
      } 

      // reset string 
      base.keyPresses = ''; 
     }; 

     base.validateSuccess = function(){ 
      if (typeof(base.opts.success)=='function') 
       base.opts.success(base.keyPresses); 
     }; 
     base.validateFailure = function(){ 
      if (typeof(base.opts.failure)=='function') 
       base.opts.failure(base.keyPresses); 
     }; 

     // run the initializer 
     base.init(); 
    }; 

    $.keyListener.defaultOptions = { 
     // time to wait before triggering callback 
     // Give it time to accumulate the key presses and send it off 
     // as a compiled package 
     callbackDelay: 1000, 

     // Filter to apply to the input (can be a string match or a regular expression) 
     filter: /.*/, 

     // functions to callback when a match has or hasn't been made 
     success: function(i){}, 
     failure: function(i){}, 

     // would you like this to completely override key input? 
     preventDefault: false, 

     // stop it from going up the DOM tree (first object to grab the keypress 
     // gets it) 
     stopPropagation: true, 
    }; 

    $.fn.extend({ 
     keyListener: function(options){ 
      // use return to allow jQuery to chain methods 
      return this.each(function(){ 
       (new $.keyListener(this, options)); 
      }); 
     } 
    }); 
})(jQuery); 

$('#listen-scanner,#listen-combo,#listen-text').add(window).keyListener({ 
    filter: /^\d+$/, 
    success: function(input){ 
     $('#output-scanner').text('Match!: '+input); 
    }, 
    failure: function(input){ 
     $('#output-scanner').text('No Match: '+input); 
    }, 
    stopPropagation: true 
}); 

そして私が試したHTML:

<input type="text" id="listen-scanner" /><span id="output-scanner"></span><br /> 
<select id="listen-combo"> 
    <option value="AA">Aardvarc</option> 
    <option value="AB">Abracabra</option> 
    <option value="AC">Accelerate</option> 
    <option value="AD">Adult</option> 
</select><span id="output-combo"></span> 
<textarea id="listen-text"></textarea>