【问题标题】:How do I add and remove classes using event listeners in Lit-HTML?如何使用 Lit-HTML 中的事件侦听器添加和删除类?
【发布时间】:2019-06-17 08:02:26
【问题描述】:

我想在使用 'dragEnter' 和 'dragLeave' 触发的 lit-html 模板创建的元素上从我的类中添加和删除 'over'

#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', '');
  }

【问题讨论】:

    标签: javascript lit-html


    【解决方案1】:

    我认为,为了以“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 时,您必须将您的 UI 表达为您的“状态”和每次状态更改时“重新渲染”的函数,因此这个小示例中的最佳解决方案是将您的类视为您的状态的一部分.

    【讨论】:

      【解决方案2】:

      这取决于您的自定义元素的外观。使用您的模板,您只需输入@dragover=${this.dragEnter}。但是,如果您希望将其应用于整个自定义元素而不仅仅是按钮,您可以执行以下操作:

      connectedCallback() {
      super.connectedCallback();
      
      this.addEventListener('dragover', this.dragEnter);
      
      }
      

      如果您没有自定义元素并且仅使用 lit-html 本身,则必须将事件处理程序 dragEnter(e)dragLeave(e) 放入模板中,如下所示:@dragover=${this.dragEnter}

      您需要在dragEnter 中添加带有classList.add 的类,并在dragLeave 中将其删除。将来你也许可以在 lit-html 中使用classMap 指令,但是只使用classList 并没有错。我会坚持只使用classList。在很遥远的将来,css 可能还会有一个选择器:Is there a CSS ":drop-hover" pseudo-class?

      【讨论】:

      • 我没有任何自定义元素,我使用的是 lit-html 本身,而不是 lit-element 或其他类似元素。我不确定您的代码如何与 CSS 相关,您是说我必须使用回调到 this.dragEnter,如果是这样,该方法将是什么,它将如何引用
      • 根据您的评论更新了答案。
      • 感谢您的更新,但这只是部分答案,您没有解决 CSS 或 dragEnter() 方法可能包含的内容。我是 lit-html 的新手,文档现在严重不足(它仍然是预发布版)。什么是最佳实践?我的方法应该像以前一样改变 DOM 吗?我应该将新变量输入模板/使用新的类绑定重新编写它吗?每次回调后再次运行 render() 函数?如果您能在代码中提供完整的解决方案,那就太好了 :) 感谢您的宝贵时间,非常感谢!
      • 添加了更多说明
      • 干杯! classMap 是我一直在寻找的东西,似乎是为这项工作而生的 :) 文档中没有任何内容,但源代码中的 cmets 解释了 github.com/Polymer/lit-html/blob/master/src/directives/…
      【解决方案3】:

      总比不上

      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/

      【讨论】:

      • 感谢关于classList 的精彩提示,我从旧代码中复制并以粗鲁结束,很好发现!我真的在寻找语法来设置事件侦听器以对 lit-html 模板中的类进行这些更改。您的示例代码可以部分工作,但错过了与事件侦听集成的重要语法:(
      猜你喜欢
      • 2018-04-26
      • 2012-07-18
      • 1970-01-01
      • 2013-06-27
      • 2011-02-28
      相关资源
      最近更新 更多