Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
2
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

Organization

Riot.jsのタグオブジェクトを探す

ページ全体をRiotで作っている場合はあまり問題にならないかもしれませんが、「HTMLの中にRiotタグが散在している」かつ「Riotのマウントと別な箇所でタグを使った処理をしたい」というような状況下では、「あとからページにセットしたRiotタグのオブジェクトを取得したい」という場面が生じてきます。

これは、Riotのデータ構造をたどることで実現可能です。

Riotのデータ構造

グローバルにある状況であればグローバルのriotconst riot = require('riot');としている場合はそのriotを使えますが、riot.util.vdomに、ページへマウントしたタグオブジェクトが配列となって入っています。

そして、タグオブジェクト自体(で、今回のテーマに関係するもの)には、以下のプロパティがあります。

  • tag.root…対応するDOMノード
  • tag.tags[子タグ名]…このタグの中に存在する別のRiotタグ。1個ならタグオブジェクトがそのまま入っていて、複数なら配列となっている。

ということで、riot.util.vdomからtagsを再帰的にたどれば目的のことをできそうです。

実際に書いてみた

get_riot_tag.js

// WeakMapがある場合はキャッシュさせる

let cache = null;
if(window.WeakMap){
  cache = new WeakMap;
}


function getRiotTag(elem, current = riot.util.vdom) {
  if(typeof elem === 'string') {
    // セレクタで回せるように
    elem = document.querySelector(elem);
  }
  if(cache) {
    const cached = cache.get(elem);
    if(cached) return cached;
  }
  let ret = null;
  if(Array.isArray(current)) {
    // 最初のvdom、あるいはtagsが配列だった時
    current.some(item => {
      ret = getRiotTag(elem, item);
      return ret;
    });
  } else {
    // currentがタグの場合
    // キャッシュに入れる
    if(cache) cache.set(current.root, current);
    // 自分自身をチェック
    if(current.root === elem) return current;
    for(const key in current.tags) {
      ret = getRiotTag(elem, current.tags[key]);
      if(ret) return ret;
    }
  }
  return ret;
}

なお、「何度も走査するのを避ける」のと「DOMがなくなればキャッシュも確実に破棄させる」ために、WeakMapでキャッシュさせています。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
2
Help us understand the problem. What are the problem?