OnBlur和由于鼠标而失去焦点在IE

时间:2017-02-03 20:06:56

标签: javascript jquery internet-explorer-11

TL:DR 我的文本框中有OnBlur个事件。此事件选择组合框中的项目并将其设置为只读。如果文本框有焦点,然后我点击组合框,我可以展开下拉菜单并选择一个项目。如果文本框有焦点,我按 Tab 一次选择组合框,OnBlur事件中的javascript成功选择该项并禁用该控件。这只发生在IE中。我该如何解决这个问题?

此外,在OnBlur代码中设置断点会导致软件无论我使用鼠标还是 Tab 都能正常运行,但这可能是由于浏览器窗口交易所致专注于我的调试器。

我有一个使用MVC,RazorViews的ASP.NET Web应用程序,并使用jquery + Telerik的Kendo UI控件。

使用文本框查看文件代码:

<td colspan="2" class="qicolumn-width-88 textalign-right">
    @(Html.Kendo().TextBoxFor(m => m.V14_Adm_C0500).HtmlAttributes(new 
       { 
         id = "cmbV14_C0500", 
         class = "width-85", 
         tabIndex = "11", 
         style = "width:149px", 
         onfocus = "FocusC0500()", 
         onblur = "BlurC0500(false);FinalizeColor(this);" 
       }))
</td>

表单上有一个文本框和下拉菜单数组。根据他们为C0100 - C0400输入的值,软件将自动确定C0500(上面定义的文本框)的值并禁用它,或启用它以进行用户输入。当用户输入一个值然后导航出该文本框时,一个方法将触发并更新组合框C0600的数据源。

这由以下冗长的javascript方法处理:

function BlurC0500(isFromDropDown) 
{
    //Get the drop down menu object that C0500 manpiulates.
    var cmb = $("#cmbV14_C0600").data("kendoDropDownList");

    //Get the value from C0500. It should be a number between 0 - 10, 99, or a hyphen.
    var val = $("#cmbV14_C0500").val();

    if (val == '99' || val == '-') 
    {
        cmb.select(0); //select '0 - No'
        cmb.readonly(true); // disable the control
        cmb.wrapper.find('.k-input').css('background', '#DDDDDD'); // set bg to gray to indicate its RO status
        SetTabIndexVals("cmbV14_C0600", "DROPDOWN", -1); //Set tab index for control
    }
    else 
    {
        if (val != sumC0100C0400 && sumC0100C0400 > 0 && isFromDropDown != true) 
        {
            //Show an error to the user if the value they entered into C0500
            //  does not equal the sum of the values entered in C0100 - C0400, if that sum is greater than 0.
        }


        //Create new data source to assign to C0600
        var ZeroToOneAndDashData = [{ "Text": "0 - No", "Value": "0" }, { "Text": "1 - Yes", "Value": "1" }, { "Text": "-", "Value": "-" }];
        cmb.dataSource.data(ZeroToOneAndDashData);


        //If the value they entered IS equal to the sum of C0100 - C0400
        if (val == sumC0100C0400) 
        {
            //Mantis#16646 Changes : Added below condition to set C0600 field empty and disable
            if ($("#cmbV14_C0100").val() == "" || $("#cmbV14_C0100").val() == '0') 
            {
                //Select the "0 - No" option for C0600 when C0100 is empty / zero, 
                //  then set the readonly state + tabindex + bg color...
            }
            else if (val == "" && $("#cmbV14_C0100").val() == '1') 
            {
                //Select "0 - No" option for C0600 when C0100 is 1
                //  then set different readonly + tabindex + bgcolor values
            }
            else
            {
                //Select "1 - Yes" option for C0600
                //  then assign yet a different set of values for readonly / tabindex / bgcolor
            }

        }
        else //executes when the value they entered IS NOT equal to the sum of C0100 - C0400
        {
            //Select "0 - No" option for C0600 when C0100 is 1
            //  then set different readonly + tabindex + bgcolor values
        }


        //If a change in C0100 - C0400 values prompted a change in C0500 + C0600's behavior
        //   we call OnChangeC0600.
        // This changes the values / readonly states of yet another set of controls 
        if (isFromDropDown === false)
            OnChangeC0600(false);
    }

    var chkBIMval = $("#cmbV14_C0500").val().trim();

    //Prepends a 0 to the value entered in C0500 if the value is greater than 0 and less than 10
    // because the value 99 valid, we want the value to always be two characters long. "06" instead of simply "6".
    if (chkBIMval != '' && chkBIMval != '01' && chkBIMval != '02' && chkBIMval != '03' && chkBIMval != '04' && chkBIMval != '05' && chkBIMval != '06' && chkBIMval != '07' && chkBIMval != '08' && chkBIMval != '09') 
    {
        if ($("#cmbV14_C0500").val() > 0 && $("#cmbV14_C0500").val() < 10) 
        {
            $("#cmbV14_C0500").val('0' + val);
        }
    }
}

这是设置标签索引的功能:

function SetTabIndexVals(controlID, controltype, tabIndex)
{
    try
    {
        var _eTabIndex;

        //If we're assigning tabIndex = -1, get the current tab index
        //  and store it into a custom attribute to be re-assigned later
        if (tabIndex == -1)
        {
            if (controltype == 'DROPDOWN')
            {
                _eTabIndex = $("span[aria-owns=" + controlID + "_listbox]").attr('tabindex');
                $("span[aria-owns=" + controlID + "_listbox]").attr('Oldtabindex', _eTabIndex);
                $("span[aria-owns=" + controlID + "_listbox]").attr('tabindex', tabIndex);
            }
            else if (controltype == 'TEXTBOX')
            {
                _eTabIndex = $("#" + controlID).attr('tabindex');
                if (_eTabIndex > 0)
                {
                    $("#" + controlID).attr('Oldtabindex', _eTabIndex);
                    $("#" + controlID).attr('tabindex', tabIndex);
                }
            }
        }
        else
        {
            if (controltype == 'DROPDOWN')
            {
                _eTabIndex = $("span[aria-owns=" + controlID + "_listbox]").attr('Oldtabindex');
                if (_eTabIndex == undefined || _eTabIndex < 0 || _eTabIndex == null)
                    _eTabIndex = $("span[aria-owns=" + controlID + "_listbox]").attr('tabindex');
                $("span[aria-owns=" + controlID + "_listbox]").attr('Oldtabindex', _eTabIndex);
                $("span[aria-owns=" + controlID + "_listbox]").attr('tabindex', _eTabIndex);
            }
            else if (controltype == 'TEXTBOX')
            {
                _eTabIndex = $("#" + controlID).attr('Oldtabindex');
                if (_eTabIndex == undefined || _eTabIndex < 0 || _eTabIndex == null)
                    _eTabIndex = $("#" + controlID).attr('tabindex');
                $("#" + controlID).attr('Oldtabindex', _eTabIndex);
                $("#" + controlID).attr('tabindex', _eTabIndex);
            }
        }
    } catch (err)
    {
        logError(err, arguments.callee.trace());
    }
}

使用Internet Explorer(v11.0.9600.18537CO),软件行为不正确:

  • 在C0500中键入一个等于C0100 - C0400
  • 总和的值
  • 点击C0600下拉
  • 下拉菜单展开,我可以选择0 - No1 - Yes-

下拉菜单不应该是可扩展的。该软件应选择0 - No并禁用它。

如果我在Chrome(v55.0.2883.87)或Firefox(v51.0.1)中执行相同的步骤,当我使用鼠标点击C0600 combox时,它会正常运行。它立即被禁用并选择0 - No,如上所述。

如果我执行相同的步骤但使用 Tab 键而不是鼠标,它可以在IE,Chrome和Firefox中正常工作。

我猜测IE的JS引擎可能比FF / Chrome慢一点,它允许用户做他们不应该做的事情,但我不知道如何确认这一点,或者如何“处理”它。

如何才能使用户无法点击被他们在Internet Explorer中离开的控件中禁用的控件?

根据MSDN

  

onflur事件在onfocus或onclick事件触发正在接收焦点的对象之前触发原始对象。

但在我的情况下,情况显然不是这样。我看到它还提到控件必须有一个tab索引。当我将组合框设置为ReadOnly时,我指定tabIndex = -1,但看起来负片应该没问题。如果我为它指定一个非负数,那么这个只读控件将获得焦点,而不是下一个不是只读的控件。

我也试过立即设置cmb.readonly(true)作为JS中的第一个动作,希望我可能只需要尽快禁用它,但这并没有解决问题。

编辑:我也尝试在视图中删除剃刀代码中的onblur属性。相反,我补充说:

    $("#cmbV14_C0500").focusout(function ()
    {
        BlurC0500(false);FinalizeColor(this);
    });

到我视图末尾的$(document).ready(function () { }脚本。根据{{​​3}}:

  

focusout事件或其中的任何元素失去焦点时,会将blur事件发送给该元素。这与mod事件的区别在于它支持检测后代元素的焦点丢失(换句话说,它支持事件冒泡)。

然而,它导致完全相同(不正确)的行为。

1 个答案:

答案 0 :(得分:1)

我做了一些测试,我可以在IE中重现这个问题,但看起来像一个bug,因为这只发生在IE中。这绝对是一个剑道问题。请注意,您甚至没有处理实际的选择。无论浏览器如何触发它们,剑道都可以随意执行任何事情。

如果它打开,你可以cmb.close()强制它关闭下拉列表。