Affichage des médias avec HTML et JavaScript
J'ai un site Web personnel que j'utilise pour partager des vidéos et des images avec des amis. Vous trouverez ci-dessous un générateur de médias utilisant JavaScript et HTML. Son objectif principal est d'afficher une image à la fois en un seul clic, mais tout type de média peut être affiché. Mon objectif était de créer une page à chargement rapide pour contenir tous mes médias.
//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>
Quelques points à noter ...
J'organise les tableaux JavaScript avec le plus jeune en haut et le plus ancien en bas (avec des dates, cela ressemblerait à ceci:
oddDate = ['Oct. 1', 'Oct. 2', 'Oct. 3', 'Oct. 4', 'Oct. 5'];Le mode aléatoire est pseudo aléatoire et est conçu pour afficher tous les éléments du tableau une fois avant d'en répéter un.
Les modes ancien-nouveau et nouvel-ancien se déplacent dans les tableaux de haut en bas et de bas en haut , respectivement.
Chaque mode et catégorie enregistre sa place lorsque vous passez à un autre. Par exemple, disons que vous avez le mode ancien-nouveau activé et que vous êtes sur l' élément 3 de la catégorie de texte. Vous passez à la catégorie photo, parcourez un peu le tableau, puis revenez à la catégorie texte. Il affichera l'élément suivant là où vous vous étiez arrêté précédemment - c'est-à-dire l' élément 4 . La même chose peut être dite pour la commutation entre les trois modes; ils sont tous indépendants les uns des autres. C'est quelque chose que je voudrais maintenir.
Une préoccupation est que le générateur et la page deviendront de plus en plus lents à mesure que je continue à ajouter plus d'éléments aux tableaux, mais je ne suis pas sûr que cela soit légitime. Dans la version en direct, il y a plus de 500 éléments dans chaque tableau et d'autres seront ajoutés au fil du temps.
Réponses
Commentaires généraux
Ce code semble fonctionner de manière acceptable, bien que la sémantique «ancien - nouveau» semble inversée.
La première puce dans les notes indique:
- J'organise les tableaux JavaScript avec le plus jeune en haut et le plus ancien en bas (avec des dates, cela ressemblerait à ceci: oddDate = ['Oct. 1', 'Oct. 2', 'Oct. 3', 'Oct. 4 ',' 5 octobre '];)
Pourtant, la troisième puce indique:
- Les modes ancien-nouveau et nouvel-ancien se déplacent dans les tableaux de haut en bas et de bas en haut , respectivement.
Cela semble contradictoire, car si le plus ancien était en bas, le tri ancien-nouveau devrait commencer à la fin du tableau.
Le code JavaScript semble très répétitif - notamment dans la fonction newThing()mais aussi dans les noms des variables. Je recommanderais quelques changements décrits plus tard, après l'examen.
La revue
Javascript
Déclarations de variables
Le code utilise certaines fonctionnalités spécifiques à ECMAScript-2015 (AKA ES-6) comme la syntaxe de diffusion . Avec les variables ES6, il est conseillé d'utiliser constet letde limiter la portée des variables et d' éviter les bogues . Notez que constcela ne signifie pas immuabilité, mais plutôt qu'une telle variable ne peut pas être réaffectée.
Variables globales
Le code fait référence aux éléments DOM en utilisant les variables créées implicitement à partir des attributs id - par exemple
if(mode1.checked && (videoCheck.checked || audioCheck.checked || photoCheck.checked || textCheck.checked)) {
Si vous souhaitez tester le code JavaScript unitaire, cela peut compliquer la tâche.
Libellés d'entrée
Il semble que toutes les entrées radio sont contenues par des <label>entrées, ce qui est bon pour l'accessibilité (par exemple, les lecteurs d'écran, la capacité de l'utilisateur à cliquer sur l'étiquette pour faire la mise au point / activer l'entrée), mais le texte à côté de chaque entrée n'est pas dans l'étiquette. Il semble inutile d'avoir une étiquette si l'entrée est la seule chose qui s'y trouve.
HTML
Gestionnaires d'événements en ligne
Le code configure des gestionnaires d'événements dans le code HTML:
<button onclick="newThing()">New Thing</button>
Il est préférable d'enregistrer les gestionnaires d'événements dans le JavaScript (par exemple en utilisant newButton.addEventListenerpour plusieurs raisons:
- La logique peut être séparée du balisage - si plusieurs coéquipiers ont travaillé sur le projet, l'un pourrait travailler sur le JavaScript tandis que l'autre pourrait travailler sur le HTML indépendamment.
- De tels gestionnaires peuvent polluer l'espace de noms global, ce qui peut conduire à un comportement étrange .
Aligner les éléments enfants
Les <div>éléments ont align="center"et align="right". Cela semble être un attribut HTML 4 obsolète et n'est plus pris en charge dans HTML 5. Cela peut être converti en règles CSS . Notez que cela text-aligns'applique aux conteneurs de bloc 1 . Pour centrer des éléments en ligne tels que des images, des vidéos, etc., le displaydoit être défini sur blocket margindéfini surauto .
Éléments de formulaire multiples
Il y a deux <form>éléments distincts . Les deux peuvent être combinés en un seul formulaire contenant tous les éléments.
Simplifier le code
Les modifications suivantes, ainsi que les suggestions des points de révision ci-dessus, peuvent être utilisées pour réduire considérablement la longueur du code:
mettre des options dans un objet qui peut contenir l'index courant, et faire de l'objet une propriété d'un objet où le nom de la propriété (c'est-à-dire la clé) est le type de chose - par exemple
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 }, }au lieu d'utiliser des
idattributs pour les boutons radio, donnez-leur simplement desvalueattributsréférencer les éléments du formulaire via
document.forms.elementsdéterminer quels boutons radio sont sélectionnés via RadioNodeList.value
utiliser un élément pour afficher la chose .
utiliser une classe pour encapsuler les index, ainsi que des méthodes pour obtenir un élément en fonction du mode
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>