【问题标题】:Jquery blur running twice--why?Jquery blur 运行两次——为什么?
【发布时间】:2011-08-25 14:52:00
【问题描述】:

我正在创建自己的 AJAX 成绩册。在其底部有一个带有可编辑单元格的表格。用户单击单元格输入成绩,当他们单击单元格时,成绩通过 AJAX 发送到数据库。到目前为止,它工作正常,除了我已经添加了用户按 Enter 并让它表现得好像用户单击其他地方以关闭编辑表单的功能。

问题是当用户点击回车而不是回车时,模糊部分会运行两次,这可以通过两次弹出的警报来证明。如果他们只是点击某个地方,那很好。 我对 jQuery 的 .blur() 的理解是,如果您在没有回调或参数的情况下调用它,它将充当执行者并将其视为所选元素失去焦点。

在 IE8、Chrome 和 FF 4.0.1 上发生。直播版在my test site 运行

有人可以解释为什么当我尝试在用户点击输入时设置模糊时它会运行两次吗?

更新:不能发布 HTML,因为它实际上只是一个表格,并且表格标签集不在 stackOverflow 白名单上。 (我是新来的,所以也许有办法做到这一点,但我不知道。)

另外,我通过改变解决了眼前的问题

                if(event.keyCode=='13')
            {
                $('#gradeUpdate').blur();
            }

                if(event.keyCode=='13')
            {
                $("#gradeUpdate").parent().focus();
                //$('#gradeUpdate').blur();
            }

但我仍然想知道为什么原来的行不只是让#gradeUpdate 像我想象的那样模糊。

一切都发生在这个函数内部:

function clickableCell(){
$("td.assignmentCell").click(function(){  //if a td with an assignment class is clicked,
    if( clicked == 0)
    {
        clicked = 1;
        currentValue = $(this).text();//get the current value of the entered grade
        var passable = this;
alert("Test:  passable is: "+$(passable).text());
    //change content to be an editable input form element
        $(this).html("<input name='gradeUpdate' id='gradeUpdate' size=3 value='"+currentValue+"' type='text' />");
    //move the cursor to the new input and highlight the value for easy deletion    
        $('#gradeUpdate').focus().select();  
    //watch for keystrokes somewhere else and act appropriately 
        $(document).keyup(function(event){
        //if they hit Enter, treat it like they clicked somewhere else
            if(event.keyCode=='13')
            {
                $('#gradeUpdate').blur();
            }
        });

        $('#gradeUpdate').blur(function(passable){
        //reset the clicked counter
            clicked = 0;
        //check to see if the value is blank or hasn't changed
            var inputValue = $('#gradeUpdate').val();
        //////////////////////////////////////////////////////////////////////////////////////////
        //  Here we need to insert a REGEX check for the "exception" values created by the GDST
        //  and check for those values; anything else that's not a number will be disallowed
        //  and reset to "" so that it's caught in a later step.  For now I'm just checking for digits
        //////////////////////////////////////////////////////////////////////////////////////////
        if(!inputValue.match(/^\d+$/)) 
        { 
            alert ("we don't have a match!");
            inputValue = "";
        }
        ///////////////////////////////////////////////////////////////////////////////////////////
            if(currentValue == inputValue || inputValue =="")//hasn't changed or is blank
            {
                //DON'T run AJAX call
alert("Not a good value, reverting to old value!");
            //assign the original, unchanged value to the table
                $('#gradeUpdate').parent().text(currentValue) 
                $("#gradeUpdate").remove();//close out the input block
            //make it like they actually clicked on the element they did click on to lose focus
                $(this).click();
            }
            else //it's valid, send the ajax
            {
                //send AJAX call here
                //on success update the td
alert("We're all good--entering value!");
                $("#gradeUpdate").parent().text(inputValue);
                $("#gradeUpdate").remove();
            }
        });
    }//close of if clicked ==0
});

}

这是原始页面的完整 HTML;它实际上只是一个表,其中包含一些用于测试的预先输入的值。我的下一步是使用从 AJAX 请求返回的 XML 动态构建表。

【问题讨论】:

    标签: jquery loops blur


    【解决方案1】:

    我认为您需要从 $('#gradeUpdate').blur() 更改为 $('#gradeUpdate')[0].blur()。浏览器将采用不同于普通模糊的 jQuery 模糊。所以会触发两次。

    【讨论】:

      【解决方案2】:

      我也遇到了同样的事情,$('input')[0].blur(); 行以某种方式修复了它,但我不明白它是如何工作的。我的代码是:

      $('h1 input').live('blur', function(){
          var text = $('h1 input').val();
          if(text == ''){
              alert('!');
              $('h1').html('<p>' + originalProjectName + '</p><span></span>');
              text = originalProjectName;
          }
          var id = document.location.hash.split('-')[1];
          $('h1').html('<p>' + text + '</p><span></span>');
          $.getJSON('json-project.php', { method: 'rename', id: id, name: text }, function(data) {
              var type = document.location.hash.split('-')[0];
              if(type == '#shoot'){
                  $('#scroller-shoots ul li[data-id=' + id + ']').html(text); 
              }
              if(type =='#project'){
                  $('#scroller-projects ul li[data-id=' + id + ']').html(text);
              }
          });
      });
      $('h1 input').live('keydown', function(event) {
          originalProjectName = $(this).val();      
          if ( event.which == 13 ) {
              $(this)[0].blur();
          }
      });
      

      这没有意义,因为$(this) 应该只引用一个选择器,而不是多个选择器。有谁知道为什么会这样?

      【讨论】:

        【解决方案3】:

        每次单击 td.assignmentCell 时,您都会重新绑定 blurkeyup 事件。如果有意义,请尝试仅绑定一次,或者使用livedelegate 绑定#gradeUpdate

        用你的 HTML 更新你的问题,我可以更好地了解你在做什么。

        【讨论】:

        • 除非我误解了你的意思,否则每次点击都不会真正重新绑定,因为 var click 就像一个布尔开关。如果用户单击,此代码将按预期工作;当他们点击回车而不是点击某处时,问题就出现了。
        • @jcanker:每次你说$(x).click(function() {/*...*/}),你都在绑定一个新的点击处理程序。对于$(x).blur(function) 也是如此,即使click 没有绑定,看起来blur 也会被绑定多次。
        【解决方案4】:

        我无法通过建议的解决方案解决此问题,因为输入上的模糊事件发生在窗口上的模糊事件之前(为什么,我还不太确定)。话虽如此,我能够关注this post,并对其进行了调整以检测用户的鼠标何时离开窗口区域以忽略模糊事件。

        示例代码:

        var isTargetWindow = false;
        
        function addEvent(obj, evt, fn) {
            if (obj.addEventListener) {
                obj.addEventListener(evt, fn, false);
            }
            else if (obj.attachEvent) {
                obj.attachEvent("on" + evt, fn);
            }
        }
        
        var isTargetWindow = false;
        
        addEvent(window,"load",function(e) {
            addEvent(window, "mouseout", function(e) {
                e = e ? e : window.event;
                var from = e.relatedTarget || e.toElement;
                if (!from || from.nodeName == "HTML") {
                    // stop your drag event here
                    // for now we can just use an alert
                    isTargetWindow = true;
                }
                else {
                    isTargetWindow = false;
                }
            });
        });
        
        $(document).on( 'blur', 'input', function( e ) {
        
            if( isTargetWindow ) {
                return false;
            }
        
            // ... do something here
        }
        

        【讨论】:

          猜你喜欢
          • 2015-01-06
          • 2022-01-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-01-16
          相关资源
          最近更新 更多