af2111: Ausgabe wird zu oft getätigt

Hallo,

ich möchte eine Seite machen, die dir anhand der Temperatur vorschlägt, was man anziehen soll wenn man rausgeht. Dafür benutze ich eine Api von OpenWeather. Mein Problem ist, dass die Ausgabe nicht nur einmal, sondern pro Abfrage einmal geschrieben werden. Ein Screenshot zur Verdeutlichung des Problems Deshalb wollte ich fragen, ob sich jemand mit der API auskennt und mir helfen kann. Hier ist der Code:

<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>Weather Application</title>
  
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

  
      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>
  

  <div class="container">
  <header class="header">
    <div class="search">
      <input type="text" placeholder="Enter City Name" id="search-txt">
      <a id="search-btn" href="#"><i class="fas fa-search"></i></a>
    </div>
  </header>

  <main id="main">
    
    <div class="city-icon">
      <div class="city-icon-holder">
      <div id="city-name"></div>
      <img src="" alt="" id="icon">
        </div>
    </div>
    
    <div class="temperature">
      <div id="temp"></div>
    </div>
    
    <div class="humidity">
      <div id="humidity-div"></div>
    </div>
    
    <div id="output">
        <div id = "out"></div>
      </div>

    </div>
    
  </main>
  
</div>
  <script src='https://use.fontawesome.com/releases/v5.0.13/js/all.js'></script>

  

    <script  src="js/index.js"></script>



</body>

</html>
const appKey = "*****";

let searchButton = document.getElementById("search-btn");
let searchInput = document.getElementById("search-txt");
let cityName = document.getElementById("city-name");
let icon = document.getElementById("icon");
let temperature = document.getElementById("temp");
let humidity = document.getElementById("humidity-div");
let output = document.getElementById("out");
let outputHolder = document.getElementById("output");



searchButton.addEventListener("click", findWeatherDetails);
searchInput.addEventListener("keyup", enterPressed);

function enterPressed(event) {
  if (event.key === "Enter") {
    
    findWeatherDetails();
   
  }
}

function findWeatherDetails() {
  if (searchInput.value === "") {
  
  }else {
    let searchLink = "https://api.openweathermap.org/data/2.5/weather?q=" + searchInput.value + "&appid="+appKey;
   httpRequestAsync(searchLink, theResponse);
  }
 }

function theResponse(response) {
  let jsonObject = JSON.parse(response);
  cityName.innerHTML = jsonObject.name;
  icon.src = "http://openweathermap.org/img/w/" + jsonObject.weather[0].icon + ".png";
  temperature.innerHTML = parseInt(jsonObject.main.temp - 273) + "°";
  humidity.innerHTML = jsonObject.main.humidity + "%";
  var celcius = Math.round(parseFloat(jsonObject.main.temp)-273.15);
  console.log (celcius)
  
  if (celcius <= 23) {
      document.body.style.backgroundColor = '#8181F7';
      document.body.style.color = "#d6f286";
      
      jQuery("div#out").prepend("<p id=\"outputPara\">Zieh dir eine Jacke an!</p>");
      
  
      
      
     
      
     


     }
    else if (celcius >= 24)
    {
      document.body.style.backgroundColor = '#FFBF00';
      document.body.style.color = "#00d8ff";
      jQuery("div#out").prepend("<p id=\"outputPara\">Zieh dir ein kurzärmliges T-Shirt an!</p>");

     
      
     
     
    }  
    }
   function httpRequestAsync(url, callback)
  {
    console.log(temperature);
      var httpRequest = new XMLHttpRequest();
      httpRequest.onreadystatechange = () => { 
          if (httpRequest.readyState == 4 && httpRequest.status == 200)
              callback(httpRequest.responseText);
      }
      httpRequest.open("GET", url, true); // true for asynchronous 
      httpRequest.send();
  }
  1. Hallo af2111,

    das liegt nicht an der API, sondern an Dir. Computer tun nie, was sie sollen. Immer nur das, was man ihnen sagt. Und deiner tut das, was Du ihm gesagt hast: prepend. Häng vor das, was schon da ist, vorne was an.

    Was Du möchtest, ist: Schmeiß weg was da ist und nimm was neues. Du könntest prepend durch html ersetzen:

    jQuery("div#out").html("<p id=\"outputPara\">Zieh dir eine Jacke an!</p>");
    

    Aber: tu's nicht. Du hast das div mit id=out bereits in einer Variablen stehen. Das kannst Du viel einfacher verwenden:

    output.innerHTML = "<p id=\"outputPara\">Zieh dir eine Jacke an!</p>"
    

    Wobei man sich fragen sollte, ob diese divitis nötig ist (eine gefährliche und ansteckende Krankeit!), aber ich kenne dein style.css nicht und weiß nicht, was Du da alles tust. Wenn Du immer ein <p> Element einsetzt, dann sollte dein div#out bereits ein p#out sein und du setzt nur den textContent. Falls Du den Inhalt mit Markup versehen willst, setzt Du innerHTML.

    Die Funktion httpRequestAsync kannst Du Dir übrigens schenken. Nimm $.getJSON von jQuery, der erledigt auch gleich den JSON.parse mit. Oder nimm fetch, dann kannst Du jQuery ganz rausschmeißen.

    Fiddle mit Beispiel für $.getJSON und fetch. Deinen API-Key habe ich darin durch *** ersetzt, den solltest Du nicht rumposten.

    Das hier:

    if (celcius <= 23) {
    }
    else if (celcius >= 24) {
    }
    

    ist übrigens auch nur nötig, wenn Du mehr als 2 Stufen baust. Bei nur 2 Stufen reicht statt des else if einfach nur ein else. Der zweite if ist konzeptionell falsch, weil Du damit eine Lücke in der Logik hat: Was ist mit Temperaturwerten zwischen 23 und 24? Ich weiß schon, du rundest und bist hier sicher, aber wenn ein einfacher else reicht, macht man keine neue Bedingung. Und wenn, dann trennscharf mit celsius > 23. Jede Lücke ist eine zuviel.

    Rolf

    --
    sumpsi - posui - clusi
  2. Danke für die Antwort, das hat das Problem gelöst. Zur Divitis: Die hat schon ihren Grund, der aktuelle Code ist nochmal da.

    <!DOCTYPE html>
    <html lang="en" >
    
    <head>
      <meta charset="UTF-8">
      <title>Weather Application</title>
      
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    
      
          <link rel="stylesheet" href="css/style.css">
    
      
    </head>
    
    <body>
      
    
      <div class="container">
      <header class="header">
        <div class="search">
          <input type="text" placeholder="Enter City Name" id="search-txt">
          <a id="search-btn" href="#"><i class="fas fa-search"></i></a>
        </div>
      </header>
    
      <main id="main">
        
        <div class="city-icon">
          <div class="city-icon-holder">
          <div id="city-name"></div>
          <img src="" alt="" id="icon">
            </div>
        </div>
        
        <div class="temperature">
          <div id="temp"></div>
        </div>
        
        <div class="humidity">
          <div id="humidity-div"></div>
        </div>
        <div id="WeatherDesc">
          <p id="WeatherDescOut"></p>
        </div>
    
        <div id="output">
            <p id = "out"></p>
          </div>
    
        </div>
        
      </main>
      
    </div>
      <script src='https://use.fontawesome.com/releases/v5.0.13/js/all.js'></script>
    
      
    
        <script  src="js/index.js"></script>
    
    
    
    </body>
    
    </html>
    
    const appKey = "*********";
    
    let searchButton = document.getElementById("search-btn");
    let searchInput = document.getElementById("search-txt");
    let cityName = document.getElementById("city-name");
    let icon = document.getElementById("icon");
    let temperature = document.getElementById("temp");
    let humidity = document.getElementById("humidity-div");
    let weatherDesc = document.getElementById("WeatherDesc");
    let weatherDescOut = document.getElementById("WeatherDescOut");
    let output = document.getElementById("out");
    let outputHolder = document.getElementById("output");
    
    
    
    searchButton.addEventListener("click", findWeatherDetails);
    searchInput.addEventListener("keyup", enterPressed);
    
    function enterPressed(event) {
      if (event.key === "Enter") {
        
        findWeatherDetails();
       
      }
    }
    
    function findWeatherDetails() {
      if (searchInput.value === "") {
      
      } else {
        let searchLink = "https://api.openweathermap.org/data/2.5/weather?q=" + searchInput.value + "&appid="+appKey;
       httpRequestAsync(searchLink, theResponse);
      }
     }
    
    function theResponse(response) {
      let jsonObject = JSON.parse(response);
      cityName.innerHTML = jsonObject.name;
      icon.src = "http://openweathermap.org/img/w/" + jsonObject.weather[0].icon + ".png";
      temperature.innerHTML = parseInt(jsonObject.main.temp - 273) + "°";
      console.log(jsonObject.weather[0].description);
      humidity.innerHTML = jsonObject.main.humidity + "%";
      var celcius = Math.round(parseFloat(jsonObject.main.temp)-273.15);
      console.log (celcius);
      
      if (celcius < 16) {
        document.body.style.backgroundColor = '#8181F7';
        document.body.style.color = "#d6f286";
        
        output.innerText = "Zieh dir eine dicke Jacke an!";
        
    
        
        
       
        
       
    
    
       }
      else if (celcius < 23 && celcius > 16) {
          document.body.style.backgroundColor = '#8181F7';
          document.body.style.color = "#d6f286";
          
          output.innerText = "Zieh dir ein langärmliges T-Shirt an!";
          
      
          
          
         
          
         
    
    
         }
        else if (celcius > 23)
        {
          document.body.style.backgroundColor = '#FFBF00';
          document.body.style.color = "#00d8ff";
         output.innerText = "Zieh dir ein kurzärmliges T-Shirt an!";
    
         
          
         
         
        }  
        if(jsonObject.weather[0].description == "clear sky") {
          weatherDescOut.innerText = "Klarer Himmel";
        }
        else if(jsonObject.weather[0].description == "scattered clouds") {
          weatherDescOut.innerText = "Vereinzelt Wolken";
    
        }
        }
       function httpRequestAsync(url, callback)
      {
        console.log(temperature);
          var httpRequest = new XMLHttpRequest();
          httpRequest.onreadystatechange = () => { 
              if (httpRequest.readyState == 4 && httpRequest.status == 200)
                  callback(httpRequest.responseText);
          }
          httpRequest.open("GET", url, true); // true for asynchronous 
          httpRequest.send();
      }
    
    body{
      background-color: #eee;
    }
    
    
    .container{
      width: 500px;
      height: 300px;
      margin:25vh auto;
      border-radius: 25px;
      box-shadow: 0 20px 40px 0px rgba(0,0,0,0.3)
    }
    
    .header {
      height: 20%;
      background-color: #FF9800;
      border-top-left-radius: 25px;
      border-top-right-radius: 25px;
      text-align: center;
      position: relative;
      margin-bottom: 90px;
    }
    
    #output {
            color: white;
            background-color: rgb(0, 236, 59);
            border-bottom-right-radius: 25px;
            border-bottom-left-radius: 25px;
            text-align: center;
            height: 200px;
            width: 500px;
            position:absolute;
            font-size: 40px;
            font-weight: bold;
            font-family: "Courier New";
    }
    
    #WeatherDesc {
      color: white;
      background-color: rgba(109, 214, 255, 0.979);
      text-align: center;
      height: 90px;
      width: 500px;
      position:absolute;
      bottom: 250px;
      font-size: 40px;
      font-weight: bold;
      font-family: "Courier New";
    }
    #WeatherDescOut {
      
    }
    
    #temp, #humidity-div {
      font-family: "Courier New";
      font-weight: bold;
      font-size: 60px;
      color: #fff;
      position: absolute;
      left: 50%;
      top: 50%;
      -webkit-transform: translate(-50%, -50%);
              transform: translate(-50%, -50%);
    }
    
    .city-icon-holder {
      position:absolute;
      left: 25%;
      top: 40%;
      -webkit-transform: translate(-50%, -50%);
              transform: translate(-50%, -50%);
      text-align: center;
    }
    
    #city-name {
      font-family: "Courier New";
      font-size: 30px;
      font-weight: bold;
      color: #fff;
    }
    
    #icon {
      width:50%;
    }
    
    #main{
      width: 500px;
      height: 250px;
      position: absolute;
    }
    
    .city-icon {
      height: 80%;
      width: 50%;
      
      background-color: #FFC107;
    }
    
    .temperature {
      position: absolute;
      left: 50%;
      top:0%;
      height: 40%;
      width: 50%;
      background-color: #9C27B0;
    }
    
    .humidity {
      height: 40%;
      width: 50%;
      position:absolute;
      left:50%;
      top:40%;
      
      background-color: #E91E63;
    }
    
    #search-btn {
      width: 40px;
      height:40px;
      color: #eee;
    }
    
    #search-txt {
      color: red;
      height:30px;
      border-radius: 10px;
      border-style:none;
      outline:none;
      padding-right:1px;
      padding-left:1px;
      text-align:center;
    }
    
    .search {
      position: absolute;
      left: 50%;
      top: 50%;
      -webkit-transform:translate(-50%,-50%);
              transform:translate(-50%,-50%);
    }
    

    Tschö, af2111

    1. Hallo af2111,

      Zur Divitis: Die hat schon ihren Grund,

      einen Grund vielleicht, eine Berechtigung nicht.

      Bis demnächst
      Matthias

      --
      Pantoffeltierchen haben keine Hobbys.
      ¯\_(ツ)_/¯
    2. Hallo af2111,

      jetzt bin ich selbst schuld, ich hab deinen API-Key rausgelöscht und die Historie entfernen lassen, um den Key zu schützen, und nun kann ich mangels Key nicht testen 😂

      Deine Divitis muss überhaupt nicht sein, und deine absolute Positionierei schon gar nicht. Es gibt heutzutage wesentlich elegantere Wege, um Boxen zu positionieren und Inhalte zu zentrieren.

      In deinem Fall solltest Du display:grid für das Gesamtlayout verwenden. Für horizontales Zentrieren reicht zumeist text-align: center und mit etwas Padding bekommt man die Werte auch vertikal zentriert dargestellt.

      Und dein Input für die Stadt braucht ein Label. Ein Placeholder ist kein Label. Du kannst das Label visuell verstecken, so dass ein sehender Mensch den Placeholder sieht. Aber das Label ist dann für Leute da, die nicht sehen können.

      Beispiel-Fiddle

      Rolf

      --
      sumpsi - posui - clusi
      1. @@Rolf B

        Und dein Input für die Stadt braucht ein Label. Ein Placeholder ist kein Label.

        So ist es.

        Du kannst das Label visuell verstecken, so dass ein sehender Mensch den Placeholder sieht. Aber das Label ist dann für Leute da, die nicht sehen können.

        Nicht die beste Idee. Entweder das Feld braucht eine sichtbare Beschriftung – dann als Label – oder es braucht keine – dann das Label visuell verstecken. Ein Placeholder ist kein Ersatz für Label – auch für Sehende nicht.

           <div class="search">
             <input type="text" placeholder="Enter City Name" id="search-txt">
             <a id="search-btn" href="#"><i class="fas fa-search"></i></a>
           </div>
        

        Außerdem braucht das Formular (warum ist das kein form?) einen Button. Ein Link ist kein Button. href="#" ist ein deutliches Zeichen für den Missbrauch das a-Elements.

        Und der Button braucht natürlich auch eine Beschriftung.

        Das Markup sollte so aussehen:

        <div role="search">
          <form>
            <label for="search-txt">City:</label>
            <input type="search" id="search-txt" name="search-txt">
            <button>search</button>
          </form>
        </div>
        

        Beachte role="search" und type="search"!

        Label und Button können ggfs. visuell versteckt werden.

        Ohne JavaScript wird das Formular abgesendet und kann serverseitig ausgewertet werden.

        LLAP 🖖

        --
        „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
        1. Hallo Gunnar,

          wenn Formularelemente nur als Dialogelemente für Javascripte dienen und keine put/get-Requests auslösen, soll man dann ein form drum rum setzen? Technisch braucht man es ja nicht.

          Gruß
          Jürgen

          1. @@JürgenB

            wenn Formularelemente nur als Dialogelemente für Javascripte dienen und keine put/get-Requests auslösen, soll man dann ein form drum rum setzen?

            Warum sollte die Suche nur mit JavaScript funktionieren?

            Und auch bei Anwendungen, die nur mit JavaScript funktionieren können, dürften Nutzer assistiver Technologien davon profitieren, wenn ein Formular auch als solches angezeigt/angesagt wird.

            Allerdings: in diesem speziellen Fall innerhalb des <div role="search"> vermutlich nicht.

            Aber auch ohne <form> muss das UI-Element zum Auslösen der Interaktion ein <button> sein; kein <a href="#">.

            LLAP 🖖

            --
            „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
            1. Hallo Gunnar,

              Und auch bei Anwendungen, die nur mit JavaScript funktionieren können, dürften Nutzer assistiver Technologien davon profitieren, wenn ein Formular auch als solches angezeigt/angesagt wird.

              d.h. du würdest auch in diesem Fall die Formularelemente in ein form einschließen?

              Gruß
              Jürgen

          2. wenn Formularelemente nur als Dialogelemente für Javascripte dienen und keine put/get-Requests auslösen, soll man dann ein form drum rum setzen? Technisch braucht man es ja nicht.

            Ich mache das meist so. Durch ein Formular hat man automatisch alle Referenzen in der "elements"-collection zum Lesen/Manipulieren der einzelnen Formular-Elemente

            /k

            --
            Stur lächeln und winken, Männer!
        2. Hi,

          <div role="search">
            <form>
              <label for="search-txt">City:</label>
              <input type="search" id="search-txt" name="search-txt">
              <button>search</button>
            </form>
          </div>
          

          Beachte role="search" und type="search"!

          Kann das role="search" nicht ins form? Und das div dann ins /dev/null?

          cu,
          Andreas a/k/a MudGuard

          1. @@MudGuard

            Kann das role="search" nicht ins form?

            Nein, dann hätte das form-Element ja nicht mehr die Rolle „Formular“.

            LLAP 🖖

            --
            „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
            1. Hallo Gunnar Bittersmann,

              Kann das role="search" nicht ins form?

              Nein, dann hätte das form-Element ja nicht mehr die Rolle „Formular“.

              For search facilities, authors SHOULD use the search role and not the generic form role. (https://www.w3.org/WAI/PF/aria/roles#form)

              Bis demnächst
              Matthias

              --
              Pantoffeltierchen haben keine Hobbys.
              ¯\_(ツ)_/¯
              1. @@Matthias Apsel

                Kann das role="search" nicht ins form?

                Nein, dann hätte das form-Element ja nicht mehr die Rolle „Formular“.

                For search facilities, authors SHOULD use the search role and not the generic form role. (https://www.w3.org/WAI/PF/aria/roles#form)

                Ich bilde mir ein, das anders gelesen zu haben, nämlich mit role="search"-Element ums Formular drumrum.

                Ich werde mich jetzt aber nicht auf die Suche nach einer Quelle machen. Es sei denn, nach einer Wasserquelle.

                LLAP 🖖

                --
                „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
    3. @@af2111

      Zur Divitis: Die hat schon ihren Grund

      Bedauerlich.


      <html lang="en" ><title>Weather Application</title><input type="text" placeholder="Enter City Name" id="search-txt">
      
          output.innerText = "Zieh dir eine dicke Jacke an!";
            ⋮
            output.innerText = "Zieh dir ein langärmliges T-Shirt an!";
            ⋮
           output.innerText = "Zieh dir ein kurzärmliges T-Shirt an!";
            ⋮
            weatherDescOut.innerText = "Klarer Himmel";
            ⋮
            weatherDescOut.innerText = "Vereinzelt Wolken";
      

      Ich bin verwirrt. Soll die Anwendung nun englisch oder deutsch sein?

      LLAP 🖖

      --
      „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann