IE 11带焦点选择,单击后焦点丢失

IE 11 Select with Focus Losing Focus When Clicked

本文关键字:焦点 单击 选择 IE      更新时间:2023-09-26

我正在制作一个电子表格,双击一个单元格会弹出'edit'控件,给它焦点,并设置一个onblur事件处理程序来隐藏'edit'控件,并将单元格的值设置为一旦失去焦点的控件的值。假定的流程是用户双击打开编辑控件,选择/输入一个值,然后单击/选项卡到其他内容,从而将焦点移动到另一个元素并触发编辑控件的onblur处理程序。

它工作得很好,除了在IE 10和11中的SELECT标签(Chrome和FF工作得很好):每次我点击carat以放下下拉菜单,SELECT失去焦点并触发onblur处理程序,然后隐藏编辑控件,从而阻止我编辑值。

有人知道为什么会发生这种情况或如何修复它吗?

我找到了这篇博客文章,它描述了这个问题,并提出了一个在SELECT中添加背景图像的解决方案,但这似乎并没有解决问题(或者我做错了)。

下面是生成编辑控件的HTML并将其插入单元格的代码。

/**Changes the contents of the cell to be its editing control instead of plain text.
@method SetCellEditMode
@param {String} mappingId: The Id of the PropertyMapping representing cell to switch over to edit mode.*/
this.SetCellEditMode = function (mappingId)
{
    if (this.Editing === true) return false;
    var cell = this.GetCell(mappingId);
    var tagType = null;
    if (cell == null) return false;
    var propInfo = cell.SourceObject.PropertyInfo;
    if (propInfo.IsReadOnly === true) return false;
    var innerHtml = null;
    if (propInfo.PropertyType === SDCMS.Resources.PropertyType.Boolean)
    {
        innerHtml = makeBoolHTML(cell.SourceObject);
    }
    else if (propInfo.PropertyType === SDCMS.Resources.PropertyType.Enum)
    {
        innerHtml = makeEnumHTML(cell.SourceObject);
    }
    else if (propInfo.PropertyType === SDCMS.Resources.PropertyType.Number || propInfo.PropertyType === SDCMS.Resources.PropertyType.String)
    {
        innerHtml = makeStringEntryHTML(cell.SourceObject);
    }
    cell.Node[0].innerText = "";
    cell.Node.html(innerHtml);
    cell.Node[0].firstChild.focus();
    this.Editing = true;
    return true;
};

/**Makes the HTML for a boolean <select> control.
@method makeBoolHTML
@param {Object} propertyMapping: The SDCMS.Resources.PropertyMapping for which we are making an <select> control.*/
var makeBoolHTML = function (propertyMapping)
{
    if (propertyMapping == null) return null;
    var innerHtml = "<select mappingId='"" + propertyMapping.Id + "'" onblur='"SD_Click(event, 'SD_ChangeValue')'">" +
                        "<option>true</option>" +
                        "<option>false</option>" +
                    "</select>";
    if (propertyMapping.PropertyValue === true)
    {
        innerHtml.replace("<option>true</option>", "<option selected='"selected'">true</option>")
    }
    else
    {
        innerHtml.replace("<option>false</option>", "<option selected='"selected'">false</option>")
    }
    return innerHtml;
};

找到解决方案了。原来是所有的输入/选择类型节点都失去了焦点,而发生的事情是,当单击表中的节点时,将事件从控件冒泡到表单元格,然后该单元格将获得焦点并导致blur()触发内部控件。解决方案是为onclick, onmousedown和onmouseup(为了更好的测量)连接事件处理程序,这些事件处理程序除了preventDefault()和stopPropagation()之外什么都不做。一旦事件停止传播到包含的表单元格,一切都正常工作。

不要直接调用focus,使用settimeout()调用它,间隔1到10毫秒应该就足够了。