HTML 및 JavaScript로 미디어 표시

Oct 02 2020

친구와 비디오와 이미지를 공유하는 데 사용하는 개인 웹 사이트가 있습니다. 아래는 JavaScript와 HTML을 사용하는 미디어 생성기입니다. 주요 목적은 버튼 클릭으로 한 번에 하나의 이미지를 표시하는 것이지만 모든 유형의 미디어를 표시 할 수 있습니다. 내 목표는 내 모든 미디어를 담을 수있는 빠른 로딩 페이지를 만드는 것이 었습니다.

//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>&nbsp;Random
    <br/><label><input type="radio" name="modes" id="mode2"/></label>&nbsp;Old&nbsp;-&nbsp;New
    <br/><label><input type="radio" name="modes" id="mode3"/></label>&nbsp;New&nbsp;-&nbsp;Old
  </form>

  <div align="right">
    <form id="categories" align="right">
      Video<label>&nbsp;<input type="radio" name="thing" id="videoCheck"/></label><br/>
      Audio<label>&nbsp;<input type="radio" name="thing" id="audioCheck"/></label><br/>
      Photo<label>&nbsp;<input type="radio" name="thing" id="photoCheck"/></label><br/>
      Text<label>&nbsp;<input type="radio" name="thing" id="textCheck"/></label>
    </form>
  </div>
</body>

참고할 몇 가지 사항 ...

  • 가장 어린 것이 맨 위에 있고 가장 오래된 것이 맨 아래에있는 JavaScript 배열을 구성합니다 (날짜 포함, 다음과 같이 표시됩니다).

    oddDate = ['Oct. 1', 'Oct. 2', 'Oct. 3', 'Oct. 4', 'Oct. 5']; 
    
  • 임의 모드는 의사 임의 이며 하나를 반복하기 전에 모든 배열 항목을 한 번 표시하도록 설계되었습니다.

  • old-new 및 new-old 모드는 어레이를 통해 각각 위에서 아래로 및 아래 에서 위로 이동합니다 .

  • 각 모드와 카테고리는 다른 모드로 변경할 때 그 자리를 저장합니다. 예를 들어, 이전 모드가 켜져 있고 텍스트 범주의 항목 3 에 있다고 가정 해 보겠습니다 . 사진 범주로 전환하고 배열을 약간 살펴본 다음 텍스트 범주로 돌아갑니다. 이전에 중단 한 다음 항목 (예 : 항목 4)이 표시 됩니다. 세 가지 모드 사이를 전환 할 때도 마찬가지입니다. 그들은 모두 서로 독립적입니다. 이것은 내가 유지하고 싶은 것입니다.

  • 한 가지 관심사 는 배열에 항목을 계속 추가함에 따라 생성기와 페이지가 점점 느려지는 것입니다. 그러나 이것이 합법적인지 확실하지 않습니다. 라이브 버전에서는 각 배열에 500 개 이상의 항목이 있으며 시간이 지남에 따라 더 많은 항목이 추가됩니다.

답변

2 SᴀᴍOnᴇᴌᴀ Oct 08 2020 at 03:22

전반적인 피드백

이 코드는 "오래된-새"의 의미가 역전 된 것처럼 보이지만 수용 가능하게 작동하는 것 같습니다.

메모의 첫 번째 글 머리 기호는 다음과 같습니다.

  • 가장 어린 것이 맨 위에 있고 가장 오래된 것이 맨 아래에있는 JavaScript 배열을 구성합니다 (날짜 포함 : oddDate = [ 'Oct. 1', 'Oct. 2', 'Oct. 3', 'Oct. 4 ', '10 월 5 일'];)

세 번째 글 머리 기호는 다음과 같습니다.

  • old-new 및 new-old 모드는 어레이를 통해 각각 위에서 아래로 및 아래 에서 위로 이동합니다 .

가장 오래된이 있었다 경우 이후 즉, 모순 보인다 하단 후 오래된 새로운 정렬은 배열의 끝에서 시작해야한다.

JavaScript 코드는 특히 함수 newThing()뿐만 아니라 변수 이름 에서 매우 반복적으로 보입니다 . 검토 후 나중에 설명 할 몇 가지 변경 사항을 권장합니다.

리뷰

자바 스크립트

변수 선언

이 코드는 스프레드 구문 과 같은 ECMAScript-2015 (AKA ES-6)에 특정한 일부 기능을 사용 합니다 . ES6 변수를 사용 const하여 let변수의 범위를 제한하고 버그를 방지 하는 것이 좋습니다 . 주 const평균 불변성을하지 않지만, 이러한 변수가 될 수 없습니다 오히려 것을 재 할당.

전역 변수

코드는 id 속성 에서 암시 적으로 생성 된 변수를 사용하여 DOM 요소를 참조합니다.

if(mode1.checked && (videoCheck.checked || audioCheck.checked || photoCheck.checked || textCheck.checked)) {

JavaScript 코드를 단위 테스트하려는 경우 어려울 수 있습니다.

입력 라벨

모든 라디오 입력은 입력에 포함되어 <label>있어 접근성 (예 : 화면 판독기, 사용자가 레이블을 클릭하여 입력에 초점을 맞추거나 활성화하는 기능)이 좋지만 각 입력 옆의 텍스트 는 레이블 내에 있지 않습니다 . 입력이 유일한 것이라면 레이블을 갖는 것은 무의미 해 보입니다.

HTML

인라인 이벤트 핸들러

이 코드는 HTML 코드 내에 이벤트 핸들러를 설정합니다.

<button onclick="newThing()">New Thing</button>

JavaScript 내에 이벤트 핸들러를 등록하는 것이 좋습니다 (예 newButton.addEventListener: 여러 가지 이유로 사용 :

  1. 로직은 마크 업과 분리 될 수 있습니다. 여러 팀원이 프로젝트에서 작업 한 경우 하나는 JavaScript에서 작업하고 다른 하나는 HTML에서 독립적으로 작업 할 수 있습니다.
  2. 이러한 핸들러는 이상한 동작을 유발할 수있는 전역 네임 스페이스를 오염시킬 수 있습니다 .

자식 요소 정렬

<div>요소는 가지고 align="center"와 align="right". 더 이상 사용되지 않는 HTML 4 속성으로 보이며 더 이상 HTML 5에서 지원되지 않습니다. 이는 CSS 규칙으로 변환 될 수 있습니다 . 참고 text-align블록 용기에 적용 1 . 등의 이미지, 비디오, 같은 센터 인라인 요소에 로 설정 될 필요가 와 세트로 .displayblockmarginauto

여러 양식 요소

두 개의 개별 <form>요소가 있습니다. 둘은 모든 요소를 ​​포함하는 단일 양식으로 결합 될 수 있습니다.

코드 단순화

위의 리뷰 포인트에서 제안한 사항과 함께 다음 변경 사항을 사용하여 코드 길이를 크게 줄일 수 있습니다.

  • 현재 색인을 포함 할 수있는 객체에 옵션을 넣고 객체를 객체의 속성으로 만듭니다. 여기서 속성 이름 (예 : 키)이 사물의 유형입니다.

      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
        },
      }
    
  • 대신에 사용하는 id라디오 버튼의 속성을 그냥 줄 value속성

  • 다음을 통해 양식 요소 참조 document.forms.elements

  • 다음을 통해 선택되는 라디오 버튼 결정 RadioNodeList.value

  • 사물 의 표시를 위해 요소를 사용합니다 .

  • 용도 클래스를 모드에 따라 항목을 얻을 방법과 함께, 인덱스를 캡슐화

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" />&nbsp;Random</label>
  <br /><label><input type="radio" name="mode" value="forward" />&nbsp;Old&nbsp;-&nbsp;New</label>
  <br /><label><input type="radio" name="mode" value="reverse" />&nbsp;New&nbsp;-&nbsp;Old</label>
  <div class="right">
    <label>Video&nbsp;<input type="radio" name="type" value="video" /></label><br />
    <label>Audio&nbsp;<input type="radio" name="type" value="audio" /></label><br />
    <label>Photo&nbsp;<input type="radio" name="type" value="photo" /></label><br />
    <label>Text&nbsp;<input type="radio" name="type" value="text" /></label>
  </div>
</form>