所以,我正在创建我的第一个 Web 组件,我正在努力处理影子根中元素的事件处理方面。
此组件的目标是显示来自端点的结果列表,用户在输入字段中键入内容,然后从所选元素中获取文本并将其显示在同一输入字段中。
HTMl 是这样的:
<div class="results">
<ul>
<li class="result-item"><i></i><span>Amalfiküste</span></li>
<li class="result-item"><i></i><span>Guatemala</span></li>
<li class="result-item"><i></i><span>Italien, Malta</span></li>
<li class="result-item"><i></i><span>Malaysia</span></li>
<li class="result-item"><i></i><span>Malediven</span></li>
<li class="result-item"><i></i><span>Mallorca</span></li>
<li class="result-item"><i></i><span>Malta</span></li>
</ul>
</div>
然后查询结果项:
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);
});
}
}
我已经检查了控制台,看我是否正在查询结果项字段并且它工作正常。问题是单击每一个,将文本选择到输入中并将其作为自定义事件分派以供另一个组件使用。
我们如何处理影子根元素中的点击事件?
需要在事件中使用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 });
}
}
代替
<li class="result-item"><i></i><span>Amalfiküste</span></li>
让它成为一个 Web 组件
<result-item>
并保持 all(交互)逻辑 inside Web Component
customElements.define("result-item",class extends HTMLElement{
connectedCallback(){
let input = this.closest("div").querySelector("input");
input.addEventListener("keyup", (evt) => {
let match = this.innerHTML.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";
}
});
<div>
<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>
</ul>
</div>