レッスンに戻る

ボールをフィールドの中央に置きます

重要度:5

ソースドキュメントの外観は以下のとおりです。

フィールドの中心の座標は何ですか?

それらを計算し、緑色のフィールドの中央にボールを配置するために使用します。

  • 要素は、CSSではなくJavaScriptで移動する必要があります。
  • コードは、任意のボールサイズ(`10`、`20`、`30`ピクセル)と任意のフィールドサイズで動作し、与えられた値に縛られるべきではありません。

追伸:確かに、CSSで中央揃えを行うことができますが、ここではJavaScriptを正確に使用したいと考えています。さらに、他のトピックと、JavaScriptを使用する必要があるより複雑な状況に遭遇します。ここでは「ウォーミングアップ」を行います。

タスクのサンドボックスを開きます。

ボールは`position:absolute`を持っています。これは、その`left/top`座標が、最も近い位置決めされた要素、つまり`#field`(`position:relative`を持つため)から測定されることを意味します。

座標は、フィールドの内部左上隅から始まります。

内部フィールドの幅/高さは`clientWidth/clientHeight`です。そのため、フィールドの中心の座標は`(clientWidth/2, clientHeight/2)`です。

…しかし、`ball.style.left/top`をこのような値に設定すると、ボール全体ではなく、ボールの左上端が中心に配置されます。

ball.style.left = Math.round(field.clientWidth / 2) + 'px';
ball.style.top = Math.round(field.clientHeight / 2) + 'px';

外観は以下のとおりです。

ボールの中心をフィールドの中心に合わせるには、ボールを幅の半分だけ左に、高さの半分だけ上に移動する必要があります。

ball.style.left = Math.round(field.clientWidth / 2 - ball.offsetWidth / 2) + 'px';
ball.style.top = Math.round(field.clientHeight / 2 - ball.offsetHeight / 2) + 'px';

これで、ボールは最終的に中央に配置されました。

注意:落とし穴!

`<img>`に幅/高さがないと、コードは信頼性高く動作しません。

<img src="ball.png" id="ball">

ブラウザが画像の幅/高さを(タグ属性またはCSSから)認識しない場合、画像は読み込みが完了するまで`0`と等しいと仮定します。

そのため、`ball.offsetWidth`の値は、画像が読み込まれるまでは`0`になります。これは、上記のコードで座標が間違っている原因となります。

初回読み込み後、ブラウザは通常画像をキャッシュし、再読み込み時にはすぐにサイズが取得されます。しかし、初回読み込み時には`ball.offsetWidth`の値は`0`です。

`<img>`に`width/height`を追加することで、これを修正する必要があります。

<img src="ball.png" width="40" height="40" id="ball">

…またはCSSでサイズを指定します。

#ball {
  width: 40px;
  height: 40px;
}

サンドボックスで解答を開きます。