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

时间:2018-02-01 16:44:43

标签: dom sapui5

在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);
},

..更新者是自定义函数,我添加到负责更新其内容的图块中。

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

2 个答案:

答案 0 :(得分: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 :(得分:1)

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

基本语法

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

演示

以下是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>

填充

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

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

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