UI5: Check if a control is currently rendered and visible

后端 未结 2 1452
攒了一身酷
攒了一身酷 2020-12-18 14:13

In a SAPUI5 application I would like to update the content of a control (e. g. a tile) only when this is currently visible to the user. I created a function like this:

相关标签:
2条回答
  • 2020-12-18 14:46

    You can utilize jQuery do achieve that.

    // 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
    };
    

    Elements could still be invisible to the user by being:

    • out of the viewport
    • visibility: hidden
    • opacity: 0
    • ...

    Also check this answer

    BR Chris

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

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

    0 讨论(0)
  • 2020-12-18 15:06

    The web API IntersectionObserver is now supported by all major browsers, including Safari.src

    Basic syntax

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

    Demo

    Below is a demo with UI5. Run the snippet and try to scroll there. The page title is changed depending on the visibility of the target element:

    sap.ui.require([
      "sap/ui/core/Core",
    ], Core => Core.attachInit(() => sap.ui.require([
      "sap/ui/core/mvc/XMLView",
      "sap/ui/model/json/JSONModel",
    ], (XMLView, JSONModel) => {
      "use strict";
    
      XMLView.create({
        definition: `<mvc:View xmlns:mvc="sap.ui.core.mvc"
          xmlns:core="sap.ui.core"
          xmlns="sap.m"
          displayBlock="true"
          height="100%"
        >
          <App>
            <Page title="Tile visible: {= %{/ratio} > 0}">
              <FlexBox renderType="Bare"
                height="360vh"
                justifyContent="Center"
                alignItems="Center"
              >
                <core:Icon id="myBox"
                  src="sap-icon://color-fill"
                  size="5rem"
                  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, null, true);
      }
    
      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_fiori_3"
      data-sap-ui-compatVersion="edge"
      data-sap-ui-xx-waitForTheme="init"
    ></script>
    <body id="content" class="sapUiBody sapUiSizeCompact"></body>

    Polyfill

    In case the IntersectionObserver is still not fully supported by the target browser (e.g. IE11), you can add the following polyfill to your project:

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

    The polyfill checks whether the API is already natively supported beforehand. If it's not supported, the needed objects and methods will be added to the global object consecutively. The signature of the polyfilled API is equivalent to the native API.

    0 讨论(0)
提交回复
热议问题