[英]CSS Transition not working with Javascript on web component
我是 Javascript 新手,我正在尝试创建一个 web 组件,正是某种列表视图。 目标是当我单击一个项目时它可以展开和折叠,并且我希望它与过渡有关。
我已经在模板上放置了过渡,但由于某种原因,它不起作用,只是在没有动画的情况下立即增长或折叠。 很少,如果我做一个const listView = document.querySelector(".list-view")
然后listView.collapse()
它工作。
总结代码是:
class ListItem extends HTMLElement {
constructor(items = []) {
super();
//Template and its variables
const listItemTemplate = document.createElement("template");
listItemTemplate.innerHTML = `
<style>
.listitem{
//some other properties
transition: height 0.3s cubic-bezier(0.65, 0, 0.35, 1);
height: ${this.initialHeight};
}
//Other styles...
</style>
changedItem(itemSelected){
//More stuff
this.refreshDOMItems();
this.collsapse();
}
`;
expand() {
let height = 10;
Array.from(this.itemsHTML).forEach((item) => {
height += item.clientHeight;
});
this.listItem.style.height = height / 16 + "rem";
}
collapse() {
this.listItem.style.height = this.initialHeight;
}
编辑:这是一个 Codepen。
我在做什么错? 希望代码不是很复杂。 先感谢您!
您正在使用transition: background .5s ease;
覆盖高度过渡transition: background .5s ease;
在.listitem:hover
,因此删除此行可以解决问题:
.listitem:hover{
/*transition: background .5s ease;*/
background: rgba(255,255,255,.65);
}
class ListItem extends HTMLElement { constructor(items = []) { super(); //Template and its variables this.initialHeight = "3.75rem"; this.initialBorderRadius = stringToNumber(this.initialHeight) / 2 + "rem"; const listItemTemplate = document.createElement("template"); listItemTemplate.innerHTML = ` <style> ul{ box-sizing: border-box; margin: 0px; padding: 0px; list-style: none; } .ul{ display: flex; align-items: center; flex-direction: column; height: 3.75rem; } .listitem{ font-family: 'Nunito', sans-serif; display: inline-block; overflow: hidden; box-sizing: border-box; background-color: white; border-radius: ${this.initialBorderRadius}; padding: 0px 1rem; cursor: pointer; box-shadow: 0px 0px 1.25rem rgba(4,25,106,.14); transition: height 0.3s cubic-bezier(0.65, 0, 0.35, 1); height: ${this.initialHeight}; } li.item{ box-sizing: border-box; min-height: ${this.initialHeight}; display: flex; align-items: center; -webkit-touch-callout: none; /* iOS Safari */ -webkit-user-select: none; /* Safari */ -khtml-user-select: none; /* Konqueror HTML */ -moz-user-select: none; /* Old versions of Firefox */ -ms-user-select: none; /* Internet Explorer/Edge */ user-select: none; /* Non-prefixed version, currently supported by Chrome, Edge, Opera and Firefox */ } .img{ width: 2rem; margin-right: 0.625rem; border-radius: 50%; } .name{ font-size: 1.125rem; font-weight: 700; color: var(--autores); margin-right: 0.6rem; } .listitem:hover{ /*transition: background .5s ease;*/ background: rgba(255,255,255,.65); }</style> <div class="listitem"> <ul class="ul"> </ul> </div> `; //Constructor this.attachShadow({ mode: "open" }); this.shadowRoot.appendChild(listItemTemplate.content.cloneNode(true)); this.items = items; this.listItem = this.shadowRoot.querySelector(".listitem"); this.itemsHTML = this.shadowRoot .querySelector(".listitem") .querySelector(".ul").children; const ul = this.shadowRoot.querySelector(".listitem").querySelector(".ul"); this.ul = ul; } connectedCallback() { //Do //Carga de items por defecto const item = { name: "Item", avatar: "images/users.svg", selected: false }; const item_two = { name: "Item 2", avatar: "images/users.svg", selected: false }; const item_three = { name: "Item 3", avatar: "images/users.svg", selected: false }; this.addItem(item); this.addItem(item_two); this.addItem(item_three); this.refreshDOMItems(); //event listeners for each item; const itemClick = this.shadowRoot.querySelector(".listitem"); itemClick.addEventListener("click", (event) => { event.preventDefault(); let targetStr = ""; const trgtCls = event.target.classList; if ( trgtCls.contains("name") || trgtCls.contains("img") || trgtCls.contains("item") ) { if (trgtCls.contains("name")) { targetStr = event.target.innerText; } if (trgtCls.contains("img")) { targetStr = event.target.nextElementSibling.innerText; } if (trgtCls.contains("item")) { targetStr = event.target.querySelector(".name").innerText; } } if (targetStr === this.items[0].name) { this.expand(); } else { this.changedItem(targetStr); } }); } addItem(item = Object) { this.items.push(item); this.items.forEach((item) => { item.selected = false; }); this.items[0].selected = true; console.log(item.selected); } refreshDOMItems() { removeChildNodes(this.ul); this.items.forEach((item) => { const itemTemplate = document.createElement("template"); itemTemplate.innerHTML = ` <li class="item"> <svg viewBox="0 0 512 512" width="100" title="user-alt" class="img"> <path d="M256 288c79.5 0 144-64.5 144-144S335.5 0 256 0 112 64.5 112 144s64.5 144 144 144zm128 32h-55.1c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16H128C57.3 320 0 377.3 0 448v16c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48v-16c0-70.7-57.3-128-128-128z" /> </svg> <p class="name">${item.name}</p> </li> `; this.ul.appendChild(itemTemplate.content.cloneNode(true)); }); } getItems() { return this.items; } changedItem(itemSelected) { let arr = Array.from(this.items); this.items.forEach(function(item, index) { if (item.name == itemSelected) { arr = moveElementArray(arr, index, 0); } }); this.items = arr; this.items.forEach((item) => { item.selected = false; }); this.items[0].selected = true; this.refreshDOMItems(); this.collapse(); } selected() { let selected; this.items.forEach((item) => { if (item.selected === true) { selected = item; } }); return selected; } value() { let selected; this.items.forEach((item) => { if (item.selected === true) { selected = item; } }); return selected.name; } expand() { let height = 10; Array.from(this.itemsHTML).forEach((item) => { height += item.clientHeight; }); this.listItem.style.height = height / 16 + "rem"; } collapse() { this.listItem.style.height = this.initialHeight; } } window.customElements.define("c-list-item", ListItem); const lsim = document.querySelector(".list"); function removeChildNodes(element = HTMLElement) { while (element.childElementCount > 0) { element.removeChild(element.firstChild); } } function stringToNumber(string = String) { let newNumber = ""; let afterComma = ""; let comma = false; Array.from(string).forEach((char) => { if (char === "." || char === ",") { comma = true; } if (comma === false) { if (Number(char)) { newNumber += Number(char); } } else { if (Number(char)) { afterComma += Number(char); } } }); if (afterComma != "") { newNumber += "." + afterComma; } return Number(newNumber); } function moveElementArray(array = Array, from = Number, to = Number) { const fromArr = array[from]; if (from > to) { for (let index = from; index >= to; index--) { array[index] = array[index - 1]; if (index == to) { array[index] = fromArr; } } } else { for (let index = from; index <= to; index++) { array[index] = array[index + 1]; if (index == to) { array[index] = fromArr; } } } return array; } function replaceElementArray(array = Array, from = Number, to = Number) { const fromArr = array[from]; const toArr = array[to]; array[from] = toArr; array[to] = fromArr; return array; }
<body style="background-color: #f0f0f0;"> <c-list-item class="list"></c-list-item> </body>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.