LoginSignup
12
0

More than 5 years have passed since last update.

AttributeとPropertyの怪奇現象

Last updated at Posted at 2018-12-07

こんにちは。新卒で入社後、新規事業への配属を経て、8月からUniposのWeb開発チームに所属しているシンバです。Web開発の世界に入門しながらElmを書いてます。

これまでGolangとAndroidをやっていることが多かった自分が、Web開発に入門して出会った謎を追った話をまとめました。(Elmコードがちょこっと話に出ますが本筋には関係ないです)

この記事を3行で

  • Webの世界には、一口に属性といってもAttributePropertyがある
  • 例えばmuted属性について、propertyとして付けるのとsetAttribute()を使うのとでは挙動が違う
  • Chromeでvideoタグをつかった動画の自動再生がうまくいかなかったら、muted属性をpropertyとして付けることを検討してみてください

本題

怪奇現象に出会った

先日、画面に自動再生動画を仕込むタスクを担当しました。

videoタグを使い実装することになったのですが、GoogleChromeでは自動再生される条件として、autoplay属性に付随してmuted属性もついていなければならないとのことでした。(この他にも条件はありますが割愛)

OKつけよう、とはいったもののElm(elm/html1.0.0)にはautoplay属性をつけるautoplay関数はあっても、同じようにmuted属性をつけるものが存在しません。代わりにattribute関数があります。これで任意の属性をつけられます。

Main.elm
view : () -> Html ()
view _ =
    video [ autoplay True, attribute "muted" "true", src "./video.mp4", width 640, height 360 ] []

ですがどうしたことか、全く自動再生されないわけです。

スクリーンショット 2018-12-06 22.44.45.png

devToolsからDOMを見るとautoplaymuted="true"もついているのに...。

困ってドキュメントをあさっていると、同じように属性をつけるproperty関数を発見しました。

Main.elm
view : () -> Html ()
view _ =
    video [ autoplay True, property "muted" (Encode.bool True), src "./video.mp4", width 640, height 360 ] []

先ほどattribute "muted" "true"としていた部分をproperty "muted" (Json.Encode.bool True)に置き換えると、見事自動再生されました!

スクリーンショット 2018-12-06 22.48.19.png

mutedがついていないのに...。

AttributeとProperty

調べていると、一口に属性といっても、AttributePropertyの2つが存在するとわかりました。

ではAttributeとPropertyはどんな関係なのかと調べてわかったのは、

  • HTMLからDOMが生成されるとき、Attributeを元にDOMオブジェクトのPropertyが生成される
  • idtypeなど、AttributeとPropertyの変更が相互に同期されるものもあれば、そうでないものもある
  • mutedは初期化に使われるものであり、DOM生成後にAttributeを変更してもPropertyは変更されない

先ほどはDOMのAttributeのみを確認していたので、Propertyも確認してみると発見がありそうです。

DOMはPropertyの値で動く

検証です。冒頭のコードを実行したときのpropertyをdevToolsで見てみたところ、

attribute関数を使用 property関数を使用
propertyのmuted false true

こんな結果になっていました。おお、propertyのmutedに沿って動いていると言えそうです。

また、HTMLとjsで冒頭のコードと同じように振る舞うコードを用意して、違いを見てみました。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<video id="videoMuted" autoplay muted src="./video.mp4" width="640" height="360"></video>
<video id="videoMutedSetAttr" autoplay src="./video.mp4" width="640" height="360"></video>
<video id="videoMutedProp" autoplay src="./video.mp4" width="640" height="360"></video>

<script>
  videoMutedSetAttr.setAttribute('muted', true);
  videoMutedProp.muted = true;
</script>
</body>
</html>

Chromeで動かした結果はこのとおりでした。

videoのid 自動再生されたか propertyのmuted attributeのmuted
videoMuted true ついている
videoMutedSetAttr false ついている
videoMutedProp true ついていない

スクリーンショット 2018-12-06 22.52.49.png

たしかに、DOMはPropertyの値を元に挙動が決定されているようですね!

DOMツリーとAttributeを見ているだけでは分からなかったわけです。

おわりに

Elmでの開発中に出会ったAttributeとPropertyの違いについて追いかけてみました。Media系はコンポーネント・ライブラリが充実しているためか事例が少なく、なかなか調べるのが難しかったです。
あれこれ試行錯誤して全く見当違いなものも追いかけましたが、歴史の長い、進化の多い分野は調べているだけでも楽しいですね〜〜〜

参考

12
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
0