如何在视图中设置初始焦点?

问题描述 投票:2回答:2

我在SAPUI5应用程序中有一个详细信息视图,其中包含ID为"bestellmenge_tu"的单个输入字段。每当调用此视图时,焦点应该放在该输入字段上。不幸的是,当在控制器的onInit方法中将焦点设置在字段上时,焦点将被设置,但是在几毫秒之后,UI5将其取走并将其传输到详细视图的“导航返回”按钮。

通过在输入字段的log.trace()事件上放置blur,我发现焦点被一个名为sap.ui.define.NavContainer._afterTransitionCallback的方法带走,该方法被异步调用(在触发器和执行之间有一些window.setTimeouts)。该函数只是在视图中查找第一个可聚焦元素,并粗暴地将焦点切换到它上面。

我的解决方法是重新定义用于找到这个“第一个可聚焦元素”的方法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>
sapui5
2个回答
3
投票

这是一个有效的例子:https://embed.plnkr.co/wp6yes/

如果你有一个NavContainer(sap.m.Appsap.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()获得焦点。


UI5 1.62及以下版本的Bug

但是仅仅在focus()中调用onAfterShow仍然会让UI5将焦点放在用户导航回来时的第一个可聚焦元素上,即使使用autoFocus="false"(请参阅此GitHub issue)。

因此,需要额外的setTimeout0 ms(或requestAnimationFrame),以便让浏览器知道该元素应该聚焦在call stack的末尾,这意味着在UI5认为它完成了最初预期的一切之后的焦点。

使用this commit(从1.63开始提供),不再需要这种解决方法。


1
投票

NavContainer有一个属性autoFocusAppNavContainer的后裔,所以它也有这个属性。帮助(如上所述)说明如下:

确定在首次渲染时和导航到新页面后是否自动设置初始焦点。当触摸设备上的键盘弹出时,由于焦点在输入字段上自动设置,这非常有用。如有必要,可以使用“afterShow”事件来聚焦另一个元素。

默认值为true。

© www.soinside.com 2019 - 2024. All rights reserved.