Upgrade to Pro — share decks privately, control downloads, hide ads and more …

謎のDOMアクセス / Mysterious DOM access

謎のDOMアクセス / Mysterious DOM access

Kanazawa.rb #96 で発表した資料です。 #kzrb

参考資料

- javascript - Do DOM tree elements with ids become global variables? - Stack Overflow (https://stackoverflow.com/questions/3434278/do-dom-tree-elements-with-ids-become-global-variables)
- Window - Web API | MDN (https://developer.mozilla.org/ja/docs/Web/API/Window)
- HTML Standard (https://html.spec.whatwg.org/multipage/window-object.html)
- サンプルコード (https://codepen.io/takayukiatkwsk/pen/abNvgmE)

TAKAyukiatkwsk

August 15, 2020
Tweet

More Decks by TAKAyukiatkwsk

Other Decks in Programming

Transcript

  1. 謎のDOMアクセス
    / Mysterious DOM access
    Kanazawa.rb meetup #96
    Takayuki Takagi

    View Slide

  2. Who am I?
    ● Takayuki Takagi (高木貴之 / ニボシーニョ)
    ● @TAKAyuki_atkwsk / takayukiatkwsk
    ● Freelance programmer
    ● Working from home
    ● Scala, Ruby, Python, AWS, Docker, etc.
    ● Like beer and gyoza

    View Slide

  3. 突然ですがこんなことがあった
    某案件で HTML と JavaScript を触っていたとき...
    (※: ソースコードはサンプルです)

    View Slide

  4. View Slide

  5. クリックすると
    上の文章とセレクト
    ボックスが消える

    View Slide

  6. View Slide

  7. View Slide

  8. エラーの原因
    ● unrecognized expression: #[object HTMLDivElement]
    ○ jQuery() メソッドに渡したセレクター文字列が有効ではない
    ○ hideElementById() 内では $(`#${id}`) としている
    ○ id を文字列化した結果 [object HTMLDivElement] となっている
    ○ id パラメーターに渡しているのは......?
    ■ onClick="hideElementById(inner)"
    ○ 本来は要素を指す id 文字列を渡してほしいが、意図せずクォーテーション
    マークが抜けている
    ■ id 文字列が渡ってくると展開後に $(‘#inner’) となって上手くいく

    View Slide

  9. エラーの原因から疑問
    ● onClick="hideElementById(inner)"
    ○ inner そのものが何かを参照している???
    ■ 定義されていない変数だとすると onClick の評価で RefferenceError が発生する
    ■ グローバルスコープ
    ■ (再掲) 文字列化すると [object HTMLDivElement] になるもの
    ■ DOM を扱う Element オブジェクトと推測される
    ○ inner はどこで定義されているのか?

    View Slide

  10. 答え: window
    ● window[name] で name の指す要素・要素のコレクション
    を返す
    ○ すなわち Element オブジェクト・このコレクションを返す
    ○ name には id属性の値, name属性の値(formなど)が該当
    ○ https://html.spec.whatwg.org/multipage/window-object.html#named-
    access-on-the-window-object
    ○ ただし推奨はしていない
    ■ document.getElementById() か document.querySelector() を使う

    View Slide

  11. 答えの続き
    ● window[‘inner’] で要素を取得できる
    ● inner のみでアクセスできたのはなぜ?
    ○ ブラウザでは、window はグローバルオブジェクト
    ○ このプロパティには window. なしでアクセスすることができる

    View Slide

  12. まとめ
    ● ブラウザで動作する JavaScript では HTML の id や name
    属性値のみでこれらの要素にアクセスできる
    ○ が、推奨はされておらず意図的に利用するのは避ける
    ● 改めて調べてみて原理を理解できてよかった!
    ○ 遭遇したときはとりあえず動くように修正したのみだった
    ○ とりあえず動く!ヨシ!は大事なときもある

    View Slide

  13. 参考資料
    ● javascript - Do DOM tree elements with ids become
    global variables? - Stack Overflow
    ● Window - Web API | MDN
    ● HTML Standard
    ● サンプルコード

    View Slide