Anzeigen von Medien mit HTML und JavaScript
Ich habe eine persönliche Website, auf der ich Videos und Bilder mit Freunden teilen kann. Unten finden Sie einen Mediengenerator, der JavaScript und HTML verwendet. Der Hauptzweck besteht darin, jeweils ein Bild auf Knopfdruck anzuzeigen. Es können jedoch alle Arten von Medien angezeigt werden. Mein Ziel war es, eine schnell ladende Seite für alle meine Medien zu erstellen.
//VIDEO ARRAY
var oddvideo = [
'video1',
'video2',
'video3',
'video4',
'video5',
];
//AUDIO ARRAY
var oddaudio = [
'audio1',
'audio2',
'audio3',
'audio4',
'audio5',
];
//PHOTO ARRAY
var oddphoto = [
'photo1',
'photo2',
'photo3',
'photo4',
'photo5',
];
//TEXT ARRAY
var oddtext = [
'text1',
'text2',
'text3',
'text4',
'text5',
];
//RANDOM UNUSED ARRAY ITEMS
var Uvideo = [];
var Uaudio = [];
var Uphoto = [];
var Utext = [];
//OLD-NEW VARIABLES
var videoFor = 0;
var audioFor = 0;
var photoFor = 0;
var textFor = 0;
//NEW-OLD VARIABLES
var videoRev = oddvideo.length - 1;
var audioRev = oddaudio.length - 1;
var photoRev = oddphoto.length - 1;
var textRev = oddtext.length - 1;
//GENERATOR FUNCTION
function newThing() {
//RANDOM MODE
if(mode1.checked && (videoCheck.checked || audioCheck.checked || photoCheck.checked || textCheck.checked)) {
if (videoCheck.checked) {
if (!Uvideo.length) Uvideo = [...oddvideo];
var randomY = Uvideo;
}
if (audioCheck.checked) {
if (!Uaudio.length) Uaudio = [...oddaudio];
var randomY = Uaudio;
}
if (photoCheck.checked) {
if (!Uphoto.length) Uphoto = [...oddphoto];
var randomY = Uphoto;
}
if (textCheck.checked) {
if (!Utext.length) Utext = [...oddtext];
var randomY = Utext;
}
var randomX = Math.floor(Math.random() * (randomY.length));
var y = randomY;
var x = randomX;
document.getElementById("thingDisplay").innerHTML = y[x];
// remove randomx from the unused array since it's been used now
randomY.splice(randomX, 1);
}
//OLD-NEW MODE
if(mode2.checked && (videoCheck.checked || audioCheck.checked || photoCheck.checked || textCheck.checked)) {
if(videoCheck.checked) {
document.getElementById('thingDisplay').innerHTML = oddvideo[videoFor];
videoFor++;
if (videoFor >= oddvideo.length) videoFor = 0;
}
if(audioCheck.checked) {
document.getElementById('thingDisplay').innerHTML = oddaudio[audioFor];
audioFor++;
if (audioFor >= oddaudio.length) audioFor = 0;
}
if(photoCheck.checked) {
document.getElementById('thingDisplay').innerHTML = oddphoto[photoFor];
photoFor++;
if (photoFor >= oddphoto.length) photoFor = 0;
}
if(textCheck.checked) {
document.getElementById('thingDisplay').innerHTML = oddtext[textFor];
textFor++;
if (textFor >= oddtext.length) textFor = 0;
}
}
//NEW-OLD MODE
if(mode3.checked && (videoCheck.checked || audioCheck.checked || photoCheck.checked || textCheck.checked)) {
if(videoCheck.checked) {
document.getElementById('thingDisplay').innerHTML = oddvideo[videoRev];
videoRev--;
if (videoRev < 0) videoRev = oddvideo.length - 1;
}
if(audioCheck.checked) {
document.getElementById('thingDisplay').innerHTML = oddaudio[audioRev];
audioRev--;
if (audioRev < 0) audioRev = oddaudio.length - 1;
}
if(photoCheck.checked) {
document.getElementById('thingDisplay').innerHTML = oddphoto[photoRev];
photoRev--;
if (photoRev < 0) photoRev = oddphoto.length - 1;
}
if(textCheck.checked) {
document.getElementById('thingDisplay').innerHTML = oddtext[textRev];
textRev--;
if (textRev < 0) textRev = oddtext.length - 1;
}
}
}
<body>
<div align="center" id='thingDisplay'></div>
<div align="center">
<button onclick="newThing()">New Thing</button>
</div>
<form id="mode">
<label><input type="radio" name="modes" id="mode1"/></label> Random
<br/><label><input type="radio" name="modes" id="mode2"/></label> Old - New
<br/><label><input type="radio" name="modes" id="mode3"/></label> New - Old
</form>
<div align="right">
<form id="categories" align="right">
Video<label> <input type="radio" name="thing" id="videoCheck"/></label><br/>
Audio<label> <input type="radio" name="thing" id="audioCheck"/></label><br/>
Photo<label> <input type="radio" name="thing" id="photoCheck"/></label><br/>
Text<label> <input type="radio" name="thing" id="textCheck"/></label>
</form>
</div>
</body>
Ein paar Dinge zu beachten ...
Ich organisiere die JavaScript-Arrays mit den jüngsten oben und den ältesten unten (mit Datumsangaben würde es so aussehen:
oddDate = ['Oct. 1', 'Oct. 2', 'Oct. 3', 'Oct. 4', 'Oct. 5'];Der Zufallsmodus ist pseudozufällig und dient dazu, alle Array-Elemente einmal anzuzeigen, bevor eines wiederholt wird.
Der Alt-Neu- und der Neu-Alt-Modus bewegen sich durch die Arrays von oben nach unten bzw. von unten nach oben .
Jeder Modus und jede Kategorie speichert ihren Platz, wenn Sie zu einem anderen wechseln. Angenommen, Sie haben den Alt-Neu- Modus aktiviert und befinden sich in Punkt 3 der Textkategorie. Sie wechseln zur Fotokategorie, durchlaufen das Array ein wenig und kehren dann zur Textkategorie zurück. Es wird das nächste Element angezeigt, von dem Sie zuvor aufgehört haben - dh Element 4 . Gleiches gilt für das Umschalten zwischen den drei Modi; sie sind alle unabhängig voneinander. Dies möchte ich beibehalten.
Eine Sorge ist, dass der Generator und die Seite immer langsamer werden, wenn ich den Arrays weitere Elemente hinzufüge, aber ich bin mir nicht sicher, ob dies legitim ist. In der Live-Version enthält jedes Array mehr als 500 Elemente, und im Laufe der Zeit werden weitere hinzugefügt.
Antworten
Allgemeines Feedback
Dieser Code scheint akzeptabel zu funktionieren, obwohl die Semantik von "alt - neu" umgekehrt zu sein scheint.
Die erste Kugel im Anhang besagt:
- Ich organisiere die JavaScript-Arrays mit den jüngsten oben und den ältesten unten (mit Datumsangaben würde dies folgendermaßen aussehen: oddDate = ['1. Oktober', '2. Oktober', '3. Oktober', 'Okt. 4 ',' 5. Oktober '];)
Die dritte Kugel besagt jedoch:
- Der Alt-Neu- und der Neu-Alt-Modus bewegen sich durch die Arrays von oben nach unten bzw. von unten nach oben .
Das scheint widersprüchlich, denn wenn die älteste unten war, sollte die Alt-Neu- Sortierung am Ende des Arrays beginnen.
Der JavaScript-Code scheint sich sehr zu wiederholen - insbesondere in der Funktion, newThing()aber auch in den Variablennamen. Ich würde einige Änderungen empfehlen, die später nach der Überprüfung beschrieben werden.
Rezension
Javascript
Variablendeklarationen
Der Code verwendet einige für ECMAScript-2015 (AKA ES-6) spezifische Funktionen wie die Spread-Syntax . Bei ES6-Variablen ist es ratsam, den Umfang der Variablen zu verwenden constund leteinzuschränken und Fehler zu vermeiden . Beachten Sie, dass constdies keine Unveränderlichkeit bedeutet, sondern dass eine solche Variable nicht neu zugewiesen werden kann.
Globale Variablen
Der Code verweist auf DOM-Elemente unter Verwendung der Variablen, die implizit aus den ID- Attributen erstellt wurden - z
if(mode1.checked && (videoCheck.checked || audioCheck.checked || photoCheck.checked || textCheck.checked)) {
Wenn Sie den JavaScript-Code einem Unit-Test unterziehen möchten, ist dies möglicherweise schwierig.
Geben Sie Beschriftungen ein
Es scheint, dass alle Radioeingänge in Eingängen enthalten sind <label>, was für die Zugänglichkeit gut ist (z. B. Bildschirmleser, Fähigkeit des Benutzers, auf das Etikett zu klicken, um den Eingang zu fokussieren / zu aktivieren), jedoch befindet sich der Text neben jedem Eingang nicht innerhalb des Etiketts. Es scheint sinnlos, eine Beschriftung zu haben, wenn die Eingabe das einzige ist, was darin enthalten ist.
HTML
Inline-Ereignishandler
Der Code richtet Ereignishandler im HTML-Code ein:
<button onclick="newThing()">New Thing</button>
Es ist besser, Ereignishandler im JavaScript zu registrieren (z. B. newButton.addEventListeneraus mehreren Gründen:
- Die Logik kann vom Markup getrennt werden. Wenn mehrere Teammitglieder an dem Projekt gearbeitet haben, kann einer an JavaScript arbeiten, während der andere unabhängig an HTML arbeitet.
- Solche Handler können den globalen Namespace verschmutzen, was zu seltsamem Verhalten führen kann .
Untergeordnete Elemente ausrichten
Die <div>Elemente haben align="center"und align="right". Dies scheint ein veraltetes HTML 4-Attribut zu sein, das in HTML 5 nicht mehr unterstützt wird. Dies kann in CSS-Regeln konvertiert werden . Beachten Sie, dass dies text-alignfür Blockcontainer 1 gilt . Bis Mitte Inline - Elemente wie Bilder, Video, etc. die displaymüßte gesetzt werden blockund marginSatzauto .
Mehrere Formularelemente
Es gibt zwei separate <form>Elemente. Die beiden könnten zu einer einzigen Form kombiniert werden, die alle Elemente enthält.
Code vereinfachen
Die folgenden Änderungen können zusammen mit Vorschlägen aus den obigen Überprüfungspunkten verwendet werden, um die Länge des Codes drastisch zu verringern:
Fügen Sie Optionen in ein Objekt ein, das den aktuellen Index enthalten kann, und machen Sie das Objekt zu einer Eigenschaft eines Objekts, bei dem der Eigenschaftsname (dh der Schlüssel) der Typ der Sache ist - z
const options = { video: { options: [ //VIDEO ARRAY 'video1', 'video2', 'video3', 'video4', 'video5', ], currentIndex: -1 }, audio: { options: [ //AUDIO ARRAY 'audio1', 'audio2', 'audio3', 'audio4', 'audio5', ], currentIndex: -1 }, photo: { options: [ //PHOTO ARRAY 'photo1', 'photo2', 'photo3', 'photo4', 'photo5', ], currentIndex: -1 }, text: { options: [ //TEXT ARRAY 'text1', 'text2', 'text3', 'text4', 'text5', ], currentIndex: -1 }, }Anstatt
idAttribute für die Optionsfelder zu verwenden, geben Sie ihnen einfachvalueAttributeVerweisen Sie auf die Formularelemente über
document.forms.elementsBestimmen Sie, welche Optionsfelder über ausgewählt werden RadioNodeList.value
Verwenden Sie ein Element für die Anzeige der Sache .
Verwenden Sie eine Klasse , um die Indizes zu kapseln, sowie Methoden, um ein Element basierend auf dem Modus abzurufen
class ThingList {
constructor(items) {
this.items = items;
this.randomUnused = [...items];
this.forwardIndex = 0;
this.reverseIndex = items.length - 1;
}
forwardItem() {
return this.items[this.forwardIndex++ % (this.items.length)];
}
randomItem() {
if (!this.randomUnused.length) {
this.randomUnused.push(...this.items);
}
const index = Math.floor(Math.random() * this.randomUnused.length)
return this.randomUnused.splice(index, 1);
}
reverseItem() {
if (this.reverseIndex < 0) {
this.reverseIndex = this.items.length - 1;
}
return this.items[this.reverseIndex--];
}
}
const options = {
video: new ThingList([ //VIDEO ARRAY
'video1',
'video2',
'video3',
'video4',
'video5',
]),
audio: new ThingList([ //AUDIO ARRAY
'audio1',
'audio2',
'audio3',
'audio4',
'audio5',
]),
photo: new ThingList([ //PHOTO ARRAY
'photo1',
'photo2',
'photo3',
'photo4',
'photo5',
]),
text: new ThingList([ //TEXT ARRAY
'text1',
'text2',
'text3',
'text4',
'text5',
])
}
const output = document.getElementsByTagName('output')[0];
//GENERATOR FUNCTION
function newThing() {
if (!(document.forms.thingSelection.type.value in options)) {
return false;
}
const list = options[document.forms.thingSelection.type.value];
const method = document.forms.thingSelection.mode.value + 'Item';
const item = list[method]();
output.innerHTML = item;
}
document.getElementsByTagName('button')[0].addEventListener('click', newThing)
.center {
text-align: center;
}
.right {
text-align: right;
}
<div class="center"><output></output></div>
<div class="center">
<button>New Thing</button>
</div>
<form name="thingSelection">
<label><input type="radio" name="mode" value="random" /> Random</label>
<br /><label><input type="radio" name="mode" value="forward" /> Old - New</label>
<br /><label><input type="radio" name="mode" value="reverse" /> New - Old</label>
<div class="right">
<label>Video <input type="radio" name="type" value="video" /></label><br />
<label>Audio <input type="radio" name="type" value="audio" /></label><br />
<label>Photo <input type="radio" name="type" value="photo" /></label><br />
<label>Text <input type="radio" name="type" value="text" /></label>
</div>
</form>