JavaScript Array
Verena
- array
- javascript
Hallo zusammen,
ich habe mich extra hier angemeldet, um Hilfe bei meinem Problem zu bekommen. Und zwar geht es um eine IMG Gallerie, die über JS bei jedem Neu-Laden zufällig angeordnet wird.
Ich möchte nun aber zu jedem einzelnen Bild individuell die alt und title Tags hinzufügen und einen Text, der beim Hover-Effekt erscheint. Wie mache ich das? Habe mir auch das folgende Script aus dem Web zusammenkopiert.
Freue mich über Hilfe und neuen Input. :D
LG
Verena
Hallo,
Wie mache ich das?
Eine Variante wäre, mit verschachtelten Arrays zu arbeiten. D.h. du hast in deinem Array statt des Pfades zum Bild jeweils ein weiteres Array, das die entsprechenden Daten (Pfad, Title, Alt-Attribut,... ) enthält.
Gruß
Kalk
@@Tabellenkalk
Eine Variante wäre, mit verschachtelten Arrays zu arbeiten. D.h. du hast in deinem Array statt des Pfades zum Bild jeweils ein weiteres Array, das die entsprechenden Daten (Pfad, Title, Alt-Attribut,... ) enthält.
Nö. Das innere Array möchte wohl lieber ein Objekt sein.
🖖 Живіть довго і процвітайте
Moin,
da du mittels document.writeln die Sachen sowieso direkt ins html rein schreibst, kannst du die Bilder auch direkt im html ausgeben und nachträglich die Knoten shuffeln.
Dann hast du nicht so ein Geschi** mit der Datenhaltung in Javascript.
Jedoch ändert sich deine Frage dann. Die Frage ist nicht mehr wie bekomme ich das ins HTML sondern, wie selektiere ich die richtigen Knoten. Und da wird JQuery dein Freund werden :).
Gruß T**Rex
Hallo T-Rex,
… Und da wird JQuery dein Freund werden :).
ich weiß nicht, ob JQuery jemals ein Freund war, heute auf keinem Fall. Es gibt genug DOM-Methoden, z.B. querySelectorAll, die das mindestens genau so gut machen, und ohne großes Framework.
@Verena Ich würde entweder, wie schon vorgeschlagen, ein 2D-Array nehmen, oder ein Array aus Objekten:
const bilder =
[
{ src: "...", alt: "...", title: "..." },
...
];
Gruß
Jürgen
@@JürgenB
Ich würde entweder, wie schon vorgeschlagen, ein 2D-Array nehmen, oder ein Array aus Objekten
Nicht entweder, sondern oder.
🖖 Живіть довго і процвітайте
Ihr könnt euch noch so darüber auslassen ob jQuery gut ist oder nicht.
Der Ansatz die Bilder einfach ins HMTL zu schreiben und dann zu shuffeln finde ich immer noch wesentlich besser, als eine Datenstruktur in JS auf zu bauen.
Gruß
T-Rex 2010er Model
Hallo T-Rex,
ja, das ist auf jeden Fall eine bessere Idee als document.write. HTML mit document.write zu erzeugen ist etwas, das man dem Browser nicht antun sollte, es bringt die ganze Ladeoptimierung der Seite durcheinander.
Wenn man mit JavaScript-Strukturen arbeitet, sollte man die Bilder mit document.createElement("img") erzeugen und mit append an den Galeriecontainer anhängen. Aber das HTML direkt zu schreiben ist einfacher.
Es sei denn, man bekommt dieses Array irgendwoher geliefert und hat die Aufgabe, daraus HTML zu machen. An der Stelle fragt der Client-Server Entwickler dann gleich: Wird das HTML aus PHP erzeugt? Kann man das Bilder-Array schon im PHP als HTML aufbereiten?
Die div-Elemente mit einem für div undefinierten href-Attribut kapiere ich übrigens nicht. Lauert da etwa ein click-Handler im Hintergrund, der auf diese Weise die divs „interaktiv“ zu machen sucht? Wenn ja: bitte zur Kur nach Bad Idea fahren!
Es bietet sich auch an, als Galeriecontainer eine LISTE zu verwenden, um die Zugänglichkeit der Galerie zu verbessern. Das HTML sollte im Minimalfall so aussehen:
<ul id="galerie">
<li><a href="..."><img src"..." alt="..."></a></li>
.
.
.
<li><a href="..."><img src"..." alt="..."></a></li>
</ul>
Diese Galerie kann man mit einer Flexbox und flex-flow: row wrap
visuell aufbereiten. Die Listenpunkte und die Standard-Paddings und -Margins von ul oder li muss man im Stylesheet entfernen (list-style:none;
).
Für das Mischen shuffelt man die li-Elemente in der Liste, der Rest folgt.
Ein besseres HTML würde nicht <img> in die Links setzen, sondern eine <figure> mit <figcaption>-Element. Auch da wird man ggf. die vom Browser gelieferten margins oder paddings entfernen müssen.
Das shuffling ist ein Vierzeiler (der zum oben gezeigten HTML passt und bei anderem HTML natürlich angepasst werden muss). jQuery? Pffft…
<script type="module">
const gallery = document.getElementById("galerie"),
gallerySize = gallery.childElementCount;
for (let i=0; i<gallerySize; i++) {
const shufflee = (Math.random() * gallerySize) >> 0;
gallery.append(gallery.children[shufflee]);
}
</script>
Die Angabe type="module" erzwingt eine Ausführung, nachdem das HTML fertig geparsed ist und erspart einen DOMContentLoaded-Eventhandler oder den Einsatz von jQuery, um einen Ready-Handler zu bauen. Es erzwingt auch den strict mode und isoliert die Variablen gallery und gallerySize in diesem Script.
Das Script hantiert mit der children-NodeList des Galeriecontainers herum. Das ist natürlich nur sinnvoll, wenn das ul Element ausschließlich li Elemente enthält und diese auch alle am shuffling teilnehmen sollen.
Rolf
Lieber Rolf,
Das shuffling ist ein Vierzeiler (der zum oben gezeigten HTML passt und bei anderem HTML natürlich angepasst werden muss). jQuery? Pffft…
man sammelt die Knoten in einem Array, die es zu shufflen gibt, mischt dieses und hängt anschließend die Knoten wieder in ihr ursprüngliches Elternelement ein. Das tut man der Reihe im Array nach.
<script type="module">
const gallery = document.getElementById("galerie"),
nodes = gallery.getElementsByTagName("li");
nodes.shuffle();
nodes.forEach(n => n.parentNode.appendChild(n));
</script>
Liebe Grüße
Felix Riesterer
Hallo Rolf,
zur Kur nach Bad Idea fahren!
🤣 Das musste ich jetzt eine Weile auf mich wirken lassen, bis ich den Gag kapiert habe.
const shufflee = (Math.random() * gallerySize) >> 0;
What the hack?[1] Um 0 Bitpositionen rechtsschieben, damit's wieder ein int wird?
Einen schönen Tag noch
Martin
Ausnahmsweise nicht What the heck. ↩︎
Hallo Martin,
Um 0 Bitpositionen rechtsschieben, damit's wieder ein int wird?
Yup. Math.floor() oder parseInt() sind doch langweilig.
Allerdings könnte dieser Gedanke auch aus besagtem Kurort stammen 😉
Rolf
Hi,
Um 0 Bitpositionen rechtsschieben, damit's wieder ein int wird?
Yup. Math.floor() oder parseInt() sind doch langweilig.
ja, und vergleichsweise umständlich.
Allerdings könnte dieser Gedanke auch aus besagtem Kurort stammen 😉
Finde ich nicht. Ich liebe solche raffinierten Tricks - vorausgesetzt, sie beruhen auf wohldefiniertem Verhalten und nicht auf einem "zufälligen" Implementierungsdetail.
Sowohl in Javascript als auch in PHP caste ich beispielsweise auch gern von String zu Number, indem ich mit 1 multipliziere. Oder von Number zu String, indem ich mit einem Leerstring verkette.
Einen schönen Tag noch
Martin
@@Der Martin
Sowohl in Javascript als auch in PHP caste ich beispielsweise auch gern von String zu Number, indem ich mit 1 multipliziere. Oder von Number zu String, indem ich mit einem Leerstring verkette.
Da hast du aber Glück, dass ich bei dir nicht Code-Review machen darf. Ich würd dir den Kram um die Ohren hauen.
(float) $string
ist sich selbsterklärender Code; $string * 1
ist es nicht.
(string) $number
ist sich selbsterklärender Code; $number . ''
ist es nicht.
🖖 Живіть довго і процвітайте
Hallo Gunnar,
Da hast du aber Glück, dass ich bei dir nicht Code-Review machen darf. Ich würd dir den Kram um die Ohren hauen.
und das, obwohl ich bei meinem C-Quellcode regelmäßig gelobt werde, der sei ja fast wie Prosa lesbar und verständlich.
(float) $string
ist sich selbsterklärender Code;$string * 1
ist es nicht.
(string) $number
ist sich selbsterklärender Code;$number . ''
ist es nicht.
Wenn man diese Konstruktionen einmal gesehen und verstanden hat, sind sie selbsterklärend.
Einen schönen Tag noch
Martin
@@Der Martin
(float) $string
ist sich selbsterklärender Code;$string * 1
ist es nicht.
(string) $number
ist sich selbsterklärender Code;$number . ''
ist es nicht.Wenn man diese Konstruktionen einmal gesehen und verstanden hat, sind sie selbsterklärend.
Nein. Und vor allem sind sie völlig unnötig. Es gibt ja sowohl in PHP als auch in JavaScript Konstrukte, die im Namen haben, was sie tun.
Für PHP hatte ich sie genannt, in JavaScript parseFloat(string)
bzw. parseInt(string)
und Number.toString()
.
🖖 Живіть довго і процвітайте
(float) $string
ist sich selbsterklärender Code;$string * 1
ist es nicht.
$float = floatval( $var ) ist „sich selbst erklärender Code“.
(string) $number
ist sich selbsterklärender Code;$number . ''
ist es nicht.
$string = strval( $var ) ist „sich selbst erklärender Code“.
Denn beide zeigen etwas, was jeder und jede am ersten Tag im Fach Programmierern gelernt hat, die „Filterschreibweise“ ist hingegen krude (a.k.a. „hirnfurzig“).
@@Rolf B
Das shuffling ist ein Vierzeiler (der zum oben gezeigten HTML passt und bei anderem HTML natürlich angepasst werden muss).
<script type="module"> const gallery = document.getElementById("galerie"), gallerySize = gallery.childElementCount; for (let i=0; i<gallerySize; i++) { const shufflee = (Math.random() * gallerySize) >> 0; gallery.append(gallery.children[shufflee]); } </script>
Von dem Unsinn mit >> 0
ganz abgesehen hege ich hier arge Zweifel, dass das ordentlich mischt.
🖖 Живіть довго і процвітайте
Danke für die Antwort, dann versuche ich das mal. :)
Hallo T-Rex,
… Und da wird JQuery dein Freund werden :).
ich weiß nicht, ob JQuery jemals ein Freund war, heute auf keinem Fall. Es gibt genuf DOM-Methoden, z.B. querySelectorAll, die das mindestens genau so gut machen, und ohne großes Framework.
@Verena Ich würde entweder, wie schon vorgeschlagen, ein 2D-Array nehmen, oder ein Array aus Objekten:
const bilder = [ { src: "...", alt: "...", title: "..." }, ... ];
Gruß
Jürgen
Hallo Jürgen! Kannst du mir zu meinem Code ein direktes Beispiel geben, wie Du das mit den Objekten machen würdest? Ich bin leider nicht soo fit da drin und benötige noch viel Übung - aber für meine Testwebsite möchte ich mir eben mal einen Pool an solchen Codes zusammentragen.
Freue mich über Hilfe und Deine Antwort. LG
@@T-Rex
Und da wird JQuery dein Freund werden :).
Die 2010er Jahre haben angerufen. Sie hätten gerne ihre nicht mehr benötigten JavaScript-Bibliotheken zurück.
🖖 Живіть довго і процвітайте
Manchmal wäre konstruktive Kritik einfach hilfreicher... Hat an dieser Stelle nichts verloren, sorry. Aber danke für den Input.
Und da wird JQuery dein Freund werden :).
Die 2010er Jahre haben angerufen. Sie hätten gerne ihre nicht mehr benötigten JavaScrpt-Bibliotheken zurück.
„2010er“? Das kann ich als alter Mann so nicht stehen lassen ;-) Wenn wir 2019 betrachten, kann man das vielleicht so durchgehen lassen. Z.B. 2013 hingegen war jQuery m.E. durchaus noch angebracht, auch für Neuentwicklungen.
@@Mitleser 2.0
Die 2010er Jahre haben angerufen. Sie hätten gerne ihre nicht mehr benötigten JavaScrpt-Bibliotheken zurück.
„2010er“? Das kann ich als alter Mann so nicht stehen lassen ;-) Wenn wir 2019 betrachten, kann man das vielleicht so durchgehen lassen. Z.B. 2013 hingegen war jQuery m.E. durchaus noch angebracht, auch für Neuentwicklungen.
Das widerspricht nicht meinem Gesagtem. Ich sagte ja nicht, dass besagte JavaScript-Bibliotheken in den 2010ern schon nicht mehr benötigt gewesen wären.
🖖 Живіть довго і процвітайте
Liebe Verena,
Code wäre als echter Text hier viel schöner, als aus einem Bild abtippen zu müssen, um dann zitieren zu können.
Du willst Bilder in einer zufälligen Reihenfolge anzeigen? Dann wäre die vernünftigste Lösung so, wie @T-Rex es vorschlug, die Bilder im HTML regulär auszuliefern.
<div id="gallery">
<img alt="Hund mit Knochen" src="images/referenzen/spenglerei-muenchen-1.png">
<img alt="Hund mit Knochen" src="images/referenzen/spenglerei-muenchen-2.png">
<img alt="Hund mit Knochen" src="images/referenzen/spenglerei-muenchen-3.png">
<!-- ... und noch Bilder 4 - 9 ... -->
</div>
Dem <div>
habe ich absichtlich eine ID gegeben, denn dann kann man das mit JavaScript-Bordmitteln sehr gut erreichen. Die Bilder darin kann man dann gut in einem Array verwalten:
document.addEventListener("DOMContentLoaded", function () {
// wo ist die Galerie?
const gallery = document.getElementById("gallery");
// keine Galerie gefunden?
if (!gallery) {
return;
}
const images = Array.from( // Array.from macht daraus ein Array:
gallery.getElementsByTagName("img")
);
// keine Bilder in der Galerie?
if (!images.length) {
return;
}
images.shuffle(); // Bilderliste vermischen
// jedes Bild ans Ende der Galerie anhängen (hängt es effektiv um)
images.forEach(function (img) {
gallery.appendChild(img);
});
// modernere Schreibweise für das Umhängen
images.forEach(img => gallery.appendChild(img));
});
Das JavaScript ist ungetestet! Es wird im <head>
-Element der Seite in einem <script>
-Element notiert und legt erst dann los, wenn die Seite das Dokument vollständig aufgebaut hat:
<head>
...
<title>... wasauchimmer ...</title>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function () {
// hier das Script
});
</script>
</head>
Liebe Grüße
Felix Riesterer
Hallo Felix,
die Idee mit der ID ist gut, das habe ich in meinem Posting gleich korrigiert.
Eine Abfrage ob die Galerie gefunden wurde? Na gut. Kann man bei sehr seitenspezifischem Code auch lassen.
Aber
const images = Array.from(gallery.getElementsByTagName("img"))
Wieso so kompliziert? Was ist mit
const images = gallery.querySelectorAll("img");
Du verwendest Array.from, damit bist Du eh bei evergreen-Browsern.
Deine shuffle-Methode bringt mich gerade an den Rand des Wahnsinns. Die war mir neu. Ich habe gestutzt, dann eine Konsole geöffnet und nach Array.prototype.shuffle gesucht - oha, ist drin?! Bei MDN geguckt - nicht dokumentiert. In einem leeren Browserfenster probiert (könnte ja Chrome-Extension sein) - nicht im Prototypen drin. Und seitdem finde ich die Seite nicht mehr wieder, die shuffle als Extension für Array.prototype definierte. Wo ist die bloß her? Jedenfalls nicht Standard-JavaScript.
Aber wenn's irgendwoher eine shuffle-Methode für Array gibt, dann sollte die so schlau sein, sich auch auf eine NodeList anwenden zu lassen (die aus querySelectorAll herauskommt).
Rolf
@@Rolf B
Und seitdem finde ich die Seite nicht mehr wieder, die shuffle als Extension für Array.prototype definierte. Wo ist die bloß her?
Aus PHP. 😁
Jedenfalls nicht Standard-JavaScript.
Yo, muss man selbst hinzufügen:
// Fisher-Yates shuffle taken from https://javascript.info/task/shuffle
Array.prototype.shuffle = function () {
for (let i = this.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1)); // random index from 0 to i
[this[i], this[j]] = [this[j], this[i]];
}
};
🖖 Живіть довго і процвітайте
Lieber Gunnar,
ja, Fisher-Yates. In meinem R-Quiz habe ich 2017 genau den verwendet:
/**
* function to shuffle an array
*
* http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array#answer-25984542
*
* @param Array input
*/
shuffleArray: function (array) {
var count = array.length, r, temp;
while (count) {
r = Math.random() * count-- | 0;
temp = array[count];
array[count] = array[r];
array[r] = temp;
}
},
Liebe Grüße
Felix Riesterer
Ich habe gestutzt, dann eine Konsole geöffnet und nach Array.prototype.shuffle gesucht
Wie kann man in der Konsole suchen, bitte?
Hallo T-Rex,
einfach Array.prototype.shuffle eintippen, ENTER drücken und "undefined" herausbekommen.
Rolf
Hallo zurück,
aber du schriebst doch "is drin". Aber undefined heißt doch, dass es nicht drin ist ...
Hallo T-Rex,
ja, einmal war sie drin. Ich fand eine function vor - mit explizitem Sourcecode, nicht als native function. Aber dann hab ich in siebenunddrölfzig Browser-Tabs herumgeturnt und dann war sie weg und ich habe nicht mehr rausgekriegt, wo sie definiert war.
Rolf
@@Felix Riesterer
Du willst Bilder in einer zufälligen Reihenfolge anzeigen? Dann wäre die vernünftigste Lösung so, wie @T-Rex es vorschlug, die Bilder im HTML regulär auszuliefern.
Nein.
Vernünftig an der Lösung ist, dass das Umsortieren progressive enhancement ist. Ohne die Ausführung des JavaScripts wird die Bildergalerie auch dargestellt – dann eben in der im HTML vorgegebenen Reihenfolge.
Unvernünftig an der Lösung ist, dass die Bildergalerie zuerst in der im HTML vorgegebenen Reihenfolge dargestellt wird und dann per JavaScript umsortiert wird, wobei der Bildschirm munter flackert. Das sollte man den Nutzern nicht antun!
Alternativen:
Die Bildergalerie erst mit JavaScript rendern. Dann dürfte ein Array von Objekten {src: …, alt: …, description: … }
das bessere Datenformat sein als Markup – zumal die Items ja noch aus mehr bestehen sollen als img
. Ohne JavaScript wäre dann nichts zu sehen, oder man müsste sich noch um eine Alternative (<noscript>
?) Gedanken machen.
Die Bildergalerie serverseitig mischen. In PHP gibt’s dafür sogar shuffle($array)
. 😉
Die Bildergalerie nicht mischen. Welchen Nutzen hat das denn für die Seitenbesucher?
🖖 Живіть довго і процвітайте
@@Gunnar Bittersmann
- Die Bildergalerie nicht mischen. Welchen Nutzen hat das denn für die Seitenbesucher?
Vermutlich keinen. Ich bekenne mich aber schuldig, so eine Spielerei auch schon gemacht zu haben: bei meiner Präsentation CSSBattle at CSS Café. Durchclicken bis die Bilder der sog. Targets erscheinen – jedes Mal in anderer Reihenfolge an anderen Plätzen.
Oh, verdammt, ich muss endlich mal das Video von dem Vortrag bearbeiten und veröffentlichen!
🖖 Живіть довго і процвітайте
@@Felix Riesterer
Das JavaScript […] wird im
<head>
-Element der Seite in einem<script>
-Element notiert und legt erst dann los, wenn die Seite das Dokument vollständig aufgebaut hat
Der bevorzugte Platz für solche Scripte ist nicht der head
, sondern das Ende des body
s.
Dann wird nicht das Rendern der Seite blockiert und das document.addEventListener("DOMContentLoaded", …)
kann man sich auch sparen.
🖖 Живіть довго і процвітайте
Hallo Gunnar,
Beides ist Quark.
<script type="module">
und fertig. Egal wo das Script steht, es wird deferred ausgeführt, also direkt vor dem Feuern des DOMContentLoaded Events
Rolf
Top Antwort - genau so hätte ich es auch gemacht.
(Nur mit jQuery. Gebt mir nur eure negativen Kommentare ... die Syntax ist kürzer und man kann jquery UI Sachen drauf setzen.)
@@T-Rex
(Nur mit jQuery. Gebt mir nur eure negativen Kommentare ... die Syntax ist kürzer
Der zu übertragende und im Browser auszuführende Code aber nicht.
Man sollte als Entwickler seine Probleme nicht auf die Nutzer abwälzen.
und man kann jquery UI Sachen drauf setzen.)
Schlimmer geht immer.
🖖 Живіть довго і процвітайте
Lieber T-Rex,
Top Antwort
da bin ich mir nicht sicher. Array.prototype.shuffle
ist keine native Methode von Array. Dass ich das in meinen Projekten via Polyfill nachrüste, hätte ich hier nicht verschweigen sollen.
Liebe Grüße
Felix Riesterer
@@Felix Riesterer
Array.prototype.shuffle
ist keine native Methode von Array.
Sollte es aber, IMHO.
Dass ich das in meinen Projekten via Polyfill nachrüste, hätte ich hier nicht verschweigen sollen.
Du verwendest hoffentlich den richtigen, nicht irgendwelchen Mist.
🖖 Живіть довго і процвітайте
@@Verena
Hallo zusammen,
ich habe mich extra hier angemeldet, um Hilfe bei meinem Problem zu bekommen. Und zwar geht es um eine IMG Gallerie, die über JS bei jedem Neu-Laden zufällig angeordnet wird.
Ich möchte nun aber zu jedem einzelnen Bild individuell die alt und title Tags hinzufügen und einen Text, der beim Hover-Effekt erscheint. Wie mache ich das? Habe mir auch das folgende Script aus dem Web zusammenkopiert.
Und dabei bist du Uralt-Seiten auf dem Leim gegangen‽
<script language="JavaScript">
Das language
-Attribute war wohl noch nie sinnvoll. <script>
genügt.
var banner = new Array(…, …);
Kann man machen; die Schreibweise mit []
ist aber kürzer und genauso gut verständlich. Außerdem solltest du die Schlüsselwörter const
bzw. let
statt var
verwenden. Hier const
:
const banner = […, …];
for(i=9; i>0; i--)
i
sollte keine globale Varible sein; das Schlüsselwort fehlt. Hier let
, denn i
ändert sich ja:
for (let i = 9; i > 0; i--)
zufall = Math.round(Math.random()*(i-1));
zufall
sollte keine globale Varible sein; das Schlüsselwort fehlt. Hier const
, denn zufall
ändert sich ja nicht mehr.
Math.round()
ist in Verbindung mit Math.random()
so gut wie immer falsch. Da wäre Math.floor()
zu verwenden:
const zufall = Math.floor(Math.random() * i);
🖖 Живіть довго і процвітайте