こんにちは。新卒で入社後、新規事業への配属を経て、8月からUniposのWeb開発チームに所属しているシンバです。Web開発の世界に入門しながらElmを書いてます。
これまでGolangとAndroidをやっていることが多かった自分が、Web開発に入門して出会った謎を追った話をまとめました。(Elmコードがちょこっと話に出ますが本筋には関係ないです)
この記事を3行で
- Webの世界には、一口に属性といっても
Attribute
とProperty
がある - 例えば
muted
属性について、propertyとして付けるのとsetAttribute()
を使うのとでは挙動が違う - Chromeでvideoタグをつかった動画の自動再生がうまくいかなかったら、
muted
属性をpropertyとして付けることを検討してみてください
本題
怪奇現象に出会った
先日、画面に自動再生動画を仕込むタスクを担当しました。
videoタグを使い実装することになったのですが、GoogleChromeでは自動再生される条件として、autoplay
属性に付随してmuted
属性もついていなければならないとのことでした。(この他にも条件はありますが割愛)
OKつけよう、とはいったもののElm(elm/html1.0.0)にはautoplay
属性をつけるautoplay
関数はあっても、同じようにmuted
属性をつけるものが存在しません。代わりにattribute
関数があります。これで任意の属性をつけられます。
view : () -> Html ()
view _ =
video [ autoplay True, attribute "muted" "true", src "./video.mp4", width 640, height 360 ] []
ですがどうしたことか、全く自動再生されないわけです。
devToolsからDOMを見るとautoplay
もmuted="true"
もついているのに...。
困ってドキュメントをあさっていると、同じように属性をつけるproperty
関数を発見しました。
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)
に置き換えると、見事自動再生されました!
muted
がついていないのに...。
AttributeとProperty
調べていると、一口に属性といっても、Attribute
とProperty
の2つが存在するとわかりました。
ではAttributeとPropertyはどんな関係なのかと調べてわかったのは、
- HTMLからDOMが生成されるとき、
Attribute
を元にDOMオブジェクトのProperty
が生成される -
id
やtype
など、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 | ついていない |
たしかに、DOMはPropertyの値を元に挙動が決定されているようですね!
DOMツリーとAttributeを見ているだけでは分からなかったわけです。
おわりに
Elmでの開発中に出会ったAttributeとPropertyの違いについて追いかけてみました。Media系はコンポーネント・ライブラリが充実しているためか事例が少なく、なかなか調べるのが難しかったです。
あれこれ試行錯誤して全く見当違いなものも追いかけましたが、歴史の長い、進化の多い分野は調べているだけでも楽しいですね〜〜〜
参考