• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

problem z obiektem globalnym typu DATE

Object Storage Arubacloud
+3 głosów
382 wizyt
pytanie zadane 22 stycznia 2022 w JavaScript przez orion170190 Nowicjusz (150 p.)

Witam wszystkich, jestem tu nowy i uczę się programowania od kilku miesięcy. Jestem na etapie JavaScriptu. Mam problem z obiektem DATE. Stworzyłem poniższą funkcję żeby na stronie o odpowiedniej godzinie wyświetlał się odpowiedni komunikat:

 

const main = () => {
    showWelcome();
};

const showWelcome = () => {
    const textWelcome = document.querySelector('.text-hour');
    const today = new Date();
    const hourNow = today.getHours();
    let greeting;

    if (hourNow > 18) {
        greeting = 'Dobry wieczór!';
    } else if (hourNow > 12) {
        greeting = 'Dzień dobry!';
    } else if (hourNow > 0) {
        greeting = 'Dzień dobry!';
    } else {
        greeting = 'Witam!';
    }
    
    textWelcome.textContent = greeting;
};

document.addEventListener('load', main);

Problem polega na tym że w podanym divie o klasie text-hour nie wyświetla się żądany komunikat tylko pustka jakby funkcja nie istniała. Wszystko działa tylko wtedy gdy nie umieszczę skryptu w funkcji tylko w zasięgu globalnym w ten sposób:

const textWelcome = document.querySelector('.text-hour');
    const today = new Date();
    const hourNow = today.getHours();
    let greeting;

    if (hourNow > 18) {
        greeting = 'Dobry wieczór!';
    } else if (hourNow > 12) {
        greeting = 'Dzień dobry!';
    } else if (hourNow > 0) {
        greeting = 'Dzień dobry!';
    } else {
        greeting = 'Witam!';
    }

    textWelcome.textContent = greeting;

Jednak uważam to za mało profesjonalne, gdyż według mnie każdy skrypt powinien być opisany w funkcji no chyba, że się mylę więc proszę o sprostowanie.

Teraz pytanie czy praca z obiektem DATE jest możliwa tylko w zasięgu globalnym czy można w jakiś sposób umieszczać z nim skrypty w funkcjach i wywoływać wedle je według własnych wymagań? A może coś robię nie tak? Prosiłbym serdecznie o pomoc i wyrozumiałość. Pozdrawiam :)

OSTATNIA LINIJKA TO NASŁUCHIWACZ KTÓRY MA ODPALAĆ FUNKCJE DOPIERO PO ZAŁADOWANIU STRONY.

3 odpowiedzi

0 głosów
odpowiedź 22 stycznia 2022 przez qax Dyskutant (8,060 p.)
edycja 22 stycznia 2022 przez qax

Problem polega na tym, iż próbujesz zmienić zawartość diva w momencie gdy strona jeszcze się ładuje i nie ma do niego dostępu. Aby wywołać funkcję po prostu wypisz jej nazwę wraz z nawiasami na końcu, czyli showWelcome().

Przykładowe rozwiązanie:

<div class="text-hour"></div>
const showWelcome = () => {
    const textWelcome = document.querySelector('.text-hour');
    const today = new Date();
    const hourNow = today.getHours();
    let greeting;
 
    if (hourNow > 18) {
        greeting = 'Dobry wieczór!';
    } else if (hourNow > 12) {
        greeting = 'Dzień dobry!';
    } else if (hourNow > 0) {
        greeting = 'Dzień dobry!';
    } else {
        greeting = 'Witam!';
    }
     
    textWelcome.innerText = greeting;
};
 
showWelcome();

Poza tym metoda .textContent JSFiddlu nie działa - zmieniłem ją na .innerText.

komentarz 22 stycznia 2022 przez orion170190 Nowicjusz (150 p.)
Dzięki za pomoc :) To co udostępniłeś też działa, ale poradziłem sobie jeszcze w inny sposób. Moje rozwiązanie umieszczam w komentarzu pod postem kolegi który wspomniał o bezużytecznej funkcji main ;)
komentarz 23 stycznia 2022 przez VBService Ekspert (254,440 p.)

Poza tym metoda .textContent JSFiddlu nie działa - zmieniłem ją na .innerText.

@qax, no jak .textContent nie działa wink

1
komentarz 23 stycznia 2022 przez qax Dyskutant (8,060 p.)

Heh to pewnie jakąś literówkę popełniłem laugh (sorry za wprowadzenie w błąd )

0 głosów
odpowiedź 22 stycznia 2022 przez Us Użytkownik (880 p.)

Cześć, 

ja też się uczę js i mam pytanie, po co tam dałeś to: 

const main = () => {
    showWelcome();
};

Wydaje mi się to bezużyteczne.

1
komentarz 22 stycznia 2022 przez orion170190 Nowicjusz (150 p.)

Ta funkcja miała wywoływać inne funkcję po załadowaniu strony. Do tego na samym dole stworzyłem nasłuchiwcz na zdarzenie load przypisane funkcji main. Ale masz rację to było bezużyteczne i poradziłem już sobie w inny sposób, a mianowicie:

window.onload = () => {
    showWelcome();
};

const showWelcome = () => {
    const textWelcome = document.querySelector('.text-hour');
    const today = new Date();
    const hourNow = today.getHours();
    let greeting;

    if (hourNow > 18) {
        greeting = 'Dobry wieczór!';
    } else if (hourNow > 12) {
        greeting = 'Dzień dobry!';
    } else if (hourNow > 0) {
        greeting = 'Dzień dobry!';
    } else {
        greeting = 'Witam!';
    }

    textWelcome.textContent = greeting;
};  

 

i teraz działa wszystko bez zarzutu :)

0 głosów
odpowiedź 22 stycznia 2022 przez VBService Ekspert (254,440 p.)
edycja 22 stycznia 2022 przez VBService

Moim zdaniem problem jest z 

document.addEventListener('load', main);

 

zamień na

document.addEventListener('DOMContentLoaded', main);

lub

window.addEventListener('load', main);

 

window.onload vs document.onload

 

const main = (eventName) => {
    showWelcome(eventName);
};
 
const showWelcome = (eventName) => {
    const textWelcome = document.querySelector('.text-hour');
    const today = new Date();
    const hourNow = today.getHours();
    let greeting;
 
    if (hourNow > 18) {
        greeting = 'Dobry wieczór!';
    } else if (hourNow > 12) {
        greeting = 'Dzień dobry!';
    } else if (hourNow > 0) {
        greeting = 'Dzień dobry!';
    } else {
        greeting = 'Witam!';
    }
     
    textWelcome.innerHTML += `${greeting} ${eventName}<br />`;
};
 
window.addEventListener('load', () => { main('window - load'); });
document.addEventListener('DOMContentLoaded', () => { main('document - DOMContentLoaded'); });
window.addEventListener('DOMContentLoaded', () => { main('window - DOMContentLoaded'); });
document.addEventListener('load', () => { main('document - load'); });

 

komentarz 23 stycznia 2022 przez qax Dyskutant (8,060 p.)

VBService, czyżbym się mylił w swojej odpowiedzi? Nie jestem specem od JS-a, bo wciąż się uczę, więc podałem najprostsze rozwiązanie... cheeky

komentarz 23 stycznia 2022 przez VBService Ekspert (254,440 p.)
edycja 23 stycznia 2022 przez VBService

@qax, Kod jest w porządku, tylko napisany w ten sposób musi znajdować się na "końcu" kodu html.

komentarz 23 stycznia 2022 przez VBService Ekspert (254,440 p.)
edycja 23 stycznia 2022 przez VBService

@qax, 

czyżbym się mylił w swojej odpowiedzi?

sprawdź laugh

<!DOCTYPE html>
<html>
    <head>

        <script>
            const showMe = (message, event_name) => {
              const div = document.querySelector('.show-me');
              div.innerHTML += message + ' - <b>' + event_name + '</b> - ' + (new Date().getTime()) + '<br />';
            };
  
           try {
             // w try ponieważ ta linia wywoła błąd i poniższy kod się nie wykona
             showMe('Before html', 'call function');
           } catch(err) { }

           window.addEventListener('load', () => { showMe('Before html', 'window.load'); });
           window.addEventListener('DOMContentLoaded', () => { showMe('Before html', 'window.DOMContentLoaded'); });
        </script>
    </head>
    <body>
        <div class="show-me"></div>

        <script>
           showMe('After html', 'call function');
           window.addEventListener('load', () => { showMe('After html', 'window.load'); });
           window.addEventListener('DOMContentLoaded', () => { showMe('After html', 'window.DOMContentLoaded'); });
        </script>
    </body>
</html>

 

1
komentarz 23 stycznia 2022 przez qax Dyskutant (8,060 p.)

Dzięki za tak precyzyjnie wytłumaczenie. Szczerze mówiąc nad takimi rzeczami nigdy się nie zastanawiałem bo nie miałem jakiś poważnych z tym problemów. :p

Kiedyś z tej książki https://helion.pl/ksiazki/javascript-i-jquery-interaktywne-strony-www-dla-kazdego-podrecznik-front-end-developera-jon-duckett,jsqwdv.htm#format/d tyle się dowiedziałem, żeby skrypty JS załączać przed znacznikiem zamykającym <body> ale widzę że są też alternatywne rozwiązania.

 

1
komentarz 24 stycznia 2022 przez orion170190 Nowicjusz (150 p.)

@VBService, Zdarzenie DOMContentLoad odpowiada tylko za wczytanie się całego DOMu, a ja użyłem load bo chciałem żeby strona uruchamiała się prawidłowo z animacjami po załadowaniu całej strony łącznie z CSS i grafikami. Dodatkowo teraz pracuję nad skryptem, który będzie wyświetlał animację podczas ładowania ;). Ale zwróciłeś mi uwagę na bardzo ważną rzecz, mój wcześniejszy kod działa kiedy nasłuchiwacz jest podpięty pod window a nie document i w tym też tkwił problem dlatego również dzięki za pomoc ;)

komentarz 24 stycznia 2022 przez VBService Ekspert (254,440 p.)

@qax,  @orion170190, 

[ UPDATE ]

<!DOCTYPE html>
<html>
    <head>
 
        <script>
            const showMe = (message, event_name) => {
              const div = document.querySelector('.show-me');
              div.innerHTML += message + ' - <b>' + event_name + '</b> - ' + (new Date().getTime()) + '<br />';
            };
   
           try {
             // w try ponieważ ta linia wywoła błąd i poniższy kod się nie wykona
             showMe('Before html', 'call function');
           } catch(err) { }
 
           window.addEventListener('load', () => { showMe('Before html', 'window.load'); });
           window.addEventListener('DOMContentLoaded', () => { showMe('Before html', 'window.DOMContentLoaded'); });
          
           document.body.onload = () => { showMe('Before html', 'document.body.onload'); }
        </script>
    </head>
    <body>
        <div class="show-me"></div>
 
        <script>
           showMe('After html', 'call function');
           window.addEventListener('load', () => { showMe('After html', 'window.load'); });
           window.addEventListener('DOMContentLoaded', () => { showMe('After html', 'window.DOMContentLoaded'); });
           
           // gdy usuniemy komentarz "nadpisze" 'Before html' document.body.onload 
           //document.body.onload = () => { showMe('After html', 'document.body.onload'); }
        </script>
    </body>
</html>

 

Podobne pytania

0 głosów
1 odpowiedź 203 wizyt
pytanie zadane 12 lutego 2020 w PHP przez juske00 Początkujący (370 p.)
0 głosów
3 odpowiedzi 580 wizyt
pytanie zadane 30 kwietnia 2019 w C i C++ przez seba Dyskutant (8,900 p.)
0 głosów
0 odpowiedzi 286 wizyt
pytanie zadane 25 marca 2019 w PHP przez Grzegorz Mikina Dyskutant (8,060 p.)

92,624 zapytań

141,482 odpowiedzi

319,822 komentarzy

62,005 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...