在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);
},
..更新程序是自定义函数,我添加到负责更新其内容的磁贴。
问题是:我想检查该区块当前是否对用户可见(即,不在页面中或当前未被选中但之前呈现的选项卡中)。 有没有办法使用对象属性实现这一目标?我需要手动管理它吗?
你可以利用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克里斯
现在所有主流浏览器都支持Web API IntersectionObserver
,包括Safari.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是否已经预先支持本机。如果不支持,则所需的对象和方法将连续添加到全局对象中。 polyfilled API的签名等同于本机API。