amp-script で button タグの属性の変更が HTML に反映されない
button タグ以外は反映される
知らなかったのでメモ。amp-script で <button>
の属性の変更が HTML に反映されない話です。
例えば、こんなボタンを作り…。
<button type="button">classを変更</button>
クリックする度に、<button>
の class に changed
の追加と削除を繰り返すとします。
const button = document.getElementsByTagName('button')[0];
button.addEventListener('click', () => {
button.classList.toggle('changed');
});
これが動きません。<button>
の class に changed
が追加されません。
ただ、コンソールに Element.attributes
で取得した <button>
の属性の一覧を出力したところ、そちらでは class の追加と削除ができています。
一方、ボタンを <div>
で作った場合は、正常に class の追加と削除が HTML に反映されます。
AMP Playground で <button>
と <div>
で作ったボタンの デモ を用意しました。クリックする度に class の追加と削除を繰り返し、その class を使って背景色を変えるようにしています。<button>
で作ったボタンは背景色が変わりませんが、<div>
で作ったボタンは背景色が変わります。
試した限り class だけではなく、その他の属性も HTML に反映されません。そのため、amp-script を使って <button>
の aria-*
を変更するのは注意すべきかもしれません。私が初めて気が付いたのは、aria-expanded
の変更が HTML に反映されなかった時です。また、変更した属性を使い CSS を指定する時も注意が必要だと思います。
ただ、変更されないのは HTML 上の属性です。属性自体は変更できており、かつ変更した属性は取得し使えます。
例えば、このような HTML を書きます。
<button type="button">テキストを変更</button>
<p>ボタンの現在の class は?</p>
そして、JavaScript は、このように書いてみます。
const button = document.getElementsByTagName('button')[0];
const paragraph = document.getElementsByTagName('p')[0];
button.addEventListener('click', () => {
button.classList.toggle('changed');
const buttonClass = button.className === '' ? '空' : button.className;
paragraph.textContent = buttonClass;
});
そうすれば、クリックする度に変わる <button>
の class を element.className
で取得し、テキストに反映できます。実際の動作は デモ でご覧いただけます。
なお、AMP 特有のアクション toggleClass や amp-bind を使えば、<button>
の class の変更が可能です。また、amp-bind であれば、class 以外の属性も変更できます。
WorkerDOM compatibility は要注意
amp-script は、WorkerDOM の仕様に沿う必要があります。WorkerDOM で使用できる DOM API は、WorkerDOM compatibility で確認できます。
WorkerDOM compatibility の現在の一覧では、HTMLElement.style
は使用不可になっています。
ですが、使えました。このような HTML を書きます。
<div style="background-color: aquamarine;">
<button type="button">色を変更</button>
</div>
そして、<button>
のクリックで <div>
の背景色をピンクに変更してみます。
const button = document.getElementsByTagName('button')[0];
const div = document.getElementsByTagName('div')[0];
button.addEventListener('click', () => {
div.style.backgroundColor = 'pink';
});
エラーは出ず、正常に背景色を変更できます。実際の デモ を用意しました。
WorkerDOM compatibility は鵜呑みにせず、1 度は試してみるのがいいかもしれません。