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):
$(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:
body.preload
section#id1
whateverContent
section#id2
moreContent
section#id3
evenMoreContent
...
Surprisingly today the console decided to tell me that top is undefined:
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.
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)
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.