Visualizzazione dei media con HTML e JavaScript
Ho un sito web personale che utilizzo per condividere video e immagini con gli amici. Di seguito è riportato un generatore di media che utilizza JavaScript e HTML. Il suo scopo principale è visualizzare un'immagine alla volta con un clic, ma è possibile visualizzare qualsiasi tipo di supporto. Il mio obiettivo era creare una pagina a caricamento rapido per contenere tutti i miei file multimediali.
//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>
Alcune cose da notare ...
Organizzo gli array JavaScript con il più giovane in alto e il più vecchio in basso (con le date, sarebbe simile a questo:
oddDate = ['Oct. 1', 'Oct. 2', 'Oct. 3', 'Oct. 4', 'Oct. 5'];La modalità casuale è pseudo casuale ed è progettata per visualizzare tutti gli elementi dell'array una volta prima di ripeterne uno.
Le modalità vecchio-nuovo e nuovo-vecchio si spostano tra gli array rispettivamente dall'alto verso il basso e dal basso verso l'alto .
Ogni modalità e categoria salva la sua posizione quando si passa a una diversa. Ad esempio, supponiamo che tu abbia attivato la modalità vecchio-nuovo e ti trovi sull'elemento 3 della categoria di testo. Si passa alla categoria delle foto, si scorre un po 'nell'array, quindi si torna alla categoria di testo. Verrà visualizzato l'elemento successivo da dove eri rimasto in precedenza, ovvero l' elemento 4 . Lo stesso si può dire per il passaggio tra le tre modalità; sono tutti indipendenti l'uno dall'altro. Questo è qualcosa che vorrei mantenere.
Una preoccupazione è che il generatore e la pagina diventeranno sempre più lenti man mano che continuo ad aggiungere più elementi agli array, ma non sono sicuro che sia legittimo. Nella versione live, ci sono più di 500 elementi in ogni array e altri verranno aggiunti nel tempo.
Risposte
Feedback generale
Questo codice sembra funzionare in modo accettabile, anche se la semantica di "vecchio - nuovo" sembra invertita.
Il primo punto nelle note afferma:
- Organizzo gli array JavaScript con il più giovane in alto e il più vecchio in basso (con le date, sarebbe simile a questo: oddDate = ['Oct. 1', 'Oct. 2', 'Oct. 3', 'Oct. 4 ', "5 ottobre"];)
Eppure il terzo punto indica:
- Le modalità vecchio-nuovo e nuovo-vecchio si spostano tra gli array rispettivamente dall'alto verso il basso e dal basso verso l'alto .
Ciò sembra contraddittorio, poiché se il più vecchio era in fondo, l' ordinamento vecchio-nuovo dovrebbe iniziare alla fine dell'array.
Il codice JavaScript sembra molto ripetitivo, specialmente nella funzione newThing()ma anche nei nomi delle variabili. Consiglierei alcune modifiche descritte più avanti, dopo la revisione.
Revisione
Javascript
Dichiarazioni variabili
Il codice utilizza alcune funzionalità specifiche di ECMAScript-2015 (AKA ES-6) come la sintassi di diffusione . Con le variabili ES6 è consigliabile utilizzare conste letlimitare l'ambito delle variabili ed evitare bug . Nota che constnon significa immutabilità, ma piuttosto che una tale variabile non può essere riassegnata.
Variabili globali
Il codice fa riferimento a elementi DOM utilizzando le variabili create implicitamente dagli attributi id - es
if(mode1.checked && (videoCheck.checked || audioCheck.checked || photoCheck.checked || textCheck.checked)) {
Se si desidera eseguire un test unitario del codice JavaScript, questo potrebbe renderlo difficile.
Etichette di input
Sembra che tutti gli ingressi radio siano contenuti da <label>ingressi, il che è positivo per l'accessibilità (ad esempio lettori di schermo, capacità dell'utente di fare clic sull'etichetta per mettere a fuoco / attivare l'input) tuttavia il testo accanto a ciascun ingresso non è all'interno dell'etichetta. Sembra inutile avere un'etichetta se l'input è l'unica cosa in essa contenuta.
HTML
Gestori di eventi in linea
Il codice imposta i gestori di eventi all'interno del codice HTML:
<button onclick="newThing()">New Thing</button>
È meglio registrare i gestori di eventi all'interno di JavaScript (ad esempio utilizzando newButton.addEventListenerper più motivi:
- La logica può essere separata dal markup: se più membri del team hanno lavorato al progetto, uno potrebbe lavorare su JavaScript mentre l'altro potrebbe lavorare sull'HTML in modo indipendente.
- Tali gestori possono inquinare lo spazio dei nomi globale che può portare a comportamenti strani .
Allineamento di elementi figlio
Gli <div>elementi hanno align="center"e align="right". Sembra essere un attributo HTML 4 obsoleto e non più supportato in HTML 5. Può essere convertito in regole CSS . Nota che si text-alignapplica ai contenitori di blocchi 1 . Per gli elementi in linea del centro, come immagini, video, ecc l' displayavrebbe bisogno di essere impostato blocke marginpronto aauto .
Più elementi del modulo
Ci sono due <form>elementi separati . I due potrebbero essere combinati in un unico modulo che contiene tutti gli elementi.
Codice semplificato
Le seguenti modifiche, insieme ai suggerimenti dei punti di revisione sopra riportati, possono essere utilizzati per ridurre drasticamente la lunghezza del codice:
inserire opzioni in un oggetto che può contenere l'indice corrente e rendere l'oggetto una proprietà di un oggetto in cui il nome della proprietà (cioè la chiave) è il tipo di cosa - ad es.
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 }, }invece di usare
idattributi per i pulsanti di opzione, assegna loro deglivalueattributifare riferimento agli elementi del modulo tramite
document.forms.elementsdeterminare quali pulsanti di opzione sono selezionati tramite RadioNodeList.value
usa un elemento per la visualizzazione della cosa .
usa una classe per incapsulare gli indici, insieme a metodi per ottenere un elemento basato sulla modalità
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>