LoginSignup
5
2

More than 5 years have passed since last update.

Lightning コンポーネント開発メモ: ポップオーバーを使ってみた

Last updated at Posted at 2018-10-30

今回は lightning:overlayLibrary でポップアップを表示してみました。
単純にポップオーバーを表示するだけであれば特に迷わないのですが、ポップオーバー自体へのマウスホバーで少し迷いました。(これくらい機能として持っていてくれてもいいじゃないか!)

動作イメージ

  • 特定の要素にマウスホバーした時に、ポップオーバーを表示
  • 表示されたポップオーバーにもマウスホバー出来る ezgif-1-f94666cc896f.gif

サンプルコード

SimplePopoverExample.cmp
<aura:component implements="flexipage:availableForAllPageTypes" access="global" >
    <!-- Public Attributes -->
    <aura:attribute access="public" type="Aura.component" name="popover" />
    <aura:attribute access="public" type="Integer"        name="closeTimer" />

    <!-- Overlay Library -->
    <lightning:overlayLibrary aura:id="overlayLib"/>

    <!-- User Interface -->
    <div>
        <lightning:card iconName="utility:quick_text" title="Simple Popover Example">
            <lightning:layout>
                    <lightning:layoutItem padding="around-medium" size="12">
                        <span class="popoverReference">
                            <a href="javascript:void(0);" onmouseenter="{!c.onMouseEntered}" onmouseleave="{!c.onMouseLeft}">
                                ホバーするとポップオーバーが出るよ!
                            </a>
                        </span>
                    </lightning:layoutItem>
            </lightning:layout>
        </lightning:card>
    </div>
</aura:component>
SimplePopoverExampleController.js
({
    onMouseEntered: function(c, e, h) {

        // 既に開いているポップオーバーがあれば、まず閉じる。
        const popover = c.get("v.popover");
       if (popover) popover.close();


        // ポップオーバーのボディを作成する。
        const parser = new DOMParser();
        const popoverBody = parser.parseFromString("<div style=\"padding:16px;\">Hello World!</div>", "text/html").querySelector("body").firstChild;

        // ポップオーバーにマウスホバーした時にポップオーバーを閉じたくないのでクローズ待ちタイマーを止める。
        // ポップオーバーからマウスが離れたら、ポップオーバーを閉じる。
        popoverBody.addEventListener("mouseenter", $A.getCallback(function(){
            clearTimeout(c.get("v.closeTimer"));
        }));
        popoverBody.addEventListener("mouseleave", $A.getCallback(function(){
            const popover = c.get("v.popover");
            if (popover) popover.close();
        }));


        // ポップオーバーを表示する
        const overlayLib = c.find("overlayLib");
        overlayLib.showCustomPopover({
            body: popoverBody, // ポップオーバーのボディ
            referenceSelector: ".popoverReference", // ポップオーバーを表示する親要素のセレクタ
         }).then(function (popover) {
            c.set("v.popover", popover);
        })
        .catch(function(reason) {
            console.error(reason);
        }); 
    },
    onMouseLeft: function(c, e, h) {

        // 親要素からマウスが離れた時は、ポップオーバーにホバーしていなければ閉じる。
        // (ホバーした場合はクローズ待ちタイマーを止める)
        c.set("v.closeTimer", setTimeout($A.getCallback(function(){
            const popover = c.get("v.popover");
            if (popover) popover.close();
        }), 100));
    },
})
SimplePopoverExample.css
.THIS .popoverReference {
   padding-right: 1rem;
}

気になった点

表示されたポップオーバーの矢印が、ホバーした親要素に重なる(!マークが隠れてる)。

Screen_Shot_2018-10-30_at_19_23_48.png

  • マウスホバーの要素の上位にポップオーバーの参照要素を作成し、パディングで調整する。 padding-right: 1rem;
ポップオーバーのボディを動的に作成した場合、たまに矢印の位置がずれる

Screen_Shot_2018-10-30_at_19_26_46.png

  • 何回か表示/非表示を繰り返すと揃うようになるので、多分ポッポオーバーのボディの高さ確定とポップオーバーの位置算出のタイミングの問題。
  • 高さを早く確定して上げる必要があるので、すべてのデータが揃ってからポップオーバーの描画を開始するのが良さそう。
5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2