QA@IT

【初心者】Javascriptで画像をうろうろランダムに動かしたいのですが、開始位置が真ん中になりません。

6360 PV

UFOという名前の画像を用意して、ボタンをクリックすれば上下左右にランダムに画像が動く
というコードを書いたんですが、開始位置が左端からになってしまい、左上だけをうろうろしてしまいます。
どうすれば真ん中のまま始まるのでしょうか?

<!DOCTYPE html>
<html lang="ja">
<head>
<title>Nice</title>
<meta http-equiv="content-script-type" content="text/javascript">
<meta http-equiv="content-type" content="text/html"; charset="utf-8">
<style type="text/css">
    #pic{
        position: absolute;
        top: 200px;
        left: 300px;
        right: 300px;
        bottom: 200px;
    }
</style>
<script type="text/javascript">
function move(){
    var get, rand, x, timer;
    get = document.getElementById("pic");
    x = Math.floor(Math.random() * 10);
    rand = Math.random();
    if(rand < 0.25){
        get.style.top = x + "px";
    }else if(rand < 0.50){
        get.style.bottom = x + "px";
    }else if(rand < 0.75){
        get.style.left = x + "px";
    }else{
        get.style.right = x + "px";
    }
    timer = setTimeout("move()", 100);
}
</script>
</head>
<body>
<script type="text/javascript">
</script>
<div id="pic">
<img src="UFO.jpg" width="400px" height="300px"/>
</div>
<form>
<input type="button" value="スタート" onclick="move()">
</form>
</body>
</html>

回答

こんにちは。こうですかね。

function move(){
    var get, rand, x, timer;
    get = document.getElementById("pic");
    x = Math.floor(Math.random() * 10);
    rand = Math.random();
    if(rand < 0.25){
        get.style.top = get.offsetTop + x + "px";
    }else if(rand < 0.50){
        get.style.top = get.offsetTop - x + "px";
    }else if(rand < 0.75){
        get.style.left = get.offsetLeft + x + "px";
    }else{
        get.style.left = get.offsetLeft - x + "px";
    }
    timer = setTimeout("move()", 100);
}
編集 履歴 (0)
  • 回答ありがとうございます。
    コードを修正すると、果てしなくページが広がってしまいます...
    どう対処したらいいのでしょうか?
    確かにoffsetなら現在の位置を取得するはずなのに.
    -
  • こんにちは。果てしなくページが広がるの意味がわかりませんでした。そこを少し明確にしていただくことはできますか? -
  • こんばんは。一般的にサイトが下に長い・横に長いとサイドバーがでます。
    そのサイドバーがボタンを押すと出現してどんどん小さくなってしまいます(ページが拡大しています)
    説明不足ですいません(;^^)
    -
  • 失敗の原因が判明しました(汗
    ```get.style.left = get.offsetLeft + x + "px";```を(x + "px")と勝手に括弧でくくって記述していたことが原因でした...
    迅速で的確な回答、ありがとうございました<(_ _)>
    -

例えば、サイズが 800 x 800 の body 要素の中で、サイズが 400 x 300 の div 要素を、初期画面では top: 200px; left: 300px; の位置に表示し、[スタート]ボタンクリックで、body 要素の中で Math.random() を使ってランダムに動かす場合ですと、以下のようにすればできるはずです。

<html>
<head>
    <title>Nice</title>
    <style type="text/css">
        #pic{
            position: absolute;
            top: 200px;
            left: 300px;
            width: 400px;
            height: 300px;
            border: 2px solid black;
        }

        body {
            width: 800px;
            height: 800px;
            border: 1px solid blue;
        }
    </style>
    <script type="text/javascript">
        function move() {
            var get = document.getElementById("pic");
            var x = Math.floor(Math.random() * (document.body.clientWidth - get.clientWidth));
            var y = Math.floor(Math.random() * (document.body.clientHeight - get.clientHeight));
            get.style.top = y + "px";
            get.style.left = x + "px";
            timer = setTimeout("move()", 100);
        }
    </script>
</head>
<body>
    <div id="pic">
    </div>
    <form>    
        <input type="button" value="スタート" onclick="move()" />    
    </form>
</body>
</html>

上記で質問者さんの目的に適わない場合は、どこが問題かを書いていただければ、別の案を考えて見ます。

編集 履歴 (0)
  • ありがとうございます!動きました!
    どうして下の方の回答ではうまく動かないのでしょうか?
    get.offsetTopで現在の場所を取得して、それに少しのランダムなピクセルを差し引きする。
    こちらでも動きそうですが・・・
    -
  • ごめんなさい、下の方の回答でもうまくうごきました・・・
    なるほどこんな書き方もあるのですね、参考になります。
    (document.body.clientWidth - get.clientWidth)は
    (800 - 400)と同じでいつも戻り値は400になる、ということで正しいでしょうか?
    -
  • 400 としないで (document.body.clientWidth - get.clientWidth) としたのは、css での設定値を変えても JavaScript のコードを変えなくて済むようにするためです。要するにハードコーディング(意味が分からなければググってください)を避けるためです。height の方も同様。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。