Exibindo mídia com HTML e JavaScript
Tenho um site pessoal que uso para compartilhar vídeos e imagens com amigos. Abaixo está um gerador de mídia usando JavaScript e HTML. Seu principal objetivo é exibir uma imagem por vez com o clique de um botão, mas qualquer tipo de mídia pode ser exibida. Meu objetivo era criar uma página de carregamento rápido para conter todas as minhas 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>
Algumas coisas a serem observadas ...
Organizo os arrays de JavaScript com o mais novo no topo e o mais antigo na parte inferior (com datas, ficaria assim:
oddDate = ['Oct. 1', 'Oct. 2', 'Oct. 3', 'Oct. 4', 'Oct. 5'];O modo aleatório é pseudoaleatório e é projetado para exibir todos os itens do array uma vez antes de repetir um.
Os modos antigo-novo e novo-antigo movem-se pelas matrizes de cima para baixo e de baixo para cima , respectivamente.
Cada modo e categoria salva seu lugar quando você muda para um diferente. Por exemplo, digamos que você tenha o modo antigo-novo ativado e esteja no item 3 da categoria de texto. Você muda para a categoria de foto, percorre um pouco a matriz e retorna à categoria de texto. Ele exibirá o próximo item de onde você parou anteriormente - ou seja, o item 4 . O mesmo pode ser dito para alternar entre os três modos; eles são todos independentes uns dos outros. Isso é algo que eu gostaria de manter.
Uma preocupação é que o gerador e a página ficarão cada vez mais lentos à medida que continuo adicionando mais itens aos arrays, mas não tenho certeza se isso é legítimo. Na versão ao vivo, existem mais de 500 itens em cada matriz e mais serão adicionados ao longo do tempo.
Respostas
Feedback geral
Este código parece funcionar de forma aceitável, embora a semântica de "antigo - novo" pareça invertida.
O primeiro marcador nas notas afirma:
- Organizo os arrays de JavaScript com o mais novo na parte superior e o mais antigo na parte inferior (com datas, seria assim: oddDate = ['01 de outubro', '2 de outubro', '3 de outubro', ' 4 ',' 5 de outubro '];)
Ainda assim, o terceiro marcador afirma:
- Os modos antigo-novo e novo-antigo movem-se pelas matrizes de cima para baixo e de baixo para cima , respectivamente.
Isso parece contraditório, pois se o mais antigo estiver na parte inferior , a classificação antigo-novo deve começar no final da matriz.
O código JavaScript parece muito repetitivo - especialmente na função, newThing()mas também nos nomes das variáveis. Eu recomendo algumas mudanças descritas mais tarde, após a revisão.
Reveja
Javascript
Declarações de variáveis
O código usa alguns recursos específicos para ECMAScript-2015 (AKA ES-6) como a sintaxe de propagação . Com as variáveis ES6 é aconselhável usar conste letlimitar o escopo das variáveis e evitar bugs . Observe que constisso não significa imutabilidade, mas sim que tal variável não pode ser reatribuída.
Variáveis globais
O código faz referência a elementos DOM usando as variáveis criadas implicitamente a partir dos atributos de id - por exemplo,
if(mode1.checked && (videoCheck.checked || audioCheck.checked || photoCheck.checked || textCheck.checked)) {
Se você quiser testar a unidade do código JavaScript, isso pode dificultar.
Rótulos de entrada
Parece que todas as entradas de rádio são contidas por <label>entradas, o que é bom para acessibilidade (por exemplo, leitores de tela, capacidade do usuário de clicar no rótulo para focar / ativar a entrada), no entanto, o texto próximo a cada entrada não está dentro do rótulo. Parece inútil ter um rótulo se a entrada for a única coisa nele.
HTML
Manipuladores de eventos inline
O código configura manipuladores de eventos no código HTML:
<button onclick="newThing()">New Thing</button>
É melhor registrar manipuladores de eventos no JavaScript (por exemplo, usando newButton.addEventListenerpor vários motivos:
- A lógica pode ser separada da marcação - se vários colegas de equipe trabalharam no projeto, um poderia trabalhar no JavaScript enquanto o outro poderia trabalhar no HTML independentemente.
- Esses manipuladores podem poluir o namespace global, o que pode levar a um comportamento estranho .
Alinhando elementos filho
Os <div>elementos têm align="center"e align="right". Isso parece ser um atributo HTML 4 obsoleto e não é mais compatível com o HTML 5. Isso pode ser convertido em regras CSS . Observe que text-alignse aplica a blocos de contêineres 1 . Para centralizar elementos inline como imagens, vídeo, etc., o displaydeve ser definido como blocke margindefinido comoauto .
Vários elementos de formulário
Existem dois <form>elementos separados . Os dois podem ser combinados em um único formulário que contém todos os elementos.
Simplificando o código
As seguintes alterações, junto com as sugestões dos pontos de revisão acima, podem ser usadas para diminuir drasticamente o comprimento do código:
colocar opções em um objeto que pode conter o índice atual e tornar o objeto uma propriedade de um objeto onde o nome da propriedade (ou seja, chave) é o tipo de coisa - por exemplo
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 }, }em vez de usar
idatributos para os botões de opção, apenas forneçavalueatributosreferenciar os elementos do formulário por meio de
document.forms.elementsdeterminar quais botões de opção são selecionados por meio de
RadioNodeList.valueuse um
<output>elemento para a exibição da coisa .use uma classe para encapsular os índices, junto com métodos para obter um item com base no modo
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>