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> 是动态创建的。

jsfiddle