【jQuery入門】offset()で要素の位置を取得・設定する方法!

こんにちは、ライターのマサトです!

今回は、jQueryで対象要素の位置座標を取得することができる「offset()」メソッドについて学習をしていきいましょう!

この記事では、

  • 「offset()」とは?
  • offset()の使い方
  • 「offset()」「position()」の違い
  • スクロール量をoffset()で取得する方法
  • offset()の注意点

などの基本的な内容から、応用的な使い方に関しても解説していきます。

この記事で、「offset()」メソッドをしっかり学習して自分のスキルアップを目指しましょう!

目次

「offset()」とは?

それでは、まず最初に「offset()」メソッドについて基本的な知識から学習していきましょう!

「offset()」は、画面上(document内)に配置したHTML要素の表示位置を座標で取得できるメソッドになります。

次のような位置座標をイメージすると分かりやすいでしょう!
jquery-offset-img1
このように「offset()」では、対象となるHTML要素の左上を原点としたX・Y座標を取得することができます。

これにより、jQuery側で要素の位置を特定できるので、例えば画面のスクロール量に応じたイベントを実行することも可能です。

本記事では、「offset()」の基本的な使い方から応用技まで解説していきますので、ぜひ参考にしてみてください!

offset()の使い方

この章では、offset()の基本的な使い方と実践例について見ていきましょう!

最も基本となる座標位置の取得方法から、取得した座標の使い方や設定例について学びます。

対象要素の座標位置を取得する方法

まずは、基本的なHTML要素の位置を取得する方法から見ていきましょう!

一般的な記述方法はとても簡単で、【 対象要素.offset() 】のように対象となる要素に対してoffset()を実行するだけです。

例えば、画面に「h1」要素だけが配置されているとして、その位置を取得するには次のように記述します。

const pos = $('h1').offset();

console.log( pos );

実行結果

{ "top":21.4375, "left":8 }

対象要素をセレクタ指定で「$(‘h1’)」とし、続けてoffset()を実行すればOKです!

実行結果を見ると、「top(Y座標)」「left(X座標)」それぞれの位置座標が取得できていますね。

ちなみに、デフォルト状態だと「body要素」「h1要素」それぞれにmarginが設定されています。

そこで、次のように初期化してみましょう!

body {
    margin: 0;
}
h1 {
    margin: 0;
}

この状態でもう一度実行すると、結果は「{ “top”:0, “left”:0 }」となりh1要素が原点に戻ります。

取得した座標「top / left」の使い方

次に、取得した位置座標を利用する方法について見ていきましょう!

先ほども確認したように、取得した値はオブジェクト形式となっています。

「top」と「left」というプロパティに、座標の値が格納されているのでこれを利用しましょう!

const pos = $('h1').offset();

console.log( pos.top );

実行結果

21.4375

この例では、h 要素の位置を取得して「pos.top」のように記述しています。

これにより取得したオブジェクトデータの「top(Y座標)」の値だけを抽出して利用することができます。

任意の位置に座標を設定する方法

今度は、位置座標を取得するのではなく任意の座標位置に設定する方法を確認しましょう!

実は「offset()」の引数に好きな座標位置を記述して設定することができます。

記述方法としては、【 offset( { top: Y座標, left: X座標 } ) 】のようにオブジェクト形式で設定します。

次のサンプル例を見てください!

const pos = $('h1').offset({
    top: 50,
    left: 100
});

この例では、offset()の引数にオブジェクト形式で「top / left」それぞれに座標を設定しています。

このように記述することで、h1要素は設定した位置へ自動的に移動するわけです。

offset()を使った要素の位置を取得・設定する方法は、ペアでよく使われるので忘れないようにしておきましょう!

「offset()」「position()」の違い

「offset()」の類似メソッドとして「position()」があるので合わせてご紹介しておきます!

どちらも対象要素の位置座標を取得するという機能は同じなのですが、取得する「位置」が異なります。

「offset()」はあくまでも画面の端からの位置ですが、「position()」は親要素からの位置になります。

次のイメージ画像を見てください!
jquery-offset-img2
このように「position()」の場合は、h1要素の親にあたる要素の端から計測した位置座標になるというわけです。

実際のコードでも確認をしておきましょう!

HTML

<div>
    <h1>タイトル</h1>
</div>

CSS

div {
    width: 200px;
    height: 100px;
    margin: 100px;
    position: relative;
}

h1 {
    margin:0;
    position: absolute;
    top: 10px;
    left: 10px;
}

この例では、div要素の中にh1要素を配置しています。

CSSの「position」でh1要素の位置を10pxほどズラしているのが分かりますね。

この状態でjQueryから「offset()」と「position()」を使って位置を取得してみましょう!

const pos1 = $('h1').offset();
const pos2 = $('h1').position();

console.log( pos1 );
console.log( pos2 );

実行結果

{"top":110,"left":118}

{"top":10,"left":10}

実行結果に注目してください!

「offset()」「position()」どちらも同じh1要素の位置を取得しているにも関わらず座標が違いますよね?

つまり、「offset()」は画面端からの位置で「position()」はh1要素の親からの位置というわけです。

先ほど10pxずつズラした位置が「position()」でしっかりと取得できていますね。

スクロール量をoffset()で取得する方法

「offset()」の活用事例としてもよく使われる「スクロール量」に応じたイベント処理について見ていきましょう!

画面をスクロールして縦方向にWebページが移動する際に、対象要素が一番上まで来たかどうかを確認してみます。

まずは、次のようなHTML / CSSを用意します。

HTML

<h1>タイトル</h1>

CSS

body {
    height: 500vh;
}
h1 {
    margin-top: 100vh;    
}

h1要素だけを配置し、bodyの高さを「500vh」とすることで5画面分の縦に長いページを作ります。

h1要素はmarginを設定して1画面分下に配置させておきました。

この状態で画面をスクロールして、h1要素が画面の一番上に来たかどうかをチェックするプログラムを作ってみましょう!

const h1 = $('h1').offset().top;

$(window).scroll(function() {
    let scroll = $(this).scrollTop();    
    
    if( scroll >= h1) {
        console.log('h1要素が画面の一番上に来ました!');
    }
})

この例でポイントになるのは、「scroll()」イベントと「scrollTop()」メソッドです。

「scroll()」イベントはスクロールをする度に特定の処理を実行することができます。

また、「scrollTop()」メソッドはスクロール量を計測して取得できるメソッドになります。

これにより、スクロール量を毎回取得しながらh1要素の「offset().top」と比較して一番上に来ているか確認できるわけです。

今回は、h1要素が一番上に到達したらコンソールログにメッセージを出力するようにしています。

offset()の注意点

この章では、offset()を使うにあたり注意するべき点について解説をしていきます!

一般的によくありがちな事例として、取得した値が「undefined」の場合と取得できないケースを学びます。

取得した返り値が「undefined」になる理由

まずは、位置座標が「undefined」になってしまうケースから見ていきましょう!

通常なら「top / left」プロパティに格納されている座標が取得できますが、以下の条件下ではそれができません。

  • 対象要素がHTMLに存在しない場合
  • 対象要素にdocument / windowを指定した場合

上記内容を実際のコードで表すと次のとおりです。

//存在しない要素の場合
$('???').offset();

//document / windowを指定した場合
$('document').offset();
$('window').offset();

この場合は、すべて返り値が「undefined」になるので位置を取得することができなくなります。

特に、jQueryで要素を意図的に追加・削除する場合は、存在しない要素の位置を取得することがあるので注意しましょう!

座標の位置が正しく取得できない理由

次に、「undefined」にはならないものの正しい位置が取得できないケースを見ていきましょう!

最も多いケースとしては、対象となる要素が「非表示」になっている場合です。

例えば、次のようなHTMLとCSSがあるとします。

HTML

<h1>タイトル</h1>

CSS

h1 {
    display: none;
}

この場合は、h1要素がCSSの「display: none」によってあらかじめ非表示になっています。

この状態で位置を取得するとどうなるか見てみましょう!

const result = $('h1').offset();

console.log( result );

実行結果

{"top":0,"left":0}

実行結果に注目して下さい!

「top / left」それぞれの座標が「0」になっているのが分かりますね。

つまり、h1要素が非表示になっているために正しく位置を取得できていないことを意味しているわけです。

対象要素が「非表示」になるケースとしては、jQuery側で意図的に操作している場合もよくあるので注意しましょう!

まとめ

今回は、jQueryで対象要素の位置座標を取得できる「offset()」について学習しました!

最後に、もう一度ポイントをおさらいしておきましょう!

  • offset()は対象要素の位置をオブジェクト形式(top / left)で取得・設定できる
  • offset()は画面端からの位置でposition()は親要素からの位置を取得できる
  • スクロール量を取得したイベント処理でもoffset()は活用できる
  • 存在しない要素や非表示になっている要素は正しく位置を取得できない

上記内容を踏まえて、ぜひ自分でもプログラミングに取り入れて活用できるように頑張りましょう!

この記事を書いた人

フリーランスのIT系ライターを10年従事する兵庫県出身の40歳。侍ブログ編集部としては、これまで270記事以上を執筆。
30歳を過ぎてから独学でJavaScript, Node.js, Linuxを習得した経験を活かし、初心者が迷わない記事作成を意識しながらプログラミングの楽しさを知ってもらうために活動しています。趣味はキャンプと登山です。

目次