javascript 如何通过单击事件从影子根中的元素返回文本

ee7vknir  于 2023-05-05  发布在  Java
关注(0)|答案(2)|浏览(96)

所以,我正在创建我的第一个Web组件,我正在与影子根中的元素进行事件处理。
此组件的目标是显示来自端点的结果列表,用户在输入字段中键入,然后从所选元素中获取文本并将其显示在同一输入字段中。
HTMl是这样的:

<div class="results">
<ul>
<li class="result-item"><i></i><span>Amsterdam</span></li>
<li class="result-item"><i></i><span>Lisbon</span></li>
<li class="result-item"><i></i><span>Paris</span></li>
<li class="result-item"><i></i><span>London</span></li>
<li class="result-item"><i></i><span>Oslo</span></li>
<li class="result-item"><i></i><span>Copenhagen</span></li>
<li class="result-item"><i></i><span>Milan</span></li>
</ul>
</div>

然后查询result-item:

let resultItem = document.querySelector('destination-search').shadowRoot.querySelectorAll('.result-item');

以及将所选值输入到输入中的函数:

function selectTextIntoInput(resultItem, searchInput, shadowRoot) {
    for (let i = 0; i < resultItem.length; i++) {
        resultItem[i].addEventListener("click", function (event) {
            searchInput.value = resultItem[i].innerText;

            const destinationEvent = new CustomEvent('destination-search', {
                detail: resultItem[i].innerText,
                bubbles: true,
                composed: true
            });

            shadowRoot.dispatchEvent(destinationEvent);
        });
    }
}

我已经检查了控制台,看看我是否查询了结果项字段,它工作正常。问题是点击每一个,将文本选择到输入中,并将其作为一个自定义事件分发给另一个组件使用。
如何处理影子根元素中的单击事件?

pcww981p

pcww981p1#

需要在事件中使用composed选项,还需要使用箭头功能
像下面这样的更新代码:-

function selectTextIntoInput(resultItem, searchInput, shadowRoot) {
        for (let i = 0; i < resultItem.length; i++) {
            resultItem[i].addEventListener("click", (event) => {
                searchInput.value = resultItem[i].innerText;

                const destinationEvent = new CustomEvent('destination-search', {
                    detail: resultItem[i].innerText,
                    bubbles: true,
                    composed: true
                });

                this.dispatchEvent(destinationEvent);
            }, { composed: true });
        }
    }
wdebmtf2

wdebmtf22#

而不是<li class="result-item"><i></i><span>Amalfiküste</span></li>
使其成为Web组件<result-item>
并将所有(交互)逻辑保留在Web组件内

customElements.define("result-item",class extends HTMLElement{
  connectedCallback(){
    let input = this.closest("destination-search").querySelector("input");
    input.addEventListener("keyup", (evt) => {
      let match = this.innerText.includes(evt.target.value);
      this.closest("li").style.display = match ? "list-item" : "none";
    });
    this.onclick = (evt) => input.value = evt.target.innerText;  
    this.style.cursor = "pointer";
    //wait till lightDOM is parsed
    setTimeout(()=>this.innerHTML = `<b>${this.innerHTML}</b>`);
  }
});
body{ font:12px arial }
<destination-search>
  <input>
  <ul>
    <li><result-item>Amsterdam</result-item></li>
    <li><result-item>Rotterdam</result-item></li>
    <li><result-item>The Hague</result-item></li>
    <li><result-item>Utrecht</result-item></li>
    <li><result-item>Eindhoven</result-item></li>
    <li><result-item>Tilburg</result-item></li>
    <li><result-item>Groningen</result-item></li>
    <li><result-item>Almere</result-item></li>
    <li><result-item>Breda</result-item></li>
    <li><result-item>Nijmegen</result-item></li>
    <li><result-item>Haarlem</result-item></li>
    <li><result-item>Arnhem</result-item></li>
    <li><result-item>Zaanstad</result-item></li>
    <li><result-item>'s-Hertogenbosch</result-item></li>
    <li><result-item>Amersfoort</result-item></li>
    <li><result-item>Zierikzee</result-item></li>
  </ul>
</destination-search>

相关问题