Mein erstes Smartphone war ein iPhone 4s. Ich erinnere mich an die Aufregung, seine Fähigkeiten zu erkunden, zu einer Zeit, als es das Coolste war, was es gab. Schließlich, natürlich, habe ich es durch ein neueres Modell ersetzt und das alte iPhone, das immer noch in neuwertigem Zustand war, verstaubte zwei Jahre lang. Was für eine Verschwendung!
Aber war es das? Mir kam die Idee, dass ich das alte iPhone umfunktionieren könnte, um eine nützliche Wetteruhr für unseren Flur zu bauen.

Dabei habe ich entdeckt, dass die Wiederverwendung eines alten Geräts nicht nur Spaß macht und wirtschaftlich ist, sondern auch Ihr Verständnis für Webstandards vertiefen kann. In diesem Tutorial zeige ich Ihnen, wie ich eine kleine Webseite erstellt habe, um Datum, Uhrzeit und aktuelle Wetterbedingungen basierend auf dem aktuellen GPS-Standort anzuzeigen. Gemeinsam werden wir Wetterdaten von einer öffentlichen API abrufen und einen API-Schlüssel zur Sicherheit in einer PHP-Datei verstecken. Schließlich werden wir uns ansehen, wie man eine Manifestdatei und Meta-Tags hinzufügt, damit Benutzer die Seite auf dem Startbildschirm eines Geräts speichern und dann als eigenständige App starten können, einschließlich eines benutzerdefinierten Icons dafür.
Hier ist ein Screenshot von dem, was wir anstreben

Schritt 1: Wie spät ist es?
Siehe den Pen Wall Clock von Steven Estrella (@sgestrella) auf CodePen.
Das HTML für die Uhr enthält etwas Platzhaltertext, den wir später ersetzen werden. Alles, was wir im Moment wirklich brauchen, ist ein zentriertes <main> Container-Element und ein paar semantische <time> Elemente für Datum und Uhrzeit. Das <span> Tag innerhalb des zweiten <time> Elements wird speziell gestylt, um die laufenden Sekunden und den Meridian anzuzeigen. Das datetime Attribut innerhalb der <time> Elemente wird dynamisch mit JavaScript aktualisiert.
<main id="container" class="daymode">
<time id="date" datetime="" class="clocktext">Someday, Anymonth 15, 20XX</time>
<time id="time" datetime="" class="clocktext">12:00<span>:00 PM</span></time>
</main>
Ein wenig responsives Design ist hier der Schlüssel. Wir möchten, dass dies auf dem Bildschirm eines iPhone 4s oder jedes anderen kleinen Smartphones sowohl im Hoch- als auch im Querformat gut aussieht. Wir möchten natürlich auch, dass es in einem Desktop-Webbrowser gut funktioniert. Wir können jedoch keine brandneuen CSS- oder JavaScript-Funktionen verwenden, da ältere Geräte wie mein iPhone 4s diese nicht verstehen.
Ich habe die Dinge noch eine Stufe weiter getrieben, indem ich spezifische Stile für die Tageszeit erstellt habe, und wir werden das auf jeden Fall auch noch behandeln. Wir könnten sogar eine Media Query nutzen, um den Tageslichtstil für Mac-Benutzer zu verdunkeln, die Dark Mode im neuesten MacOS aktiviert haben.
Das <span> Tag mit den laufenden Sekunden und dem Meridian wird basierend auf einer Breite von 2em schön umgebrochen, was gerade groß genug ist, um zwei Großbuchstaben (d.h. AM und PM) unterzubringen. Das endgültige CSS, das benötigt wird, ist eine Media Query, um die Schriftgrößen zu erhöhen, wenn die Uhr im Querformat angezeigt wird, oder wirklich jedes Gerät mit einer Ansichtsbreite von mehr als 480 Pixel.
Hier sind die Basisstile, die wir betrachten, wobei die dekorativeren Stile in der endgültigen App zur Kürze entfernt wurden
/* Base nighttime styles */
.nightmode {
background-color: #121212;
color: #fff;
}
/* Base daytime styles */
.daymode {
background-color: #87ceeb;
color: #333;
}
/* Target MacOS users who have Dark Mode enabled */
@media (prefers-color-scheme: dark) {
.daymode {
background-color: #003;
color: #ffc;
}
}
/* Used to wrap any lines of text */
.clocktext {
display: block;
margin: 0;
padding: 1px 0 0 0;
text-align: center;
white-space: nowrap;
width: 100%;
}
#date {
font-size: 1.3rem;
padding-top: 15px;
}
#time {
font-size: 5rem;
margin: 1px 0 0 0;
}
#time span {
display: inline-block;
font-size: 1.5rem;
line-height: 1.5;
margin: 0 0 0 0.5em;
padding: 0;
text-align: left;
vertical-align: baseline;
white-space: normal;
width: 2em;
}
@media (min-width: 480px){
#date {font-size: 2rem;}
#time {font-size: 8rem;}
#time span {
font-size: 2rem;
line-height: 2;
}
}
Für JavaScript habe ich **ES5 gewählt, da viele Funktionen von ES6 im mobilen Safari-Browser unter iOS 9.35, dem letzten iOS, das auf dem iPhone 4s läuft, nicht funktionieren**. Glücklicherweise ist ES5 mehr als ausreichend und die App läuft auch auf neueren Geräten ordnungsgemäß.
Wir benötigen Variablen für das aktuelle Datum und die aktuelle Uhrzeit (now), das Element, das das Datum anzeigen wird (dd), das Element, das die Uhrzeit anzeigen wird (td) und die Namen der Monate und Tage. Sobald die Seite geladen ist, wird eine Init-Funktion aufgerufen, um die Uhrzeit jede Sekunde (1000 Millisekunden) zu aktualisieren. Die Funktion getClockStrings() aktualisiert den Wert im now Date-Objekt und gibt ein Objekt mit HTML-Strings für Datum und Uhrzeit zurück. Dann aktualisiert die Funktion updateTime() das HTML, um die Uhrzeit anzuzeigen. Eine hier weniger genutzte Funktion ist die Einbeziehung der toISOString() Methode des Date-Objekts, die einen maschinenlesbaren Datumsstring zum datetime Attribut der beiden <time> Elemente hinzufügt.
Hier ist, was das bedeutet, unter Verwendung des JavaScript aus der Demo
// NOTE: ES5 chosen instead of ES6 for compatibility with older mobile devices
var now, dd, td;
var months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
var days = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
document.addEventListener("DOMContentLoaded", init, false);
function init() {
dd = document.getElementById("date");
td = document.getElementById("time");
updateTime();
setInterval(updateTime,1000);
}
function updateTime() {
var clockdata = getClockStrings();
dd.innerHTML = clockdata.datehtml;
td.innerHTML = clockdata.timehtml;
dd.dateTime = now.toISOString();
td.dateTime = now.toISOString();
}
function getClockStrings() {
now = new Date();
var year = now.getFullYear();
var month = months[now.getMonth()];
var date = now.getDate();
var day = days[now.getDay()];
var hour = now.getHours();
var minutes = now.getMinutes();
var seconds = now.getSeconds();
var meridian = hour < 12 ? "AM" : "PM";
var clockhour = hour > 12 ? hour - 12 : hour;
if (hour === 0) {clockhour = 12;}
var clockminutes = minutes < 10 ? "0" + minutes : minutes;
var clockseconds = seconds < 10 ? "0" + seconds : seconds;
var datehtml = day + ", " + month + " " + date + ", " + year;
var timehtml = clockhour + ":" + clockminutes + "<span>:" + clockseconds + " " + meridian + "</span>";
return {"datehtml":datehtml,"timehtml":timehtml};
}
Schritt 2: Wo bist du?
Siehe den Pen Clock with GPS von Steven Estrella (@sgestrella) auf CodePen.
Die Geolocation API ist ein einfacher Weg, um den genauen Standort des Benutzers zu ermitteln. Wir können das tun, wenn die Seite geladen wird, aber gute Manieren und Chromes Best Practices Audit schreiben vor, dass wir den Benutzer bitten, die Standortfunktion zu initiieren. Daher müssen wir einen Button und ein <div> zum HTML hinzufügen, um die GPS-Informationen anzuzeigen, die wir erhalten.
<button id="gpsbutton">Get GPS Location</button>
<div id="gps" class="clocktext infotext"></div>
Diese neuen Elemente erfordern eigene Stile – meine können im obigen eingebetteten Pen eingesehen werden. Wichtig ist, die Klassen-Selektor-Regel für die Klasse infotext sowie die beiden ID-Selektor-Regeln für den gpsbutton hinzuzufügen.
Schließlich müssen wir die modifizierte infotext Klassen-Selektor-Regel innerhalb der Media Query hinzufügen.
Nochmal, die Basisstile abzüglich dekorativer Stile zur Kürze
/* The geolocation coordinates upon clicking GPS button */
.infotext {
font-size: 1.3rem;
line-height: 1.4;
padding: 0 5px 0 5px;
width: auto;
}
/* The button itself */
#gpsbutton {
-webkit-appearance: none;
-moz-appearance: none;
display: block;
margin: 0 auto;
width: auto;
cursor: pointer;
}
#gpsbutton:hover {
/* Styles for the hover state */
}
@media (min-width: 480px){
/* Add the rule below to the end of the media query */
.infotext {font-size: 1.8rem;}
}
Das JavaScript erfordert einige neue Variablen für den Breitengrad, Längengrad, das GPS <div> und die GPS <button>. Wenn der GPS-Button geklickt wird, ruft er die Funktion getLocation() auf, die auf die Verfügbarkeit von Geolocation-Unterstützung im Browser prüft. Wenn er solche Unterstützung findet, ruft er die Methode getCurrentPosition des navigator.geolocation Objekts auf und übergibt eine Referenz auf eine Erfolgs-Callback-Funktion namens showPosition und eine Fehler-Callback-Funktion namens geoError.
An diesem Punkt wird der Browser den Benutzer um Erlaubnis bitten, seinen GPS-Standort zu ermitteln. Wenn der Besucher ablehnt, wird eine entsprechende Nachricht angezeigt. Wenn der Benutzer zustimmt, zeigt die Funktion showPosition() dann den Breitengrad und Längengrad an und blendet den GPS-Button aus.

Hier ist das JavaScript, das wir basierend auf dem, was wir in diesem Abschnitt behandelt haben, erhalten
// ...
var lat, lon, gd, gpsbutton;
// ...
function init(){
// ...
gd = document.getElementById("gps");
gpsbutton = document.getElementById("gpsbutton");
gpsbutton.addEventListener("click",getLocation,false);
// ...
}
function updateTime(){
// ...
var sec = now.getSeconds();
var minutes = now.getMinutes();
if (sec === 0){
if (minutes % 5 === 0){
getLocation(); // Get location every 5 minutes while the app is running
}
}
}
function getClockStrings(){
// ...
}
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition,geoError);
}else{
gd.innerHTML = "location unknown";
}
}
function geoError(){
gd.innerHTML = "location detection disabled";
}
function showPosition(position) {
gpsbutton.style.display = "none";
lat = position.coords.latitude;
lon = position.coords.longitude;
gd.innerHTML = "GPS: " + lat.toFixed(2) + " | " + lon.toFixed(2);
}
Schritt 3: Wie ist das Wetter?
Das Hinzufügen aktueller Wetterbedingungen zu dieser Uhr ist eine nützliche Funktion. Glücklicherweise erlauben die netten Leute von OpenWeatherMap.org den kostenlosen Zugriff auf grundlegende Wetterinformationen. Melden Sie sich dort für ein kostenloses Konto an und Sie erhalten einen API-Schlüssel, den Sie in Ihrer Webentwicklung verwenden können. Das kostenlose Konto bietet aktuelle Bedingungen und 5-Tage-Vorhersagen für jeden gültigen GPS-Standort, den Sie ihm übergeben. Achten Sie nur darauf, die API nicht öfter als 60 Mal pro Minute aufzurufen, sonst werden Sie aufgefordert, ein kostenpflichtiges Konto abzuschließen. Sobald Sie einen API-Schlüssel haben, ersetzen Sie ihn durch die Worte YOUR_API_KEY_HERE in diesem Codebeispiel und fügen Sie den Code dann in die Adressleiste des Browsers ein. Sie erhalten ein JSON-Objekt mit dem Wetter für meinen Standort hier in Pennsylvania. Experimentieren Sie mit verschiedenen Breitengraden und Längengraden. Koordinaten für jede größere Stadt finden Sie unter LatLong.net, wo die Koordinaten im benötigten Dezimalformat angegeben sind.
http://api.openweathermap.org/data/2.5/weather?lat=40.15&lon=-75.21&APPID=YOUR_API_KEY_HERE
Siehe den Pen Clock and Weather von Steven Estrella (@sgestrella) auf CodePen.
Fügen Sie das HTML hinzu
Fügen Sie direkt unter dem GPS <button> Folgendes zum HTML hinzu
<div id="weather" class="clocktext infotext"></div>
<img id="icon" src="https://openweathermap.org/img/w/01n.png" alt="weather icon" />
Fügen Sie das CSS hinzu
Das CSS benötigt Stile für das neue Wetter-<div> und das Icon-Bild. Beachten Sie, dass die Opazität des Icons zunächst auf 0 gesetzt ist. Dies wird im JavaScript-Code geändert, sobald gültige Wetterinformationen abgerufen wurden.
#weather {
display: block;
width: auto;
}
#icon {
display: inline-block;
opacity: 0;
vertical-align: top;
width: 50px;
height: 50px;
}
@media (min-width: 480px){
/* Add the rule below to the end of the media query */
#weather {display: inline-block;}
}
Fügen Sie das JavaScript hinzu
Wir müssen Variablen hinzufügen, um die Wetter-URL, das Wetter-<div> (wd) und das Wetter-Icon zu referenzieren. Wir müssen uns auch zwischen Fahrenheit oder Celsius entscheiden. Der boolesche Wert für usephp sollte vorerst auf false gesetzt werden. Wir werden das Verstecken Ihres API-Schlüssels in einem PHP-Dokument etwas später besprechen. Der boolesche Wert locationRequested wird uns helfen, unnötige Aufrufe der Wetter- und Geolocation-APIs zu vermeiden, bevor der Benutzer sie angefordert hat. Die Variablen für Sonnenuntergangs- und Sonnenaufgangszeit ermöglichen es uns, das Aussehen der Uhr basierend auf der Tageszeit zu ändern. Der Wert iconurl liefert den Stamm der URL, den wir zum Abrufen von Wetter-Icons benötigen. Wir benötigen auch eine Zufallszahl zwischen 0 und 14, die wir in unserer updateTime Funktion verwenden, damit nicht alle unsere Benutzer zur gleichen Minute alle Viertelstunde Wetter abfragen. Wenn Sie eigene Icon-Sets haben, können Sie den URL-Wert für iconurl ändern. Die Dateinamen für die PNG-Icons finden Sie unter OpenWeatherMap.org.
// ...
var weatherurl, wd, icon, weatherminute;
var temperaturescale = "F"; // Set to F or C (fahrenheit or celsius)
var usephp = false; // Set to true to use a PHP document to hide your api key
var locationRequested = false;
var sunsettime = 0;
var sunrisetime = 0;
var iconurl = "https://openweathermap.org/img/w/";
// ...
function init(){
//... Add these lines before the updateTime call at the end of the function
wd = document.getElementById("weather");
icon = document.getElementById("icon");
weatherminute = randRange(0,14);
// ...
}
// Random number utility function
function randRange(min, max) {
return Math.floor(Math.random()*(max-min+1))+min;
}
Als Nächstes modifizieren wir den letzten if-Block der updateTime() Funktion. Wir möchten unnötige Aufrufe der Wetter- und Geolocation-APIs vermeiden, daher ist es wichtig, auf sec === 0 zu prüfen, um sicherzustellen, dass wir weder 60 Mal pro Minute aufrufen. Wir möchten die APIs auch nur dann aufrufen, wenn der Benutzer die Anfrage der Browser-Geolocation genehmigt hat.
function updateTime(){
//...
if (locationRequested && sec === 0){
checkForSunset(); // Checks for sunset once each minute
if (minutes % 15 === weatherminute){
getWeather(); // Get weather every 15 minutes while the app is running
// weatherminute is a random number between 0 and 14 to ensure
// that users don't all hit the API at the same minute
}
if (minutes % 5 === 0){
getLocation(); // Get location every 5 minutes while the app is running
}
}
}
In der Funktion showPosition() ist die URL zum Abrufen der Wetterdaten entweder ein relativer Pfad zur PHP-Datei oder eine vollständige HTTPS-URL, die auf den OpenWeatherMap.org-Dienst verweist. In beiden Fällen übergeben wir den Breitengrad und Längengrad in der Query-String der URL. Für die APPID ersetzen Sie bitte Ihren eigenen API-Schlüssel für die Worte YOUR_API_KEY_HERE, es sei denn, Sie verwenden die PHP-Lösung, die in Schritt 4 unten besprochen wird.
function showPosition(position) {
//...
if (usephp){
weatherurl = "clock.php?lat=" + lat + "&lon=" + lon;
}else{
weatherurl = "https://api.openweathermap.org/data/2.5/weather?";
weatherurl += "lat=" + lat + "&lon=" + lon + "&APPID=";
weatherurl += "YOUR_API_KEY_HERE";
}
if (!locationRequested){
getWeather();
locationRequested = true;
}
}
Die Funktion showPosition() ruft dann getWeather() auf, die das Wetter-<div> aktualisiert, um dem Benutzer mitzuteilen, dass etwas geschieht, während die Wetterdaten abgerufen werden. Ich habe mich für den älteren XMLHttpRequest-Standard entschieden, da fetch auf alten Geräten wie dem iPhone 4s nicht unterstützt wird. Wenn die Anfrage der Wetterdaten über ein PHP-Dokument geleitet wird, ist der Antworttyp "document" und nicht einfacher Text, daher müssen wir dies prüfen. Wenn dies der Fall ist, befindet sich das benötigte JSON-Objekt in der Eigenschaft textContent des Antwortkörpers. Andernfalls benötigen wir nur den einfachen Text in der Eigenschaft responseText. Die Daten werden dann als JSON-Objekt geparst und an die Funktion processWeather() gesendet.
function getWeather() {
wd.innerHTML = "getting weather";
var xhttp = new XMLHttpRequest();
xhttp.responseType = usephp ? "document" : "text";
// The PHP file returns a document rather than plain text
xhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
// When using PHP as a data source we need the `textContent`
// of the body of the returned document
var data = usephp ? xhttp.response.body.textContent : xhttp.responseText;
processWeather(JSON.parse(data));
}
};
xhttp.open("GET", weatherurl, true);
xhttp.send();
}
Das an processWeather() gesendete JSON-Objekt sieht etwa so aus
{"coord":{"lon":-75.21,"lat":40.15},
"weather":[{"id":701,"main":"Mist","description":"mist","icon":"50n"}],
"base":"stations",
"main":{"temp":276.42,"pressure":1011,"humidity":100,"temp_min":275.15,"temp_max":277.15},"visibility":16093,"wind":{"speed":2.1,"deg":310},"clouds":{"all":90},"dt":1545021480,
"sys":{"type":1,"id":4743,"message":0.1513,"country":"US","sunrise":1545049047,"sunset":1545082605},"id":5190089,"name":"Fort Washington","cod":200}
Aus diesen JSON-Daten müssen wir die Eigenschaft weather extrahieren, die die Beschreibung der aktuellen Bedingungen und den Dateinamen für das Wetter-Icon enthält. Das <img> Tag im HTML mit der ID "icon" wird dann mit einem neuen src Attributwert aktualisiert, um das Icon-Bild zu laden. Die Temperatur ist Teil der Eigenschaft main, muss aber in Fahrenheit oder Celsius umgerechnet werden (die meisten Menschen denken nicht in Kelvin). Wenn das geschehen ist, können die aktuellen Bedingungen der Eigenschaft innerHTML des Wetter-<div> zugewiesen werden. Die Zeiten für Sonnenaufgang und Sonnenuntergang befinden sich in der Eigenschaft sys der Daten. Sobald wir diese haben, können wir die Funktion checkForSunset() aufrufen und den Stil an die Tageszeit anpassen.
function processWeather(data){
var weather = data["weather"][0];
icon.src = iconurl + weather.icon + ".png";
icon.style.opacity = 1;
var localtemperature = convertTemperature(data["main"].temp).toFixed(0);
var weatherstring = localtemperature + "°" + temperaturescale + " " + weather.description;
wd.innerHTML = weatherstring;
sunsettime = Number(data["sys"].sunset);
sunrisetime = Number(data["sys"].sunrise);
checkForSunset();
}
function checkForSunset(){
var nowtime = now.getTime()/1000;
// Changes the presentation style if the time of day is after sunset
// or before the next day's sunrise
var isDark = nowtime > sunsettime || nowtime < sunrisetime;
document.getElementById("container").className = isDark ? "nightmode":"daymode";
}
function convertTemperature(kelvin){
// Converts temps in kelvin to celsius or fahrenheit
var celsius = (kelvin - 273.15);
return temperaturescale === "F" ? celsius * 1.8 + 32 : celsius;
}
Schritt 4: Muss ich Ihnen wirklich meinen API-Schlüssel zeigen?
Ich habe einen Einweg-API-Schlüssel verwendet, um eine funktionierende Demo zu erstellen. Im Allgemeinen scheint es jedoch eine schlechte Idee zu sein, einen API-Schlüssel im Klartext im Code einer Front-End-Webanwendung zu platzieren. Andere könnten ihn kopieren und Ihr API-Zugriffskontingent aufbrauchen. Wenn Sie Zugang zu einem typischen Webserver haben (CodePen unterstützt kein PHP), können Sie den API-Schlüssel in einer PHP-Datei verstecken. Hier ist ein Beispielcode. Ersetzen Sie den API-Schlüssel und laden Sie die Datei als clock.php in dasselbe Verzeichnis wie die Haupt-HTML-Datei hoch. Die PHP-Datei dient als eine Art Proxy zur OpenWeatherMap API, die wir verwenden, um Daten in der Demo abzurufen. Wenn sie Probleme beim Abrufen von Wetterdaten hat, gibt sie einfach ein entsprechend strukturiertes Objekt mit "Wetter nicht verfügbar" als Beschreibung und einer Temperatur, die sich in 0° Fahrenheit umrechnet, zurück. Der API-Schlüssel wird nie vom Server zum Browser übertragen, sodass es nichts gibt, was neugierige Augen sehen könnten.
Ich wäre daran interessiert zu hören, ob Sie eine sichere, serverlose Lösung zum Verstecken eines API-Schlüssels kennen (Netlify oder Docker vielleicht?), da es schön wäre, nicht unseren eigenen Server zum Speichern und Abrufen der Daten starten zu müssen. Melden Sie sich, wenn Sie Gedanken dazu haben.
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Clock Data</title></head>
<body>
<?php
error_reporting(0);
$latitude = "80";
$longitude = "-85";
if (isset($_GET["lat"]) && isset($_GET["lon"])) {
$latitude = $_GET["lat"];
$longitude = $_GET["lon"];
}
$endpoint = "http://api.openweathermap.org/data/2.5/weather?";
$apikey = "YOUR_API_KEY_HERE";
$weatherurl = $endpoint . "lat=" . $latitude . "&lon=" . $longitude . "&appid=" . $apikey;
$jsonfile = file_get_contents($weatherurl);
if ($jsonfile !== false){
echo "$jsonfile";
} else {
echo '{"weather":[{"description":"Weather Unavailable","icon":"01n"}],"main":{"temp":255.372278}}';
}
?>
</body>
</html>
Wenn jemand anderes versucht, diese PHP-Datei von einer anderen Domäne aus zu verwenden, sollte der Browser einen Fehler wie den im folgenden Beispiel ausgeben. Ich habe eine Kopie der Wetteruhr auf meiner makepages.com-Domäne geladen und versucht, auf die PHP-Datei auf meiner shearspiremedia.com-Domäne zuzugreifen. Heutzutage gilt die Same-Origin Policy standardmäßig für typische kommerzielle Webserverinstallationen. Möglicherweise müssen Sie bestätigen, dass dies auf dem von Ihnen verwendeten Server der Fall ist.
[Error] Origin https://makepages.com is not allowed by Access-Control-Allow-Origin.
[Error] XMLHttpRequest cannot load https://shearspiremedia.com/demos/clock/clock.php?lat=40.14616446413611&lon=-75.20946717104738 due to access control checks.
Aktualisieren Sie als Nächstes die Variable usephp in der JavaScript-Datei und testen Sie
var usephp = true; // Set to true to use a PHP document to hide your api key
Schritt 5: Kann ich bitte Vollbild gehen?
Sobald die App läuft und funktioniert, kann sie auf jedem Smartphone-Browser geladen werden. Das iPhone ist jedoch gezwungen, die Anwesenheit der Adressleiste und der Fußzeile zu ertragen. Igitt!

Es wäre schön, wenn wir es stattdessen im Vollbildmodus sehen könnten. Dazu benötigen wir eine Manifestdatei, um dem Gerät mitzuteilen, dass wir die Uhr als eigenständige App anzeigen möchten, und um Android-Geräten mitzuteilen, wo sich die App-Icons befinden. Hier ist meine Manifestdatei, die ich als manifest.json im selben Verzeichnis wie die HTML-Datei gespeichert habe. Sie können Ihre eigene Manifestdatei mit dem Web App Manifest Generator erstellen. Achten Sie darauf, die Icon-Dateinamen in Ihrer eigenen Manifestdatei und in den Link-Tags im HTML anzupassen, wie wir hier sehen
{
"short_name": "Weather Clock",
"name": "Weather Clock by Shearspire Media",
"icons":
{
"src": "icons/launcher-icon-1x.png",
"type": "image/png",
"sizes": "48x48"
},
{
"src": "icons/launcher-icon-2x.png",
"type": "image/png",
"sizes": "96x96"
},
{
"src": "icons/launcher-icon-128.png",
"type": "image/png",
"sizes": "128x128"
},
{
"src": "icons/launcher-icon-152.png",
"type": "image/png",
"sizes": "152x152"
},
{
"src": "icons/launcher-icon-4x.png",
"type": "image/png",
"sizes": "192x192"
}
],
"orientation": "landscape",
"display": "standalone",
"start_url": "index.html"
}
Wir benötigen auch ein Set von quadratischen PNG-Bildern in den Größen 192px, 152px, 128px, 96px und 48px für das Icon auf dem Startbildschirm. Speichern Sie diese in einem Ordner "icons" im selben Ordner wie Ihre HTML-Datei. Verwenden Sie die Dateinamen aus dem Manifest. Der Web App Manifest Generator erstellt Icons in allen benötigten Größen außer 48px, indem ein einzelnes 512 x 512 Pixel großes Bild hochgeladen wird. Hier ist das einfache Icon, das ich gemacht habe

Schließlich müssen wir eine Reihe von Meta- und Link-Tags in den Head der HTML-Datei hinzufügen, damit das alles funktioniert. Hier ist der vollständige Code der index.html-Datei, einschließlich aller Head-Tags, die Sie auf CodePen nicht sehen.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="manifest" href="manifest.json">
<link rel="apple-touch-icon" sizes="48x48" href="icons/launcher-icon-1x.png">
<link rel="apple-touch-icon" sizes="96x96" href="icons/launcher-icon-2x.png">
<link rel="apple-touch-icon" sizes="128x128" href="icons/launcher-icon-128.png">
<link rel="apple-touch-icon" sizes="152x152" href="icons/launcher-icon-152.png">
<link rel="apple-touch-icon" sizes="192x192" href="icons/launcher-icon-4x.png">
<title>Weather Clock by ShearSpire Media</title>
<script src="clock.js"></script>
<link rel="stylesheet" type="text/css" href="clock.css">
</head>
<body>
/* Clock markup */
</body>
</html>
Der Besucher kann nun auf der iPhone-Oberfläche auf die Teilen-Schaltfläche tippen und "Zum Startbildschirm hinzufügen" wählen. Ein Icon erscheint, das die Uhr als Vollbild-Standalone-App startet. Genießen Sie es!

Andere Option: IP-Adressen-Standort
Siehe den Pen Clock and Weather IP von Steven Estrella (@sgestrella) auf CodePen.
Wenn der genaue Standort des Benutzers keine Anforderung ist, könnten wir die Geolocation API komplett vermeiden und den ungefähren Standort über verschiedene IP-Adressdienste ermitteln. In der obigen Demo wird ein JSON-Objekt von extreme-ip-lookup.com empfangen, um den ungefähren GPS-Standort des Benutzers zu ermitteln. Dies zeigt die Stadt und die Regionen aus dem JSON anstelle der GPS-Koordinaten. Es sollte dem Benutzer in diesem Fall klar sein, dass der Wetterstandort eine Nachbarstadt ist.

Da IP-Informationen Teil der normalen Anfrage für eine Webseite sind, könnte man argumentieren, dass es ethisch unbedenklich ist, IP-Standortinformationen ohne Benutzererlaubnis anzuzeigen. Das macht den GPS-Button überflüssig. Ich habe die endgültige App tatsächlich auf die IP-Adressen-Standortfunktion umgestellt, wobei die Geolocation nur als Fallback dient, falls der IP-Standortdienst ausfällt. Ich habe auch weitere Wetterinformationen, benutzerdefinierte Hintergrundbilder und benutzerdefinierte Wettericons hinzugefügt, die den aktuellen Wetterbedingungen entsprechen. Die benutzerdefinierten Icons sind in diesem Pen verfügbar. Die endgültige App ist hier auf meiner ShearSpireMedia.com Website verfügbar. Ich habe auch einen Pen erstellt, der einen Sternenhimmel für den Nachtmodus generiert, der für einen Nachtbackground verwendet werden kann.
Das ist ein Abschluss!
Wir haben in diesem Artikel viel Stoff behandelt, aber hoffentlich gibt er Ihnen eine Idee, dass
- Wir einem alten Gerät neue Tricks beibringen können.
- Die Geolocation API ist nicht so beängstigend.
- Das Abrufen und Verwenden von Daten von einer externen API ist nützlich.
- Die Verwendung einer kleinen PHP-Datei ist eine einfache Möglichkeit, Ihren API-Schlüssel vor neugierigen Blicken zu verbergen.
- Die Arbeit mit Benutzerberechtigungen ist eine gute (und oft erforderliche) Praxis.
Wie ich bereits erwähnt habe, wäre eine serverlose Lösung zur Datenspeicherung ideal. Wenn Sie also Gedanken dazu haben – oder wirklich irgendwelche Ideen oder Fragen – lassen Sie es mich bitte in den Kommentaren wissen!
Oh mein Gott, das ist genial!!! Ich habe ein altes Moto G der ersten Generation herumliegen… Ich glaube, ich weiß jetzt, was ich damit machen werde…
Danke für den Kommentar, Andrew. Eine Sache, die ich nicht erwähnt habe, ist, dass ich Command Picture Hanging Strips von 3M verwendet habe, um das Telefon an die Wand zu hängen. Sie enthalten einen Klebstoff, der die Wand nicht beschädigt und bis zu 2 Pfund Gewicht tragen kann.
Sie könnten Netlify ausprobieren – sie unterstützen Cloud Functions, sodass Sie die serverseitige Seite in JS schreiben und von einer statischen Website aus darauf zugreifen können.
Danke Jed. Ich werde mir Netlify genauer ansehen. Ich habe gerade die Dokumentation überprüft und glaube, ich verstehe, wie das funktionieren könnte. Wenn es mir gelingt, werde ich einen CodePen posten und ihn hier verlinken.
Das ist cool – das Einzige, worüber ich mir Sorgen machen würde, ist die Stromversorgung.
Vielleicht wäre es gut, das Telefon in der Nähe eines Fensters mit einer kleinen Solarzelle zu lagern.
Hallo! Kann ich nur das iPhone 4 benutzen – oder kann ich jedes Handy benutzen – wie das Samsung 6?
Hallo Stéphane,
Dieses Projekt sollte auf fast jedem Gerät funktionieren. Das CSS muss vielleicht hier und da ein wenig angepasst werden. Das Samsung 6 ist deutlich größer als das alte iPhone 4, sodass Sie Platz haben, mehr Wetterinformationen einzubauen, wenn Sie möchten. Hier ist meine fertige Version auf meiner Website. https://shearspiremedia.com/demos/clock/
Ich bin sicher, ich habe ein altes iPhone herumliegen. Ich muss dieses nette Projekt ausprobieren.
Viel Glück. Ich habe die iOS-Version auf meinem iPhone 4 auf die aktuellste, die es verarbeiten konnte (9.3.5), aktualisiert, bevor ich mit dem Projekt begonnen habe. Das stellte sicher, dass der Safari-Browser so aktuell wie möglich war. Solange Sie ES5 verwenden, sollte es gut funktionieren.
Spaß, schläft das Telefon nach einer bestimmten Zeit ein?
Hallo Jim, ich habe mein iPhone 4 so eingestellt, dass es niemals schläft (Einstellungen -> Allgemein -> Automatische Sperre -> Nie). Es bleibt die ganze Zeit wach und wird wahrscheinlich noch ein paar Jahre zuverlässig so dienen.