Dapatkan posisi tag div / span

103

Dapatkah seseorang menunjukkan kepada saya cara mendapatkan posisi top& leftdari elemen divatau spanjika tidak ditentukan?

yaitu:

<span id='11a' style='top:55px;' onmouseover="GetPos(this);">stuff</span>
<span id='12a' onmouseover="GetPos(this);">stuff</span>

Di atas, jika saya melakukannya:

document.getElementById('11a').style.top

Nilai 55pxdikembalikan. Namun, jika saya mencobanya untuk span'12a', maka tidak ada yang dikembalikan.

Saya memiliki banyak div/ spans pada halaman yang tidak dapat saya tentukantop / leftproperties-nya, tetapi saya perlu menampilkan divlangsung di bawah elemen itu.

schmoopy
sumber

Jawaban:

100

Fungsi ini akan memberi tahu Anda posisi x, y elemen relatif terhadap halaman. Pada dasarnya Anda harus melakukan loop melalui semua orang tua elemen dan menambahkan offset mereka bersama-sama.

function getPos(el) {
    // yay readability
    for (var lx=0, ly=0;
         el != null;
         lx += el.offsetLeft, ly += el.offsetTop, el = el.offsetParent);
    return {x: lx,y: ly};
}

Namun, jika Anda hanya menginginkan posisi x, y dari elemen relatif terhadap wadahnya, maka yang Anda butuhkan hanyalah:

var x = el.offsetLeft, y = el.offsetTop;

Untuk meletakkan sebuah elemen tepat di bawah yang ini, Anda juga perlu mengetahui tingginya. Ini disimpan di properti offsetHeight / offsetWidth.

var yPositionOfNewElement = el.offsetTop + el.offsetHeight + someMargin;
nickf
sumber
5
Sayangnya metode ini gagal di Chrome ketika elemen berada di dalam tabel dengan batas. Ini juga akan gagal dalam mode standar IE6 karena margin BODY.
Dapatkan Gratis
1
Hanya peringatan bagi pengguna kode ini. Ini relatif terhadap halaman dan bukan jendela. Ini mengembalikan nilai yang sama jika pengguna menggulir menggunakan scrollbar. Hati-hati.
Isaac Bolinger
terima kasih @IsaacBolinger baru saja menyadarinya. Dapatkah seseorang memberi tahu saya bagaimana saya mengubahnya untuk mengubah nilai ketika jendela diubah ukurannya atau pengguna menggulir?
David Fariña
@ DavidFariña Saya menggunakan modul geometri "dom-geometri" dari dojo untuk itu. Saya tidak tahu bagaimana melakukannya secara asli.
Isaac Bolinger
Suara negatif - Ini mungkin terlihat jelas bagi pengguna yang lebih berpengalaman, tetapi Anda belum menentukan apa sebenarnya yang perlu diteruskan untuk el (yaitu, berikan contoh penggunaan).
Matt
184

Anda dapat memanggil metode getBoundingClientRect()dengan referensi ke elemen. Kemudian Anda dapat memeriksa top, left, rightdan / atau bottomproperti ...

var offsets = document.getElementById('11a').getBoundingClientRect();
var top = offsets.top;
var left = offsets.left;

Jika menggunakan jQuery, Anda dapat menggunakan kode yang lebih ringkas ...

var offsets = $('#11a').offset();
var top = offsets.top;
var left = offsets.left;
alex
sumber
11
1 untuk jawaban ini, getBoundingClientRect()harus digunakan - dan ini harus menjadi jawaban yang diterima! Tetapi Anda tidak memerlukan "browser modern" agar ini berfungsi, lihat daftar kompatibilitas yang saya tunjukkan di sini: stackoverflow.com/questions/1480133/… . Ini berfungsi dengan baik di IE 4.0+ (!), Chrome 1.0+, FF 3.0+, Safari 4.0+ dan Opera.
Sk8erPeter
25
Perhatikan bahwa getBoundingClientRect()mengembalikan nilai relatif terhadap viewport, bukan dokumen. Untuk itu, Anda menginginkan sesuatu seperti top = el.getBoundingClientRect().top + window.pageYOffset - el.ownerDocument.documentElement.clientTop.
Zack Bloom
1
Juga mencatat bahwa getBoundingClientRectmengambil transformke rekening.
ExpExc
Ini tidak akurat jika turunan non-absolut pertama memiliki margin-top atau margin-left. Saat ini tidak ada solusi yang akurat di halaman ini jadi jika ada yang tahu, silakan kirim jawaban.
Curtis
16

Sementara jawaban @ nickf berhasil. Jika Anda tidak peduli dengan browser lama, Anda dapat menggunakan versi Javascript murni ini. Bekerja di IE9 +, dan lainnya

var rect = el.getBoundingClientRect();

var position = {
  top: rect.top + window.pageYOffset,
  left: rect.left + window.pageXOffset
};
Benjamin Intal
sumber
12

Seperti yang dicatat Alex, Anda dapat menggunakan jQuery offset () untuk mendapatkan posisi relatif terhadap aliran dokumen. Gunakan posisi () untuk koordinat x, y relatif terhadap induk.

EDIT: Switched document.readyuntuk window.loadkarena loadmenunggu semua elemen sehingga Anda mendapatkan ukuran bukan hanya mempersiapkan DOM. Dalam pengalaman saya, loadmenghasilkan lebih sedikit elemen posisi Javascript yang salah.

$(window).load(function(){ 
  // Log the position with jQuery
  var position = $('#myDivInQuestion').position();
  console.log('X: ' + position.left + ", Y: " + position.top );
});
Dylan Valade
sumber
9

Bagi siapa pun yang hanya membutuhkan posisi atas atau kiri, sedikit modifikasi pada kode @ Nickf yang dapat dibaca dapat membantu.

function getTopPos(el) {
    for (var topPos = 0;
        el != null;
        topPos += el.offsetTop, el = el.offsetParent);
    return topPos;
}

dan

function getLeftPos(el) {
    for (var leftPos = 0;
        el != null;
        leftPos += el.offsetLeft, el = el.offsetParent);
    return leftPos;
}
Jens Frandsen
sumber
2

Saya menyadari ini adalah utas lama, tetapi jawaban @alex perlu ditandai sebagai jawaban yang benar

element.getBoundingClientRect() sama persis dengan jQuery $(element).offset()

Dan itu kompatibel dengan IE4 + ... https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect

lukeed
sumber
Anda harus menyertakan offset gulir halaman
Benjamin Intal