我在SAPUI5应用程序中有一个详细信息视图,其中包含ID为"bestellmenge_tu"
的单个输入字段。每当调用此视图时,焦点应该放在该输入字段上。不幸的是,当在控制器的onInit
方法中将焦点设置在字段上时,焦点将被设置,但是在几毫秒之后,UI5将其取走并将其传输到详细视图的“导航返回”按钮。
通过在输入字段的log.trace()
事件上放置blur
,我发现焦点被一个名为sap.ui.define.NavContainer._afterTransitionCallback
的方法带走,该方法被异步调用(在触发器和执行之间有一些window.setTimeout
s)。该函数只是在视图中查找第一个可聚焦元素,并粗暴地将焦点切换到它上面。
我的解决方法是重新定义用于找到这个“第一个可聚焦元素”的方法jQuery.fn.firstFocusableDomRef
:
// DIESE KANONE FUNKTIONIERT
jQuery.fn.firstFocusableDomRef = (function() {
var _default = jQuery.fn.firstFocusableDomRef;
return function() {
var bestellmenge_tu = document.querySelector("input[id$='bestellmenge_tu-inner']");
if (bestellmenge_tu &&
bestellmenge_tu.style.display !="none" &&
bestellmenge_tu.style.visibility != "hidden") return bestellmenge_tu;
else return _default.apply(this);
}
})();
但这可能是一个性能问题(在任何页面加载时从DOM横向调用querySelector
),并且编码太多以达到预期的效果。
有没有更简单的方法来实现这一目标?
我想到了类似的东西
<mvc:View controllerName="zrt_dispo.view.Detail"...>
<Page id="detailPage" initialFocus="bestellmenge_tu"> <!-- ID of the element to carry the focus -->
</Page>
</mvc:view>
这是一个有效的例子:https://embed.plnkr.co/wp6yes/
如果你有一个NavContainer(sap.m.App
或sap.f.FlexibleColumnLayout
),它的直接孩子,又名。 NavContainerChild通常是一个View,可以对导航相关事件作出反应。在我们的例子中,我们应该根据API参考为事件afterShow
附加一个处理程序:
/**
* With autoFocus="false" in NavContainer control.
* setTimeout is required as a workaround for UI5 versions below 1.63.
* Otherwise, you can remove it.
*/
const onAfterShow = () => setTimeout(() => this.byId("thatControl").focus());
this.getView().addEventDelegate({ onAfterShow });
只有当
afterShow
设置为autoFocus
.false
时,[source]事件才能用于聚焦另一个元素
动画结束后触发事件处理程序。最重要的是:
当NavContainer使这个子控件可见时,每次都会触发此事件(与
onAfterRendering
相反)。
由于sap.ui.core.Control
扩展sap.ui.core.Element
,每个控件都可以通过focus()
获得焦点。
但是仅仅在focus()
中调用onAfterShow
仍然会让UI5将焦点放在用户导航回来时的第一个可聚焦元素上,即使使用autoFocus="false"
(请参阅此GitHub issue)。
因此,需要额外的setTimeout
与0
ms(或requestAnimationFrame
),以便让浏览器知道该元素应该聚焦在call stack的末尾,这意味着在UI5认为它完成了最初预期的一切之后的焦点。
使用this commit(从1.63开始提供),不再需要这种解决方法。
NavContainer
有一个属性autoFocus。 App
是NavContainer
的后裔,所以它也有这个属性。帮助(如上所述)说明如下:
确定在首次渲染时和导航到新页面后是否自动设置初始焦点。当触摸设备上的键盘弹出时,由于焦点在输入字段上自动设置,这非常有用。如有必要,可以使用“afterShow”事件来聚焦另一个元素。
默认值为true。