รับตำแหน่งของแท็ก div / span


103

ใครสามารถแสดงวิธีรับtop& leftตำแหน่งขององค์ประกอบdivหรือspanเมื่อไม่ได้ระบุ?

กล่าวคือ:

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

ในข้างต้นถ้าฉันทำ:

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

ค่าของ55pxจะถูกส่งกลับ อย่างไรก็ตามหากฉันลองใช้span'12a' แล้วจะไม่มีอะไรกลับมา

ฉันมีdiv/ spans มากมายในหน้าที่ฉันไม่สามารถระบุtop/ leftproperties ได้ แต่ฉันต้องการแสดงdivโดยตรงภายใต้องค์ประกอบนั้น

คำตอบ:


100

ฟังก์ชันนี้จะบอกตำแหน่ง x, y ขององค์ประกอบที่สัมพันธ์กับหน้า โดยทั่วไปคุณจะต้องวนซ้ำพ่อแม่ขององค์ประกอบทั้งหมดและบวกค่าชดเชยเข้าด้วยกัน

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};
}

อย่างไรก็ตามหากคุณต้องการแค่ตำแหน่ง x, y ขององค์ประกอบที่สัมพันธ์กับคอนเทนเนอร์สิ่งที่คุณต้องมีคือ:

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

หากต้องการวางองค์ประกอบไว้ด้านล่างโดยตรงคุณจะต้องทราบความสูงด้วย สิ่งนี้ถูกเก็บไว้ในคุณสมบัติ offsetHeight / offsetWidth

var yPositionOfNewElement = el.offsetTop + el.offsetHeight + someMargin;

5
น่าเสียดายที่วิธีนี้ล้มเหลวใน Chrome เมื่อองค์ประกอบอยู่ภายในตารางที่มีเส้นขอบ นอกจากนี้ยังจะล้มเหลวในโหมดมาตรฐาน IE6 เนื่องจากระยะขอบของ BODY
ฟรี

1
เพียงคำเตือนสำหรับผู้ใช้รหัสนี้ สิ่งนี้สัมพันธ์กับหน้าไม่ใช่หน้าต่าง จะคืนค่าเดียวกันหากผู้ใช้เลื่อนไปรอบ ๆ โดยใช้แถบเลื่อน ระวัง.
Isaac Bolinger

ขอบคุณ @IsaacBolinger เพิ่งสังเกตเห็น ใครช่วยบอกหน่อยได้ไหมว่าฉันจะเปลี่ยนค่าได้อย่างไรเมื่อหน้าต่างถูกปรับขนาดหรือผู้ใช้เลื่อน
David Fariña

@ DavidFariñaฉันใช้โมดูลเรขาคณิต "dom-geometry" ของ dojo สำหรับสิ่งนั้น ไม่รู้จะทำยังไงดี
Isaac Bolinger

Downvoted - อาจเห็นได้ชัดสำหรับผู้ใช้ที่มีประสบการณ์มากกว่า แต่คุณยังไม่ได้ระบุสิ่งที่ต้องส่งผ่านสำหรับ el (เช่นโปรดระบุตัวอย่างการใช้งาน)
Matt

185

คุณสามารถเรียกใช้เมธอดgetBoundingClientRect()โดยอ้างอิงถึงองค์ประกอบ จากนั้นคุณสามารถตรวจสอบtop, left, rightและ / หรือbottomคุณสมบัติ ...

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

หากใช้ jQuery คุณสามารถใช้รหัสที่รวบรัดกว่านี้ ...

var offsets = $('#11a').offset();
var top = offsets.top;
var left = offsets.left;

11
+1 สำหรับคำตอบนี้getBoundingClientRect()ควรใช้ - และนี่ควรเป็นคำตอบที่ยอมรับ! แต่คุณไม่จำเป็นต้องมี"เบราว์เซอร์ที่ทันสมัย"สำหรับการทำงาน, ดูรายการความเข้ากันได้ผมก็จะแสดงที่นี่: stackoverflow.com/questions/1480133/... ทำงานได้ดีใน IE 4.0+ (!), Chrome 1.0+, FF 3.0+, Safari 4.0+ และ Opera
Sk8erPeter

25
โปรดทราบว่าgetBoundingClientRect()ส่งคืนค่าที่สัมพันธ์กับวิวพอร์ตไม่ใช่เอกสาร top = el.getBoundingClientRect().top + window.pageYOffset - el.ownerDocument.documentElement.clientTopเพื่อที่คุณจะต้องการสิ่งที่ต้องการ
Zack Bloom

1
นอกจากนี้ทราบว่าgetBoundingClientRectจะใช้เวลาtransformเข้าบัญชี
ExpExc

สิ่งนี้ไม่ถูกต้องหากลูกคนแรกที่ไม่อยู่ในตำแหน่งที่แน่นอนมีระยะขอบบนหรือด้านซ้าย ขณะนี้ยังไม่มีวิธีแก้ไขที่ถูกต้องในหน้านี้ดังนั้นหากใครทราบโปรดโพสต์คำตอบ
Curtis

16

ในขณะที่คำตอบของ @ nickf ใช้งานได้ หากคุณไม่สนใจเบราว์เซอร์รุ่นเก่าคุณสามารถใช้ Javascript เวอร์ชันบริสุทธิ์นี้ได้ ทำงานใน IE9 + และอื่น ๆ

var rect = el.getBoundingClientRect();

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

12

ดังที่ Alex กล่าวไว้คุณสามารถใช้ jQuery offset () เพื่อรับตำแหน่งที่สัมพันธ์กับโฟลว์เอกสาร ใช้ตำแหน่ง () สำหรับพิกัด x, y ที่สัมพันธ์กับพาเรนต์

แก้ไข: Switched document.readyสำหรับwindow.loadเพราะloadรอให้ทุกองค์ประกอบเพื่อให้คุณได้รับขนาดของพวกเขาแทนที่จะเตรียม DOM จากประสบการณ์ของฉันloadส่งผลให้องค์ประกอบตำแหน่ง Javascript ที่ไม่ถูกต้องน้อยลง

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

9

สำหรับใครก็ตามที่ต้องการเพียงแค่ตำแหน่งบนหรือซ้ายการปรับเปลี่ยนโค้ดที่อ่านได้ของ @ Nickf เล็กน้อยจะเป็นเคล็ดลับ

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

และ

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

2

ฉันรู้ว่านี่เป็นกระทู้เก่า แต่คำตอบของ @alex ต้องทำเครื่องหมายว่าเป็นคำตอบที่ถูกต้อง

element.getBoundingClientRect() เป็นการจับคู่กับ jQuery ทุกประการ $(element).offset()

และเข้ากันได้กับ IE4 + ... https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect


คุณจะต้องรวมค่าชดเชยการเลื่อนหน้า
Benjamin Intal
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.