I am using the following jQuery code to find the position of the active link on my top menu navigation:
$(document).ready(){
// Handles the triangle image sprite for the top navigation
$('#topnav a')
.on({
mouseenter: function() {
var pos = $("#topnav a.active-top").offset();
console.log("Top: " + pos.top + " Left: " + pos.left );
// Get the position of the current hovered "a" element
var upSprite = $("#upArrow").show(),
pos = $(this).offset(),
aWidth = $(this).width(),
offsetTop = 27, // Adjust this to raise or lower the sprite
offsetLeft = aWidth / 2; // Centers the element under the link
upSprite
.css({
"top": pos.top + offsetTop,
"left": pos.left + offsetLeft
});
//console.log("Top: " + pos.top + " Left: " + pos.left);
},
mouseleave: function() {
// Hide the arrow once the mouse leaves
$('#upArrow').hide();
}
});
}
Now when I paste the exact same code outside of this event handler
$(document).ready(function () {
var pos = $("#topnav a.active-top").offset();
console.log("Top: " + pos.top + " Left: " + pos.left );
}
I get a complete different value for my pos.left.
As I understand .offset() should give me the position relative the document and unlike .position() which gives me the position relative to the parent container.
Is the code being fed a different type of context when it’s in the scope of the .on() event handler? I have tried using $.proxy() to no avail. Any tips are appreciated. Thanks.
$(document).ready()fires once the DOM has loaded; but before all images have loaded. You’ll find the offset is being changed after you’re retrieving theoffset()by the repainting of the elements due to this.To fix this you can handle the
$(window).load()event instead, or continue to retrieve the position inside the click handler (which is what I’d recommend).