jQuery .offset() returns undefined value
You are returning the same value in each iteration. the cached this
object doesn't refer to your section
collection's elements, it refers to the window
object. Use $(this)
instead of the obj
in the map
's callback.
Related videos on Youtube
Marian
I'm actually into permaculture and auto sustainability in rural areas. Still doing some coding here and there for fun and work but really looking into other things. Jade and SASS are awesome, try it! I'm a fan of ditching jQuery for vanilla JavaScript and am looking into ES6/7 and ReactJS right now.
Updated on June 04, 2022Comments
-
Marian almost 2 years
I built this very basic .map() function with jQuery to store the top offsets of my HTML sections in an array (inside script tag at the very end of the body):
jQuery
$(window).load(function() { var obj = $(this), sec = $('section'), arr = sec.map(function() { return obj.offset().top }).get(); })
It's almost as simple as in the jQuery documentation. And it already worked! ... Until like a week ago.
My HTML (jade [compiled with CodeKit]) has a very simple structure either:HTML
body.preload section#id1 whateverContent section#id2 moreContent section#id3 evenMoreContent ...
Surprisingly today the console decided to tell me that top is undefined:
Console
Uncaught TypeError: Cannot read property 'top' of undefined
Supposedly in my function .map() takes all section tags and returns the offset of each iterated element just as stated in the documentation:
Within the callback function, this refers to the current DOM element for each iteration.
Not even to mention again that this has already worked rock solid for me about a week ago.So what's the issue here?
Is there a typo? Is something in between messing around? I got more variables defined there, but it shouldn't make any difference, should it? Could it have to do something with compiling jade? With CodeKit? Any clues are highly appreciated!
This is my uncensored, complete JS on the page (worked a week ago):
// Let DOM finish loading $(window).load(function() { // CSS animation hack $('body').removeClass('preload') // Sticky nav and active class var win = $(window), doc = $(document), obj = $(this), sec = $('section'), nav = $('nav'), anc = $('nav a'), pos = nav.offset().top, // Fill array with top offsets from sections arr = sec.map(function() { return obj.offset().top }).get(), act = function() { win.scrollTop() > pos ? nav.addClass('sticky') : nav.removeClass('sticky'), $.each(arr, function(i, val) { (win.scrollTop() > val && win.scrollTop() < (val + sec.eq(i).outerHeight(true) + 1) ) ? anc.eq(i).addClass('active') : anc.eq(i).removeClass('active') }) }; // Execute sticky function win.scroll(act)
-
Ram over 9 yearsYou are returning the same value in each iteration. the cached
this
object doesn't refer to yoursection
elements, it refers to thewindow
object. Use$(this)
instead of theobj
in themap
s callback.
-