javascript 在Web组件中如何在单击外部或单击其他工具提示时显示和隐藏工具提示

ndh0cuux  于 2023-02-11  发布在  Java
关注(0)|答案(2)|浏览(157)

我有一个Web组件,其中包含带有工具提示的卡片。
我正在尝试完成三件事。我正在尝试使用香草Javascript vs jQuery或其他库。
1.单击按钮时显示,再次单击按钮时隐藏。此操作当前有效。
1.在按钮外点击时隐藏。我试着选择文档,然后比较点击的元素和我想定位的元素,定位有问题。
1.一次只显示一个工具提示,所以如果一个打开了,然后你点击另一个,只有第二个显示。不知道如何处理这个。
以下是我目前的情况。

class BuildABox extends HTMLElement {
  constructor() {
    super();
    this.querySelectorAll('[data-tooltip]').forEach((button) =>
      button.addEventListener('click', this.toggleTooltip.bind(this))
    );
  }

  toggleTooltip(e) {
    e.preventDefault();
    const toolTip = e.currentTarget.lastChild.previousSibling;
    toolTip.classList.toggle('tw-invisible');
  }
}

customElements.define('build-a-box', BuildABox);
<button id="info-btn" aria-label="Information" type="button" data-info="{{ block.settings.product_description }}">
  <div data-tooltip="tooltip" class="tw-w-12">
    <svg  xmlns="http://www.w3.org/2000/svg"
          viewBox="0 0 24 24"
          fill="currentColor"
          class="w-12 h-12"
    >
      <path fill-rule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zm8.706-1.442c1.146-.573 2.437.463 2.126 1.706l-.709 2.836.042-.02a.75.75 0 01.67 1.34l-.04.022c-1.147.573-2.438-.463-2.127-1.706l.71-2.836-.042.02a.75.75 0 11-.671-1.34l.041-.022zM12 9a.75.75 0 100-1.5.75.75 0 000 1.5z" clip-rule="evenodd" />
      </svg>
    {% comment %} This is tooltip to hide/show {% endcomment %}
    <div
      id="tooltip"
      class="tw-invisible z-50 tw-absolute tw-top-24  tw-max-w-[300px] tw-bg-blue-400 tw-text-white tw-border-graphite tw-border-2 tw-overflow-auto tw-rounded-2xl tw-p-4 tw-mt-1"
                              >
      <p>{{ block.settings.product_description }}</p>
    </div>
  </div>
</button>
zdwk9cvp

zdwk9cvp1#

您不希望创建依赖项,因此请尽可能多地将逻辑*保留在Web组件*内部
此处使用shadowDOM是因为它使Web组件保持

您可以使用::part全局CSS设置样式
关键概念:<my-button tooltip>
tooltip属性确定它是否可见
我在额外的风格重击显示更多的风格选项。
有关<slot>::slotted的详细信息,请阅读:::shadowDOM槽中嵌套子级的槽CSS选择器
相同代码:https://jsfiddle.net/WebComponents/xg3ns6od/

customElements.define('my-button', class extends HTMLElement {
  constructor() {
    super().attachShadow({mode:"open"}).innerHTML =
    `<style>`+
      `button{ width:120px; cursor:pointer } ::slotted(div){ pointer-events:none }` + 
      `[name="tooltip"]::slotted(div) { color:blue; font-size: 1.2rem }`+
      `[name="label"]::slotted(div) { font-size:1em;font-weight:bold }`+
      `:host([tooltip]) svg { fill:green!important } `+
      `:host(:hover:not([tooltip])) path{ scale:1.2; transform-origin: center }` +
      `:host(:not([tooltip])) [name="tooltip"]::slotted(div) { visibility:hidden } `+
    `</style>`+
    `<button part="button"><svg part="icon" viewBox="0 0 2400 2400">`+
      `<path fill-rule="evenodd" d="m225 1200c0-539 437-975 975-975s975 437 975 975-437 975-975 975-975-436-975-975zm871-144c115-57 244 46 213 171l-71 284 4-2a75 75 90 0167 134l-4 2c-115 57-244-46-213-171l71-284-4 2a75 75 90 11-67-134l4-2zm104-156a75 75 90 100-150 75 75 90 000 150z"/>`+
      `</svg><slot name="tooltip"></slot>`+
            `<slot name="label"></slot></button>`;
  }
  connectedCallback(){
    this.onclick = () => this.tooltip = !this.tooltip;
    this.globalListener = document.addEventListener("click",
                                  (evt) => this.tooltip = evt.target == this )
  }
  get tooltip()   { return this.hasAttribute("tooltip") }
  set tooltip(val){ this.toggleAttribute("tooltip",val) }

  disconnectedCallback(){
    document.removeEventListener("click", this.globalListener);
  }
});
/* style parts IN shadowDOM */
my-button::part(icon){ fill:red }

/* style lightDOM! */
my-button[tooltip] [slot="tooltip"] { background:lightgreen }
<my-button>
  <div slot="tooltip">Tooltip 1</div>
  <div slot="label">Product Description</div>
</my-button>
<my-button tooltip>
  <div slot="tooltip">Tooltip 2</div>
  <div slot="label">Product Description</div>
</my-button>
<my-button>
  <div slot="tooltip">Tooltip 3</div>
  <div slot="label">Product Description</div>
</my-button>
vngu2lb8

vngu2lb82#

解释我先前删除的评论;我稍微更新了你的代码,并添加了一些CSS来清楚地显示它。我有一个数据元素来选择一个目标,然后在点击处理程序中使用它。

class BuildABox extends HTMLElement {
  constructor() {
    super();
    this.querySelectorAll('[data-tooltip-target]').forEach((button) => {
      button.addEventListener('click', this.toggleTooltip.bind(this))
    });
  }

  toggleTooltip(e) {
    e.preventDefault();
    const mytarget = e.currentTarget.dataset.tooltipTarget;
    const toolTip = e.currentTarget.querySelector(`[data-tooltip="${mytarget}"]`);
    toolTip.classList.toggle('tw-invisible');
  }
}

customElements.define('build-a-box', BuildABox);
.tw-invisible {
  display: none;
}

.tooltip-text {
  color: blue;
  font-size: 1.5rem;
}
<build-a-box>
  <button id="info-btn" aria-label="Information" type="button" data-info="{{ block.settings.product_description }}" data-tooltip-target="mine">
  <div class="tw-w-12">
    <svg  xmlns="http://www.w3.org/2000/svg"
          viewBox="0 0 24 24"
          fill="currentColor"
          class="w-12 h-12"
    >
      <path fill-rule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zm8.706-1.442c1.146-.573 2.437.463 2.126 1.706l-.709 2.836.042-.02a.75.75 0 01.67 1.34l-.04.022c-1.147.573-2.438-.463-2.127-1.706l.71-2.836-.042.02a.75.75 0 11-.671-1.34l.041-.022zM12 9a.75.75 0 100-1.5.75.75 0 000 1.5z" clip-rule="evenodd" />
      </svg>
    <tool-tip data-tooltip="mine" class="tw-invisible">
    <span class="tooltip-text">This is tooltip to hide/show</span>
    </tool-tip>
    <div class="z-50 tw-absolute tw-top-24  tw-max-w-[300px] tw-bg-blue-400 tw-text-white tw-border-graphite tw-border-2 tw-overflow-auto tw-rounded-2xl tw-p-4 tw-mt-1">
      <p>{{ block.settings.product_description }}</p>
    </div> 
  </div>
</button>
</build-a-box>

相关问题