首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在WebComponent中添加事件

在WebComponent中添加事件
EN

Stack Overflow用户
提问于 2022-06-09 13:48:33
回答 1查看 57关注 0票数 1

我想要创建一个Web组件。我使用一个ShadowDom,在生成列表之后,我想向列表的每个元素添加一个单击事件。但我想知道怎样才能查到名单。

无论是文档还是模板,都不会在querySelect之后向我显示项目。

我的问题:如何访问webcomponent中生成的列表?

代码语言:javascript
复制
const news =
  {
    uk: [{
      id: 1,
      title: "News 1 UK",
      body: "lorem ipsum" 
    },
    {
      id: 2,
      title: "News 2 UK",
      body: "lorem ipsum" 
    },
    {
      id: 3,
      title: "News 3 UK",
      body: "lorem ipsum" 
    },
    {
      id: 4,
      title: "News 4 UK",
      body: "lorem ipsum" 
    },      
  ],
  de: [
    {
      id: 1,
      title: "News 1 DE",
      body: "lorem ipsum" 
    },
    {
      id: 2,
      title: "News 2 DE",
      body: "lorem ipsum" 
    },
    {
      id: 3,
      title: "News 3 DE",
      body: "lorem ipsum" 
    },
    {
      id: 4,
      title: "News 4 DE",
      body: "lorem ipsum" 
    }, 
  ]
  };

class MyNews {

  #limit = 10;
  #region = 'uk';
  news = [];
  
  constructor(conf = {}) {
    this.#limit = conf.limit ?? this.#limit;
    this.#region = conf.region ?? this.#region;
    this.news = news[this.#region]
  }

  
  showNews() {
    const items = this.news.slice(0,this.#limit);
    return items.map((n,i) => {
      return `<p>${i+1}. ${n.title}</p>`;
    }).join('');
  }
  
  getNewsData() {
    return this.news;
  }
}


class NewsTicker extends HTMLElement {
  
  constructor() {
    super();
    this.name = 'World News';
    this.limit = 10;
    this.region = "uk"
  }

  static get observedAttributes() {
    return ['name', 'url', 'limit', 'region'];
  }

  attributeChangedCallback(property, oldValue, newValue) {

    if (oldValue === newValue) return;
    this[ property ] = newValue;
    
  }

  async connectedCallback() {
    const options = {
      url: this.url, 
      limit: this.limit,
      region: this.region
    };
    const myNews = new MyNews(options);
    
    const 
      shadow = this.attachShadow({ mode: 'closed' }),
      template = document.getElementById('news-template').content.cloneNode(1),
      contextTitle = `Context ${ this.name } !`;

    template.querySelector('.news-context-title').textContent = contextTitle;
    template.querySelector('.news-list').innerHTML = myNews.showNews();
    shadow.append( template );
    
    const list = document.querySelector('.news-list');
    console.log("try to get list inner the template tag:", list)
  }
 
}

customElements.define( 'news-ticker', NewsTicker );
代码语言:javascript
复制
<news-ticker 
     name="News DE" 
     region="de" 
     limit="2">
</news-ticker>
<template id="news-template">
  <style>
    h2 {
      text-align: center;
      font-weight: normal;
      padding: 0.5em;
      margin: 1px 0;
      background-color: black;
      color: white;
      border: 1px solid #666;
      font-weight: bold;
    }
    
    .news-list > p {
      font-weight: normal;
      border: 1px solid #787878; 
      padding: 0.3em; 
      border-radius: 5px; 
      margin: 0.2em; 
      text-transform: capitalize; 
      text-align: left;
    }
    
    .news-list p:hover { 
      cursor: pointer; 
      background-color: #ffffd0; 
    }
  </style>

  <h2 class="news-context-title"></h2>
  <div class="news-list"></div>
</template>

<h1></h1>

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-10 06:08:07

您无法通过文档访问模板。模板标记是一个阴影DOM。如果将模式参数更改为true:this.attachShadow({ mode: 'open' }),则可以为访问影子DOM提供方便。然后您可以使用this.shadowRoot.querySel...。否则,您可以使用shadow = this.attachShadow({ mode: 'closed' })直接通过阴影对象( shadow.querySelector() )进行访问。

代码语言:javascript
复制
const news =
  {
    uk: [{
      id: 1,
      title: "News 1 UK",
      body: "lorem ipsum" 
    },
    {
      id: 2,
      title: "News 2 UK",
      body: "lorem ipsum" 
    },
    {
      id: 3,
      title: "News 3 UK",
      body: "lorem ipsum" 
    },
    {
      id: 4,
      title: "News 4 UK",
      body: "lorem ipsum" 
    },      
  ],
  de: [
    {
      id: 1,
      title: "News 1 DE",
      body: "lorem ipsum" 
    },
    {
      id: 2,
      title: "News 2 DE",
      body: "lorem ipsum" 
    },
    {
      id: 3,
      title: "News 3 DE",
      body: "lorem ipsum" 
    },
    {
      id: 4,
      title: "News 4 DE",
      body: "lorem ipsum" 
    }, 
  ]
  };

class MyNews {

  #limit = 10;
  #region = 'uk';
  news = [];
  
  constructor(conf = {}) {
    this.#limit = conf.limit ?? this.#limit;
    this.#region = conf.region ?? this.#region;
    this.news = news[this.#region]
  }

  
  showNews() {
    const items = this.news.slice(0,this.#limit);
    return items.map((n,i) => {
      return `<p>${i+1}. ${n.title}</p>`;
    }).join('');
  }
  
  getNewsData() {
    return this.news;
  }
}


class NewsTicker extends HTMLElement {
  
  constructor() {
    super();
    this.name = 'World News';
    this.limit = 10;
    this.region = "uk"
  }

  static get observedAttributes() {
    return ['name', 'url', 'limit', 'region'];
  }

  attributeChangedCallback(property, oldValue, newValue) {

    if (oldValue === newValue) return;
    this[ property ] = newValue;
    
  }

  async connectedCallback() {
    const options = {
      url: this.url, 
      limit: this.limit,
      region: this.region
    };
    const myNews = new MyNews(options);
    
    const 
      shadow = this.attachShadow({ mode: 'open' }), // change mode to open then you have access over the shadowRoot
      template = document.getElementById('news-template').content.cloneNode(1),
      contextTitle = `Context ${ this.name } !`;

    template.querySelector('.news-context-title').textContent = contextTitle;
    template.querySelector('.news-list').innerHTML = myNews.showNews();
    shadow.append( template );
    
    const list = document.querySelector('.news-list');
    const list_1 = shadow.querySelector('.news-list');
    const list_2 = this.shadowRoot.querySelector('.news-list');
    
    console.log("document.querySelector('.news-list') :", list_1)
    console.log("shadow.querySelector('.news-list') :", list_2);
    console.log("this.shadowRoot.querySelector('.news-list') :", list_3);
    
  }
 
}

customElements.define( 'news-ticker', NewsTicker );
代码语言:javascript
复制
<news-ticker 
     name="News DE" 
     region="de" 
     limit="2">
</news-ticker>
<template id="news-template">
  <style>
    h2 {
      text-align: center;
      font-weight: normal;
      padding: 0.5em;
      margin: 1px 0;
      background-color: black;
      color: white;
      border: 1px solid #666;
      font-weight: bold;
    }
    
    .news-list > p {
      font-weight: normal;
      border: 1px solid #787878; 
      padding: 0.3em; 
      border-radius: 5px; 
      margin: 0.2em; 
      text-transform: capitalize; 
      text-align: left;
    }
    
    .news-list p:hover { 
      cursor: pointer; 
      background-color: #ffffd0; 
    }
  </style>

  <h2 class="news-context-title"></h2>
  <div class="news-list"></div>
</template>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72561487

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档