我有一个页面需要同时做两件事:
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 :(得分: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);
}
答案 1 :(得分:0)
delegate不会给你必要的控制权吗?然后,您可以检查事件目标并做出相应的响应吗?
即:
$(window).delegate('keypress', function(e){
if ($(e.target).attr('id') == 'userlist'){
// something
}else{
//something else
}
});
答案 2 :(得分:0)
您不需要两个处理程序。只需在窗口级别有一个处理程序,然后检查引发事件的元素:
$(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
}
});
答案 3 :(得分: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>