質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.37%

Riot.jsにて、動的にカスタムタグをマウントしたい。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,255

score 13

前提・実現したいこと

Riot.jsにて、動的にカスタムタグをマウントしたい。

発生している問題・エラーメッセージ

カスタムタグのマウント時の初期化で、DOM操作(getElementByIdなど)したものの、アクセスしたい要素にアクセスできず、要素のプロパティ参照時にnullが取得される。

エラーメッセージ
Uncaught TypeError: Cannot read property 'プロパティ名' of null(…)

該当のソースコード

[マウント元]
<my-tag>

    <h3>マウント元タグ</h3>

    <div>
        <button type="button" onclick={ btnClick }>トリガー</button>
        <mount-tag each={ item in items } item={ item }/></div>
    </div>

    <script>
        var items
        var cnt

        /*** 初回マウント時実施  ***/
        this.on('mount', function(){
            this.init()
        })

        /*** 初期化 ***/    
        init(){
            items = []
            cnt = 0
        }

        /*** ボタンクリック時 ***/
        btnClick(e){
            cnt = cnt + 1
            var item = { 'id' : cnt }
            items.push(item)
            riot.compile(function(){
                 riot.mount('mount-tag')
             })
             this.update()
        }
    </script>
</my-tag>

[マウント先]
<mount-tag>

    <h3>マウント先タグ</h3>

    <div id={ opts.item.id } data-target="10">
        取得したいdiv
    </div>

    <script>

        var getDiv

        /*** 初回マウント時実施  ***/
        this.on('mount', function(){
            this.init()
        })

        /*** 初期化 ***/    
        init(){
            getDiv =  document.getElementById(opts.item.id) // getElementByIdで要素にアクセスできず、nullが返される。
            console.log(opts.item) // optsによる値の受け渡しは行われている。
            console.log(getDiv.dataset.target) // ここでエラー

        }

    </script>

</mount-tag>

div each={ item in items } で、itemsにpushされて値が増えるたびに、mount-tagを動的にマウントしたい

試したこと

上記のとおり。
また、これら2つのタグは、index.htmlで読み込み済みであり、コンパイルもしている。

[index.html]
<!DOCTYPE html>
<html>
<head>
(略)
</head>

<body>
    <script type="riot/tag" src="tag/my-tag.html"></script>
    <script type="riot/tag" src="tag/mount-tag.html"></script>
</body>
</html>

[index.js]
init(){
    riot.compile(function() {
        riot.route.base('/BaseURL/')
        riot.route.start(true)
        riot.mount('*')
    })
}

補足情報(言語/FW/ツール等のバージョンなど)

バージョン
riot: 2.6.4

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

解決はしていませんが、HTMLの描画がされる前に、mount処理が走ってしまっているようで、 
setTimeoutで時間を待たせてからDOMにアクセスすることで、本事象を回避できることがあるようです。

setTimeout(function(){ 
    document.getElementById(opts.item.id)) 
}, 1000)

1秒待ってgetElementByIdでアクセスしたら、タグインスタンス
<div id={ opts.item.id } data-target="10"> が取得できました。

riot 3.0.1の知人の端末で試したら、setTimeoutなしで普通にgetElementByIdで
取得できたので、riotのバージョンのせいなのか、マシンスペックの問題なのか環境起因の問題とし、本件はクローズ致します。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る