UI5:检查控件当前是否呈现且可见

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

在SAPUI5应用程序中,我想仅在用户当前可见时才更新控件的内容(例如,图块)。我创建了一个这样的函数:

updatePage: function() {
  for (var i = 0; i < this.myTiles.length; i++) {
    if (this.myTiles[i].updater) {
      this.myTiles[i].updater();
    }
  }
  setTimeout(this.updatePage.bind(this), 10000);
},

..更新程序是自定义函数,我添加到负责更新其内容的磁贴。

问题是:我想检查该区块当前是否对用户可见(即,不在页面中或当前未被选中但之前呈现的选项卡中)。 有没有办法使用对象属性实现这一目标?我需要手动管理它吗?

dom sapui5
2个回答
1
投票

你可以利用jQuery做到这一点。

// determine whether your control is still part of the active DOM
jQuery.contains(document, yourControl.$());

// determine whether your control is visible (in terms of CSS)
yourControl.$().is(':visible');

// combined
MyControl.prototype.isVisible = function() {
  return this.$().length && // has rendered at all
    jQuery.contains(document, this.$()) && // is part of active DOM
    this.$().is(':visible'); // is visible
};

通过以下方式,用户仍然可以看不到元素:

  • 离开视口
  • visibility: hidden
  • opacity: 0
  • ...

还要检查this answer

BR克里斯

http://api.jquery.com/jQuery.contains/

http://api.jquery.com/visible-selector/


1
投票

现在所有主流浏览器都支持Web API IntersectionObserver,包括Safari.src

Basic syntax

const observer = new IntersectionObserver(callback/*, settings?*/);
observer.observe(domElement);

Demo

以下是UI5的演示。运行代码段并尝试滚动。页面标题会根据目标元素的可见性而更改:

sap.ui.getCore().attachInit(() => sap.ui.require([
  "sap/ui/core/mvc/XMLView",
  "sap/ui/model/json/JSONModel",
], (XMLView, JSONModel) => XMLView.create({
  definition: `<mvc:View xmlns:mvc="sap.ui.core.mvc"
    xmlns:core="sap.ui.core"
    xmlns="sap.m"
    displayBlock="true"
  >
    <App>
      <Page title="Tile visible: {= %{/ratio} > 0}">
        <FlexBox renderType="Bare"
          height="310vh"
          justifyContent="Center"
          alignItems="Center"
        >
          <core:Icon id="myBox"
            src="sap-icon://color-fill"
            size="10rem"
            color="Critical"
          />
        </FlexBox>
      </Page>
    </App>
  </mvc:View>`,
  afterInit: function() {
    this.byId("myBox").addEventDelegate({
      onAfterRendering: onAfterRenderingBox.bind(this),
    });
  },
  models: new JSONModel(),
}).then(view => view.placeAt("content"))));

function onAfterRenderingBox() {
  const domRef = this.byId("myBox").getDomRef();
  new IntersectionObserver(myCallback.bind(this)).observe(domRef);
}

function myCallback(entries) {
  const entry = getTarget(entries, this.byId("myBox").getDomRef());
  this.getModel().setProperty("/ratio", entry.intersectionRatio);
}

function getTarget(entries, source) {
  return entries.find(entry => entry.target === source);
}
<script id="sap-ui-bootstrap"
  src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
  data-sap-ui-libs="sap.ui.core, sap.m"
  data-sap-ui-async="true"
  data-sap-ui-theme="sap_belize"
  data-sap-ui-compatVersion="edge"
  data-sap-ui-xx-waitForTheme="true"
></script>
<body id="content" class="sapUiBody sapUiSizeCompact"></body>

Polyfill

如果目标浏览器(例如IE11)仍未完全支持IntersectionObserver,则可以将以下polyfill添加到项目中:

https://github.com/w3c/IntersectionObserver/blob/master/polyfill/intersection-observer.js

polyfill会检查API是否已经预先支持本机。如果不支持,则所需的对象和方法将连续添加到全局对象中。 polyfilled API的签名等同于本机API。

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