Как добавить и удалить классы, используя прослушиватели событий в Lit-HTML?

Я хотел бы добавить и удалить 'over' из моего класса для элемента, созданного с использованием шаблона lit-html, запускаемого с помощью dragEnter и dragLeave:

#app {
  background-color: #72a2bc;
  border: 8px dashed transparent;
  transition: background-color 0.2s, border-color 0.2s;
}

#app.over {
  background-color: #a2cee0;
  border-color: #72a2bc;
}
const filesTemplate = () =>
html`
  <button id="app"     
    @dragover=${??}
    @dragleave=${??}     
  >
    Click Me
  </button>
`;

В моей старой системе я вызывал эти методы в отдельном модуле с помощью генератора событий, но я надеюсь, что смогу все это определить в шаблоне с помощью lit-html.

 dragEnter(e) {
    this.view.element.className += ' over';
  }

  dragLeave(e) {
    this.view.element.className = element.className.replace(' over', '');
  }

2 ответа

Решение

Это зависит от того, как выглядит ваш пользовательский элемент. С вашим шаблоном вы можете просто положить @dragover=${this.dragEnter}, Однако, если вы хотите, чтобы это применялось ко всему пользовательскому элементу, а не только к кнопке, вы можете сделать что-то вроде этого:

connectedCallback() {
super.connectedCallback();

this.addEventListener('dragover', this.dragEnter);

}

Если у вас нет пользовательского элемента и вы просто используете lit-html, вы должны установить обработчики событий dragEnter(e)а также dragLeave(e) в шаблон так: @dragover=${this.dragEnter}

Вам нужно добавить класс с classList.add в dragEnter и удалите его в dragLeave. В будущем вы можете использовать classMap директива в lit-html, однако нет ничего плохого в использовании только classList, Я бы придерживался только использования classList. В очень далеком будущем CSS может также иметь селектор для этого: есть ли CSS ":drop-hover" псевдокласс?

Я думаю, что для решения проблемы в стиле "lit-html" решение должно быть примерно таким:

import { html, render} from 'lit-html';
import { classMap } from 'lit-html/directives/class-map.js';

const myBtnClasses = {
  over: false
};
function dragEnter(e) {
  myBtnClasses.over = true;
  renderFiles();
}
function dragLeave(e) {
  myBtnClasses.over = false;
  renderFiles();
}

const filesTemplate = (classes) =>
html`
  <button id="app" class="${classMap(myBtnClasses)}"
    @dragover=${dragEnter} @dragleave=${dragLeave}     
  >
    Click Me
  </button>
`;
function renderFiles() {
  render(filesTemplate(myBtnClasses), YOUR_CONTAINER);
}

Когда используешь lit-html вы должны выражать свой пользовательский интерфейс как функцию вашего "состояния" и "повторной визуализации" каждый раз, когда ваше состояние изменяется, поэтому лучшим решением в этом небольшом примере является рассмотрение ваших классов как части вашего состояния.

Во всяком случае лучше, чем

this.view.element.className += ' over';

является

this.view.element.classList.add('over');

И вместо того, чтобы

this.view.element.className = element.className.replace(' over', '');

использование

this.view.element.classList.remove('over');

Это лучше, потому что позволяет избежать многих ошибок, таких как многократное добавление одного и того же класса.

Я не знаю lit-html но попробую

let sayHello = (name, myClass) => html`<h1 class="${myClass}">Hello ${name}</h1>`;

https://lit-html.polymer-project.org/

Другие вопросы по тегам