单击时切换相同类型的所有stencil.js组件

问题描述 投票:0回答:3

我正在创建一个工具栏,该工具栏将用于文本编辑。

使用此代码创建工具栏中的每个项目:

import {Component, h, Prop, Event, EventEmitter} from '@stencil/core';

@Component({
  tag: 'spa-toolbar-item',
  styleUrl: 'spa-toolbar-item.scss',
})

export class spaToolbarItem {
  @Prop({reflectToAttr: true, mutable: true}) toggle: boolean = false;
  @Prop({reflectToAttr: true}) type: string;
  @Event() onToggle: EventEmitter;

  toggleComponent(): void {
    this.toggle = !this.toggle;
    this.onToggle.emit({visible: this.toggle});
  }

  render() {
    return [
      <button onClick={() => this.toggleComponent()}>
        <slot/>
      </button>,
      <div class={this.toggle ? 'is-active' : null}>
        {this.type == 'font'
          ? <div class={this.type}>
            <span class="arial">Arial</span>
            <span class="georgia">Georgia</span>
            <span class="palatino">Palatino</span>
            <span class="tahoma">Tahoma</span>
            <span class="times">Times New Roman</span>
            <span class="helvetica">Helvetica</span>
            <span class="courier">Courier New</span>
            <span class="lucida">Lucida Sans Typewriter</span>
            <span class="verdana">Verdana</span>
          </div>
          : null}
      </div>
    ]
  }
}

这可以按预期工作,但是,我希望单击一个项目时关闭所有其他下拉菜单,因此基本上,'this.toggle'需要应用于所有非活动的下拉菜单。我该怎么办?

javascript typescript stenciljs tsx
3个回答
0
投票

因此,想法是将addEventListener应用于文档以及组件本身(主机-下拉列表)。为此,您可以使用生命周期钩,例如componentdidload

import {Component, h, Prop, Event, EventEmitter} from '@stencil/core';

@Component({
  tag: 'spa-toolbar-item',
  styleUrl: 'spa-toolbar-item.scss',
})

export class spaToolbarItem {
  @Prop({reflectToAttr: true, mutable: true}) toggle: boolean = false;
  @Prop({reflectToAttr: true}) type: string;
  @Event() onToggle: EventEmitter;

private hostElement;
private buttonElement;
  closeDropdown(){
    this.toggle = false;
  }
  toggleComponent(): void {
    this.toggle = !this.toggle;
    this.onToggle.emit({visible: this.toggle});
  }

render() {
 return 
 <Host ref={(el) => this.hostElement = el}>
   //everything you had before in the return value
 </Host>
}

 componentDidLoad(){
  document.addEventListener("click", ()=>{this.clickManager("document");}, true)
  this.hostElement.addEventListener("click", ()=>{this.clickManager("dropdown");}, true)
 }

 private clickManager(identifier){
   if(identifier == "dropdown"){
     //the clicked dropdown -> active dropdown
     this.toggleComponent();
     return;
   }
   //all non active Dropdowns
   this.closeDropdown();
 }

}

您可以看到,我们有两个事件正在调用clickManager。第一个是文档,第二个是您单击的下拉列表。当然,您必须删除按钮上的onclick事件,但是此代码无法正常工作。现在,您可以决定如果单击下拉列表会发生什么情况,以及所有非活动下拉列表会发生什么情况。

这是基本概念,可以根据需要随时进行调整和更改。


0
投票

感谢Christian,我最终在下面使用了此解决方案。

import {Component, h, Prop, Host, Element} from '@stencil/core';

@Component({
  tag: 'spa-toolbar-item',
  styleUrl: 'spa-toolbar-item.scss',
})

export class spaToolbarItem {
  @Prop({reflectToAttr: true, mutable: true}) isOpen: string = 'false';
  @Prop({reflectToAttr: true}) type: string;
  @Element() el: HTMLElement;

  openDropdown() {
    function closeDropdown() {
      let dropdowns = document.querySelectorAll('spa-toolbar-item[is-open]');
      dropdowns.forEach(item => {
        item.setAttribute('is-open', 'false')
      });
    }

    if (this.el.getAttribute('is-open') == 'true') {
      closeDropdown();
      return
    }

    if (this.el.getAttribute('is-open') == 'false') {
      closeDropdown();
      this.el.setAttribute('is-open', 'true')
    }
  }

  render() {
    return (
      <Host>
        <button onClick={this.openDropdown.bind(this)}>
          <slot/>
        </button>
        <div class={this.type}>
          {this.type == 'font'
            ? <div>
              <span class="arial">Arial</span>
              <span class="georgia">Georgia</span>
              <span class="palatino">Palatino</span>
              <span class="tahoma">Tahoma</span>
              <span class="times">Times New Roman</span>
              <span class="helvetica">Helvetica</span>
              <span class="courier">Courier New</span>
              <span class="lucida">Lucida Sans Typewriter</span>
              <span class="verdana">Verdana</span>
            </div>
            : null}
        </div>
      </Host>
    )
  }
}

-1
投票

您可以使用纯javascript做的事情是,使用class-active遍历所有元素,并将每个元素的toggle的属性设置为0(或任何您执行的方式)

示例:

new Array(document.getElementsByClassName('is-active')).forEach(function(e){/*Set toggle property to 0*/});

这是什么,用is-active搜索所有元素,反复遍历并设置一个函数,在此函数中,参数e等于当前元素,您可以在此处设置属性。

© www.soinside.com 2019 - 2024. All rights reserved.