jquery stopImmediatePropagation 不会阻止事件执行函数两次
jquery stopImmediatePropagation does not prevent event from executing function twice
我的问题是代码被执行了两次。
我有一个弹出 jquery 对话框的文本区域(当键入一个点时)。
$('#myText').keydown(function(e){handleKeys(e);});
function handleKeys(e){ if(e.keyCode == 190){openIntelli(e,null);}}
当用户不断键入按键时,对话框的小部件会收听
widget.unbind('keypress');
widget.on('keypress',function(event)
{event.stopImmediatePropagation();rearrangeIntelli(event);});
在 rearrangeIntelli 中,对话框关闭,然后将键入的键插回 teaxtarea,然后使用 openIntelli() 再次打开智能对话框
function rearrangeIntelli(event){
console.log('rearrangeIntelli');
//event.stopImmediatePropagation(); I tried to put it here, no effect
//alert('key:'+event.which);
var key=String.fromCharCode(event.which);
closeIntelli();
insertTextAtCursor(key);
openIntelli(event,key);
}
它工作正常,直到我想关闭对话框:
if(key=='k'){closeIntelli();}
然后它关闭,但再次插入最后一个键,这不是我想要的。我试图用 event.stopImmediatePropagation(); 来阻止它。在所有可能的地方。但是在 closeIntelli 之后,它 returns 到 widget.keypress(function..,然后回到 rearrangeIntelli 的末尾并且 id 添加另一个键。
我不知道如何阻止它。从 jquery 的漫游来看,它似乎想要 return rearrangeIntelli 函数的结果 again.But 我不知道该怎么做才能阻止它执行 inserttextAtCursor () 两次。
下面是完整代码。有人可以给我一个提示吗?它与 stopPropagation 有什么关系吗,还是我需要看看其他地方。
非常感谢您的帮助,
珍妮塔
<script type="text/javascript" src="/js/jquery.1.11.0.min.js"> </script>
<link rel="stylesheet" href="/js/jquery.1.11.1.ui.smoothness.css" />
<script>
$(function() {
$('#myText').keydown(function(e){handleKeys(e);});
$("#intelli" ).dialog({autoOpen:false});
$("#intelli" ).dialog({ width: 700,maxHeight:500 }).css({ "font-size": "18px", "font-family":"Times New Roman" } );
$("#intelli").dialog("option","title","Properties and Methods");
});
function handleKeys(e){ if(e.keyCode == 190){openIntelli(e,null);}}
function openIntelli(event,key){
console.log('openIntelli');
var intelli=$('#intelli'); /// get the intelli dialog
$("#intelli" ).dialog("open");
$("#intelli").dialog('option','position',{my: "left top",at: "right top",of: event.target});
var widget=$('#intelli').dialog('widget');
widget.unbind('keypress');
widget.on('keypress',function(event){event.stopImmediatePropagation();rearrangeIntelli(event);});
widget.focus();
if(key=='k')
{
console.log('from openIntelli:close'); closeIntelli();
}
}
function closeIntelli(){
console.log('closeIntelli');
$("#intelli").dialog("close");
}
function rearrangeIntelli(event){
console.log('rearrangeIntelli');
//event.stopImmediatePropagation();
//alert('key:'+event.which);
var key=String.fromCharCode(event.which);
closeIntelli();
insertTextAtCursor(key);
openIntelli(event,key);
}
function insertTextAtCursor( text) {
var el=$('#myText')[0];
console.log('insertTextCursor:'+text);
var val = el.value, endIndex, range;
if (typeof el.selectionStart != "undefined" && typeof el.selectionEnd != "undefined") {
endIndex = el.selectionEnd;
}
console.log('endIndex:'+endIndex);
el.value = val.slice(0, endIndex) + text + val.slice(endIndex);
el.selectionStart = el.selectionEnd = endIndex + text.length;
}
</script>
<textarea id='myText'></textarea>
<div id='intelli'>hello there</div>
在您当前的代码中,当按下 k
时,它由小部件的 keypress
处理程序处理。这将关闭对话框,将 k
添加到文本区域,然后通过调用 openIntelli()
重新打开对话框。当然,当 k
传递给 openIntelli()
时,它会立即关闭对话框。
如果我没理解错的话,您不希望将 k
添加到文本区域。在这种情况下,请检查小部件的 keypress
处理程序中的密钥。如果键是 k
,请不要将其添加到文本区域,也不要重新打开对话框。
不过,我认为没有必要为每个键关闭并重新打开对话框。这是一些可能对您有用的代码。看代码中的注释:
$(function() {
function insertTextAt(el, text, pos) {
if (typeof pos != 'undefined') {
var val = el.value;
el.value = val.slice(0, pos) + text + val.slice(pos);
el.selectionStart = el.selectionEnd = pos + text.length;
} else {
el.value += text;
el.selectionStart = el.selectionEnd = el.value.length;
}
}
function instrumentIntelli($textarea) {
// Create closure variable for the textarea cursor position.
var pos;
// Create the dialog element and instrument it as a dialog.
var $dialog = $('<div></div>').dialog({
autoOpen: false,
title: 'Properties and Methods',
width: 250,
maxHeight: 100,
position: {
my: 'left top',
at: 'right top',
of: $textarea[0]
}
}).css({
'font-size': '18px',
'font-family': 'Times New Roman'
});
$dialog.dialog('widget').keypress(function(event) {
var key = String.fromCharCode(event.which);
if (key != 'k') {
// In some browsers this moves the focus to the textarea.
insertTextAt($textarea[0], key, pos);
// Update the cursor position variable.
pos = $textarea[0].selectionEnd;
// Move the focus back to the widget.
$dialog.dialog('widget').focus();
} else {
$dialog.dialog('close');
// Since the dialog will remain closed, we want to move the
// focus to the textarea, but we want to delay this until
// after the keyup event is finished or else the textarea
// will get a keypress event for the key.
setTimeout(function() {
$textarea.focus();
$textarea[0].selectionStart = $textarea[0].selectionEnd = pos;
}, 0);
}
});
$textarea.keydown(function(event) {
if (event.keyCode == 190) {
// Set the cursor position variable before opening the
// dialog and moving the focus from the textarea.
pos = $textarea[0].selectionEnd;
// Open the dialog and move the focus to the widget.
$dialog.dialog('open').dialog('widget').focus();
}
});
}
instrumentIntelli($('#myText'));
});
请注意,对话框的 <div>
是动态创建的。
我的问题是代码被执行了两次。 我有一个弹出 jquery 对话框的文本区域(当键入一个点时)。
$('#myText').keydown(function(e){handleKeys(e);});
function handleKeys(e){ if(e.keyCode == 190){openIntelli(e,null);}}
当用户不断键入按键时,对话框的小部件会收听
widget.unbind('keypress');
widget.on('keypress',function(event)
{event.stopImmediatePropagation();rearrangeIntelli(event);});
在 rearrangeIntelli 中,对话框关闭,然后将键入的键插回 teaxtarea,然后使用 openIntelli() 再次打开智能对话框
function rearrangeIntelli(event){
console.log('rearrangeIntelli');
//event.stopImmediatePropagation(); I tried to put it here, no effect
//alert('key:'+event.which);
var key=String.fromCharCode(event.which);
closeIntelli();
insertTextAtCursor(key);
openIntelli(event,key);
}
它工作正常,直到我想关闭对话框: if(key=='k'){closeIntelli();}
然后它关闭,但再次插入最后一个键,这不是我想要的。我试图用 event.stopImmediatePropagation(); 来阻止它。在所有可能的地方。但是在 closeIntelli 之后,它 returns 到 widget.keypress(function..,然后回到 rearrangeIntelli 的末尾并且 id 添加另一个键。
我不知道如何阻止它。从 jquery 的漫游来看,它似乎想要 return rearrangeIntelli 函数的结果 again.But 我不知道该怎么做才能阻止它执行 inserttextAtCursor () 两次。
下面是完整代码。有人可以给我一个提示吗?它与 stopPropagation 有什么关系吗,还是我需要看看其他地方。 非常感谢您的帮助, 珍妮塔
<script type="text/javascript" src="/js/jquery.1.11.0.min.js"> </script>
<link rel="stylesheet" href="/js/jquery.1.11.1.ui.smoothness.css" />
<script>
$(function() {
$('#myText').keydown(function(e){handleKeys(e);});
$("#intelli" ).dialog({autoOpen:false});
$("#intelli" ).dialog({ width: 700,maxHeight:500 }).css({ "font-size": "18px", "font-family":"Times New Roman" } );
$("#intelli").dialog("option","title","Properties and Methods");
});
function handleKeys(e){ if(e.keyCode == 190){openIntelli(e,null);}}
function openIntelli(event,key){
console.log('openIntelli');
var intelli=$('#intelli'); /// get the intelli dialog
$("#intelli" ).dialog("open");
$("#intelli").dialog('option','position',{my: "left top",at: "right top",of: event.target});
var widget=$('#intelli').dialog('widget');
widget.unbind('keypress');
widget.on('keypress',function(event){event.stopImmediatePropagation();rearrangeIntelli(event);});
widget.focus();
if(key=='k')
{
console.log('from openIntelli:close'); closeIntelli();
}
}
function closeIntelli(){
console.log('closeIntelli');
$("#intelli").dialog("close");
}
function rearrangeIntelli(event){
console.log('rearrangeIntelli');
//event.stopImmediatePropagation();
//alert('key:'+event.which);
var key=String.fromCharCode(event.which);
closeIntelli();
insertTextAtCursor(key);
openIntelli(event,key);
}
function insertTextAtCursor( text) {
var el=$('#myText')[0];
console.log('insertTextCursor:'+text);
var val = el.value, endIndex, range;
if (typeof el.selectionStart != "undefined" && typeof el.selectionEnd != "undefined") {
endIndex = el.selectionEnd;
}
console.log('endIndex:'+endIndex);
el.value = val.slice(0, endIndex) + text + val.slice(endIndex);
el.selectionStart = el.selectionEnd = endIndex + text.length;
}
</script>
<textarea id='myText'></textarea>
<div id='intelli'>hello there</div>
在您当前的代码中,当按下 k
时,它由小部件的 keypress
处理程序处理。这将关闭对话框,将 k
添加到文本区域,然后通过调用 openIntelli()
重新打开对话框。当然,当 k
传递给 openIntelli()
时,它会立即关闭对话框。
如果我没理解错的话,您不希望将 k
添加到文本区域。在这种情况下,请检查小部件的 keypress
处理程序中的密钥。如果键是 k
,请不要将其添加到文本区域,也不要重新打开对话框。
不过,我认为没有必要为每个键关闭并重新打开对话框。这是一些可能对您有用的代码。看代码中的注释:
$(function() {
function insertTextAt(el, text, pos) {
if (typeof pos != 'undefined') {
var val = el.value;
el.value = val.slice(0, pos) + text + val.slice(pos);
el.selectionStart = el.selectionEnd = pos + text.length;
} else {
el.value += text;
el.selectionStart = el.selectionEnd = el.value.length;
}
}
function instrumentIntelli($textarea) {
// Create closure variable for the textarea cursor position.
var pos;
// Create the dialog element and instrument it as a dialog.
var $dialog = $('<div></div>').dialog({
autoOpen: false,
title: 'Properties and Methods',
width: 250,
maxHeight: 100,
position: {
my: 'left top',
at: 'right top',
of: $textarea[0]
}
}).css({
'font-size': '18px',
'font-family': 'Times New Roman'
});
$dialog.dialog('widget').keypress(function(event) {
var key = String.fromCharCode(event.which);
if (key != 'k') {
// In some browsers this moves the focus to the textarea.
insertTextAt($textarea[0], key, pos);
// Update the cursor position variable.
pos = $textarea[0].selectionEnd;
// Move the focus back to the widget.
$dialog.dialog('widget').focus();
} else {
$dialog.dialog('close');
// Since the dialog will remain closed, we want to move the
// focus to the textarea, but we want to delay this until
// after the keyup event is finished or else the textarea
// will get a keypress event for the key.
setTimeout(function() {
$textarea.focus();
$textarea[0].selectionStart = $textarea[0].selectionEnd = pos;
}, 0);
}
});
$textarea.keydown(function(event) {
if (event.keyCode == 190) {
// Set the cursor position variable before opening the
// dialog and moving the focus from the textarea.
pos = $textarea[0].selectionEnd;
// Open the dialog and move the focus to the widget.
$dialog.dialog('open').dialog('widget').focus();
}
});
}
instrumentIntelli($('#myText'));
});
请注意,对话框的 <div>
是动态创建的。