我正在创建一个工具栏,该工具栏将用于文本编辑。
使用以下代码创建工具栏中的每个项目:
public override void CollectObservations()
{
//internal info
AddVectorObs(gameObject.transform.rotation.z);
AddVectorObs(gameObject.transform.position);
Vector3 externalInfo1 = ExternalInfoGetter.StaticGetInfo1();
AddVectorObs(externalInfo1);
float externalInfo2 = ExternalInfoGetter.StaticGetInfo2();
AddVectorObs(externalInfo2);
}
这可以按预期工作,但是,我希望在单击一个项目时关闭所有其他下拉菜单,因此基本上,'this.toggle'需要应用于所有非活动的下拉菜单。我该怎么办?
答案 0 :(得分: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事件,但是此代码无法正常工作。现在,您可以决定如果单击下拉菜单会发生什么情况,以及所有非活动的下拉菜单会发生什么情况。
这是基本概念,可以根据需要随时进行调整和更改。
答案 1 :(得分: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>
)
}
}
答案 2 :(得分:-1)
使用纯JavaScript可以做什么,使用is-active类遍历所有元素,并将每个元素的toggle属性设置为0(或您执行的方式)
示例:
new Array(document.getElementsByClassName('is-active')).forEach(function(e){/*Set toggle property to 0*/});
这是什么,用is-active
搜索所有元素,遍历它们,并设置一个函数,在此函数中,参数e等于当前元素,您可以在此处设置属性。