Jquery模糊运行两次 - 为什么?

时间:2011-05-14 18:05:41

标签: jquery loops blur

我正在努力创建自己的成绩单,作为AJAX。在它的基础上有一个可编辑单元格的表格。用户点击单元格以输入成绩,当他们点击单元格时,成绩将通过AJAX发送到DB。到目前为止它工作得很好,除了我添加了用户点击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来动态构建表。

4 个答案:

答案 0 :(得分:8)

我认为您需要从$('#gradeUpdate').blur()更改为$('#gradeUpdate')[0].blur()。浏览器将使jQuery模糊与正常模糊不同。所以它会被触发两次。

答案 1 :(得分:1)

我发生了同样的事情,$('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)应该只引用一个选择器,而不是多个。有谁知道为什么这有效?

答案 2 :(得分:0)

每次点击td.assignmentCell,您都会重新绑定blurkeyup个事件。如果有意义,请尝试将它们绑定一次,或者live使用delegate#gradeUpdate

使用您的HTML更新您的问题,我可以更好地了解您正在做的事情。

答案 3 :(得分:0)

由于输入上的模糊事件发生在窗口上的模糊事件之前,我无法通过建议的解决方案解决此问题(为什么,我还不太确定)。话虽这么说,我能够跟随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
}