2013-09-23 2 views
1

У меня есть приложение Rails. Существует мнение, содержащее:JQuery offset возвращает undefined

<nav class="navigation" id="navigation"> 
    <ul> 
    <li><a href="#info">Info</a></li> 
    <li><a href="#address">Address</a></li> 
    <li><a href="#menu">Menu</a></li> 
    <li><a href="#">Website</a></li> 
    </ul> 
</nav> 

custom.js файл в моем приложении/активах/JavaScript папки, содержащий:

var mediaTop = $('div#navigation').offset(); 
var media = $('div#navigation'); 
console.log(mediaTop); 

$(document).scroll(function() { 
    var scrollTop = $(document).scrollTop(); 


    //fix/unfix as necessary 
    if (mediaTop < scrollTop) { 
     $(media).addClass('fixed'); 
    } 
    else { 
     $(media).removeClass('fixed'); 
    } 
}); 

Консоль линии распечатка не определена, однако. Код jQuery должен блокировать навигационную панель в верхней части страницы, когда я прокручиваю вниз, а верхний край попадает в верхнюю часть страницы.

ответ

2

The console line is printing out undefined, however.

Я считаю, что удивительно. Я не знаю ситуации, когда offset возвращает undefined. null, да, но не undefined.

две основные вещи:

Во-первых, если console.log линия показывает null, это потому, что #navigation элемент еще не существует. Убедитесь, что ваш код не работает до после. Элемент существует, перемещая ваш скрипт под элементом в HTML или используя jQuery ready.

Возможно undefined используется в некоторых случаях, когда спрятанный элемент, так как документация говорит

jQuery does not support getting the offset coordinates of hidden elements or accounting for borders, margins, or padding set on the body element.

While it is possible to get the coordinates of elements with visibility:hidden set, display:none is excluded from the rendering tree and thus has a position that is undefined.

(Но в моих экспериментах, я до сих пор получил позицию даже с display: none, а не получать undefined.)

Во-вторых, offset возвращает объект с двумя объектами: left и top. Вы хотите top.

Кроме того, нет необходимости искать элемент дважды. Просто измените порядок своих первых двух утверждений.

Принимая все вместе:

// Make sure this is run *after* the element exists, and make sure it's not hidden 
var media = $('div#navigation'); 
var mediaTop = media.offset().top; 

Вы спросили ниже, как использовать ready с внешним файлом сценария: Вы просто кладете вызов в ready обратного вызова, например:

$(document).ready(function() { 
    // Your code here 
}); 

или ярлык

$(function() { 
    // Your code here 
}); 

Но вам нужно только это сделать, если вы не контролируете, где идет ваш тег script (например,, вы пишете библиотеку или что-то в этом роде). Если вы сделать контроль это, просто поместите script тега at the end of the document, как раз перед закрывающими </body> тегом:

<!-- ...page content... --> 
<script src="myfile.js"></script> 
</body> 
</html> 
+0

Я думаю, что готовый ответ. Как я могу использовать его в отдельном файле jQuery? – delisdeli

+0

@delisdeli: Обычно нет необходимости использовать 'ready', если вы не контролируете местоположение вашего тега' script' (например, записываете плагины или библиотеки). Просто поместите тег 'script' в самую нижнюю часть страницы, непосредственно перед закрывающим элементом' '. Однако, если вы хотите использовать 'ready', просто вызовите свой код из« готового »обратного вызова:' $ (document) .ready (function() {/ * ... ваш код здесь ... * /}); 'или используйте ярлык:' $ (function() {/ * ... ваш код здесь ... * /}); ' –

-1

Заменить

var mediaTop = $('div#navigation').offset(); 

с

var mediaTop = $('div#navigation').offset().top; 

Official Document

+0

Хотя OP * действительно * хочет 'top' (не' Top'), если линия показывает 'undefined', это не главная проблема. –

+0

ну, так как смещение возвращает undefined в этом случае вызов .top, который дает мне следующую ошибку: «Uncaught TypeError: Невозможно прочитать свойство« Топ »неопределенного». Также не должно быть верхняя строчка? – delisdeli

+0

@delisdeli его 'top' не' Top' я отредактировал ответ .. –