Uncaught TypeError: Nie można odczytać właściwości „top” wartości undefined

95

Przepraszam, jeśli na to pytanie została już udzielona odpowiedź. Próbowałem szukać rozwiązań, ale nie mogłem znaleźć żadnego pasującego do mojego kodu. Wciąż jestem nowy w jQuery.

Mam dwa różne rodzaje lepkich menu dla dwóch różnych stron. Oto kod dla obu.

$(document).ready(function () {
    var contentNav = $('.content-nav').offset().top;
    var stickyNav = function () {
        var scrollTop = $(window).scrollTop();
        if (scrollTop > contentNav) {
            $('.content-nav').addClass('content-nav-sticky');
        } else {;
            $('.content-nav').removeClass('content-nav-sticky')
        }
    };
    stickyNav();
    $(window).scroll(function () {
        stickyNav();
    });
});
$(document).ready(function () {
    var stickyNavTop = $('.nav-map').offset().top;
    // var contentNav = $('.content-nav').offset().top;
    var stickyNav = function () {
        var scrollTop = $(window).scrollTop();
        if (scrollTop > stickyNavTop) {
            $('.nav-map').addClass('sticky');
            // $('.content-nav').addClass('sticky');
        } else {
            $('.nav-map').removeClass('sticky');
            // $('.content-nav').removeClass('sticky')
        }
    };
    stickyNav();
    $(window).scroll(function () {
        stickyNav();
    });
});

Mój problem polega na tym, że kod przyklejonego menu bocznego na dole nie działa, ponieważ druga linia kodu wywołuje var contentNav = $('.content-nav').offset().top;błąd o treści „Uncaught TypeError: Cannot read property 'top' of undefined”. W rzeczywistości żaden inny kod jQuery poniżej tej drugiej linii w ogóle nie działa, dopóki nie zostanie umieszczony nad nią.

Po pewnych badaniach wydaje mi się, że problem polega na tym, że $('.content-nav').offset().topnie można znaleźć określonego selektora, ponieważ znajduje się on na innej stronie. Jeśli tak, nie mogę znaleźć rozwiązania.

edubba
źródło
1
użyj jsbin.com proszę.
Royi Namir
sprawdź w html, czy div jest obecny, czy nie
Bhadra

Odpowiedzi:

146

Sprawdź, czy obiekt jQuery zawiera jakiś element, zanim spróbujesz uzyskać jego przesunięcie:

var nav = $('.content-nav');
if (nav.length) {
  var contentNav = nav.offset().top;
  ...continue to set up the menu
}
Guffa
źródło
2
To działa! Cóż za proste rozwiązanie. Muszę się o wiele więcej nauczyć. Wielkie dzięki.
edubba
tak, to działa również dla mnie. ale jaka jest różnica między var contentNav = $('.content-nav').offset().topkodem a Twoim kodem?
Prashant Tapase
@Prashant: Różnica polega na tym, że kod sprawdza, czy liczba elementów $('.content-nav')znalezionych przez wywołanie jest różna od zera, zanim spróbuje uzyskać pozycję pierwszego znalezionego elementu.
Guffa
1
stackoverflow.com/questions/28508939/… Mam tabelę, ale nadal otrzymuję błąd.
SearchForKnowledge
@Guffa dzięki kolego! jednak tylko się zastanawiałem ... Zawsze miałem element, który był tagiem <header>. Czy miałoby to znaczenie, jeśli jest to <div> czy <header>?
Antonio Almeida
17

Twój dokument nie zawiera żadnego elementu z klasą content-nav, dlatego metoda .offset()zwraca wartość undefined, która rzeczywiście nie ma topwłasności.

Możesz się przekonać na tych skrzypcach

alert($('.content-nav').offset());

(zobaczysz „undefined”)

Aby uniknąć awarii całego kodu, możesz zamiast tego mieć taki kod:

var top = ($('.content-nav').offset() || { "top": NaN }).top;
if (isNaN(top)) {
    alert("something is wrong, no top");
} else {
    alert(top);
}

Zaktualizowane skrzypce .

Czarodziej cienia to ucho dla Ciebie
źródło
1
dziękuję za tę odpowiedź mam inny problem, ale działa idealnie
Naved Khan
12

Wiem, że jest to bardzo stare, ale rozumiem, że ten typ błędu jest częstym błędem popełnianym przez początkujących, ponieważ większość początkujących będzie wywoływać swoje funkcje po załadowaniu elementu nagłówka. Ponieważ to rozwiązanie w ogóle nie jest omówione w tym wątku, dodam je. Jest bardzo prawdopodobne, że ta funkcja javascript została umieszczona przed załadowaniem właściwego kodu HTML . Pamiętaj, że jeśli natychmiast wywołasz swój javascript, zanim dokument będzie gotowy, wtedy elementy wymagające elementu z dokumentu mogą znaleźć niezdefiniowaną wartość.

Joseph Casey
źródło
$ (dokument) .ready (funkcja () {...}); uruchamia się po załadowaniu dokumentu i nie ma znaczenia, gdzie znajduje się skrypt. Ale masz tak daleko idącą rację, że każdy skrypt bez tego opakowania może nie działać, gdy zostanie zaznaczony na górze strony.
David
12

Problem, który najprawdopodobniej masz, polega na tym, że gdzieś na stronie znajduje się łącze do nieistniejącej kotwicy. Załóżmy na przykład, że masz:

<a href="#examples">Skip to examples</a>

Na stronie musi znajdować się element o tym identyfikatorze, na przykład:

<div id="examples">Here are the examples</div>

Dlatego upewnij się, że każdy z linków jest dopasowany na stronie do odpowiedniego zakotwiczenia.

drjorgepolanco
źródło
3

Przeszedłem przez podobny problem i stwierdziłem, że próbuję uzyskać przesunięcie stopki, ale ładowałem skrypt wewnątrz elementu div przed stopką. To było coś takiego:

<div> I have some contents </div>
<script>
  $('footer').offset().top;
</script>
<footer>This is footer</footer>

Tak więc problem polegał na tym, że wywoływałem element footer przed załadowaniem stopki.

I pchnął mój skrypt w dół poniżej stopce i to działało w porządku!

MD. Atiqur Rahman
źródło
0

Miałem ten sam problem („Uncaught TypeError: Cannot read property 'top' of undefined”)

Wypróbowałem każde rozwiązanie, jakie mogłem znaleźć i zauważenie pomogło. Ale potem zauważyłem, że mój DIV miał dwa identyfikatory.

Więc usunąłem drugi identyfikator i zadziałało.

Chciałbym tylko, żeby ktoś powiedział mi, żebym wcześniej sprawdził moje dokumenty))

Andrew Losseff
źródło