jquery stopImmediatePropagation不会阻止事件执行两次函数

时间:2015-04-10 02:21:43

标签: jquery keyboard-events

我的问题是代码被执行了两次。 我有一个textarea弹出一个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);

}

它工作正常,直到我想关闭对话框:     如果(键== 'K'){closeIntelli();}

然后它关闭,但再次插入最后一个键,这不是我想要的。我试图用event.stopImmediatePropagation();在所有可能的地方。但是在closeIntelli之后,它返回到widget.keypress(函数..,然后回到rearrangeIntelli的末尾,id又添加了另一个键。

我不知道如何阻止这一点。从jquery方面的漫游开始,似乎它想要再次返回rearrangeIntelli函数的结果。但是我不知道如何阻止它执行inserttextAtCursor()两次。

以下是完整代码。有人可以给我一个提示。它与stopPropagation有什么关系,还是我需要查看其他地方。 非常感谢您的帮助, Jenita

           <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>

1 个答案:

答案 0 :(得分:1)

在当前代码中,当按下k时,它由窗口小部件的keypress处理程序处理。这将关闭对话框,将k添加到textarea,然后通过调用openIntelli()重新打开对话框。当然,当k传递给openIntelli()时,会立即关闭对话框。

如果我理解正确,您不希望将k添加到textarea。在这种情况下,请检查小部件的keypress处理程序中的键。如果密钥是k,请不要将其添加到textarea,也不要重新打开对话框。

但是,我不认为有必要关闭并重新打开每个键的对话框。以下是一些可能适合您的代码。请参阅代码中的注释:

$(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