Hiển thị phương tiện với HTML và JavaScript

Oct 02 2020

Tôi có một trang web cá nhân mà tôi sử dụng để chia sẻ video và hình ảnh với bạn bè. Dưới đây là trình tạo đa phương tiện sử dụng JavaScript và HTML. Mục đích chính của nó là hiển thị một hình ảnh tại một thời điểm chỉ bằng một nút bấm, nhưng bất kỳ loại phương tiện nào cũng có thể được hiển thị. Mục tiêu của tôi là tạo một trang tải nhanh để chứa tất cả các phương tiện của tôi.

//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>

Một vài điều cần lưu ý ...

  • Tôi sắp xếp các mảng JavaScript với mảng nhỏ nhất ở trên cùng và già nhất ở dưới cùng (với ngày tháng, nó sẽ giống như sau:

    oddDate = ['Oct. 1', 'Oct. 2', 'Oct. 3', 'Oct. 4', 'Oct. 5']; 
    
  • Chế độ ngẫu nhiên là giả ngẫu nhiên và được thiết kế để hiển thị tất cả các mục của mảng một lần trước khi lặp lại một.

  • Chế độ cũ-mới và mới-cũ lần lượt di chuyển qua các mảng từ trên xuống dưới và từ dưới lên trên .

  • Mỗi chế độ và danh mục sẽ lưu vị trí của nó khi bạn thay đổi sang một chế độ khác. Ví dụ: giả sử bạn đang bật chế độ cũ-mới và đang ở mục 3 của danh mục văn bản. Bạn chuyển sang thể loại ảnh, chạy qua mảng một chút rồi quay lại thể loại văn bản. Nó sẽ hiển thị mục tiếp theo từ nơi bạn đã dừng trước đó - tức là mục 4 . Điều tương tự cũng có thể nói đối với việc chuyển đổi giữa ba chế độ; chúng đều độc lập với nhau. Đây là điều tôi muốn duy trì.

  • Một mối quan tâm là trình tạo và trang sẽ ngày càng chậm hơn khi tôi tiếp tục thêm nhiều mục hơn vào các mảng, nhưng tôi không chắc liệu điều này có hợp pháp hay không. Trong phiên bản trực tiếp, có hơn 500 mục trong mỗi mảng và nhiều hơn nữa sẽ được thêm vào theo thời gian.

Trả lời

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

Phản hồi chung

Mã này có vẻ hoạt động được, mặc dù ngữ nghĩa của "cũ - mới" dường như bị đảo ngược.

Dấu đầu dòng đầu tiên trong ghi chú nêu rõ:

  • Tôi sắp xếp các mảng JavaScript với mảng nhỏ nhất ở trên cùng và già nhất ở dưới cùng (với ngày tháng, nó sẽ giống như sau: retailDate = ['1 tháng 10', '2 tháng 10', '3 tháng 10', 'tháng 10. 4 ',' ngày 5 tháng 10 '];)

Tuy nhiên, gạch đầu dòng thứ ba cho biết:

  • Chế độ cũ-mới và mới-cũ lần lượt di chuyển qua các mảng từ trên xuống dưới và từ dưới lên trên .

Điều đó có vẻ mâu thuẫn, vì nếu cái cũ nhất ở dưới cùng thì việc sắp xếp cũ-mới sẽ bắt đầu ở cuối mảng.

Mã JavaScript có vẻ rất lặp lại - đặc biệt là trong hàm newThing()mà còn cả tên biến. Tôi muốn giới thiệu một số thay đổi được mô tả sau, sau khi xem xét.

Ôn tập

Javascript

Khai báo biến

Mã sử ​​dụng một số tính năng dành riêng cho ECMAScript-2015 (AKA ES-6) như cú pháp lây lan . Với các biến ES6, bạn nên sử dụng constvà lethạn chế phạm vi của các biến và tránh lỗi . Lưu ý rằng điều constđó không có nghĩa là bất biến, mà đúng hơn là một biến như vậy không thể được gán lại.

Biến toàn cục

Mã tham chiếu đến các phần tử DOM bằng cách sử dụng các biến được tạo ngầm từ các thuộc tính id - ví dụ:

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

Nếu bạn muốn kiểm tra đơn vị mã JavaScript thì điều này có thể gây khó khăn.

Nhãn đầu vào

Có vẻ như tất cả các đầu vào vô tuyến đều được chứa bởi các <label>đầu vào, điều này tốt cho khả năng truy cập (ví dụ: trình đọc màn hình, khả năng người dùng nhấp vào nhãn để lấy tiêu điểm / kích hoạt đầu vào) tuy nhiên văn bản bên cạnh mỗi đầu vào không nằm trong nhãn. Có vẻ như vô nghĩa để có một nhãn nếu đầu vào là thứ duy nhất trong đó.

HTML

Trình xử lý sự kiện nội tuyến

Mã thiết lập các trình xử lý sự kiện trong mã HTML:

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

Tốt hơn là đăng ký các trình xử lý sự kiện trong JavaScript (ví dụ: sử dụng newButton.addEventListenervì nhiều lý do:

  1. Logic có thể được tách biệt khỏi đánh dấu - nếu nhiều thành viên cùng làm việc trong dự án thì một người có thể làm việc trên JavaScript trong khi người kia có thể làm việc trên HTML độc lập.
  2. Những trình xử lý như vậy có thể gây ô nhiễm không gian tên toàn cầu, dẫn đến hành vi lạ .

Căn chỉnh các phần tử con

Các <div>phần tử có align="center"và align="right". Đó dường như là thuộc tính HTML 4 không được dùng nữa và không còn được hỗ trợ trong HTML 5. Thuộc tính này có thể được chuyển đổi thành quy tắc CSS . Lưu ý text-alignáp dụng cho vùng chứa khối 1 . Để căn giữa các phần tử nội tuyến như hình ảnh, video, v.v. , displaybạn cần phải đặt blockvà marginđặt thànhauto .

Nhiều phần tử biểu mẫu

Có hai <form>yếu tố riêng biệt . Cả hai có thể được kết hợp thành một dạng duy nhất chứa tất cả các phần tử.

Đơn giản hóa mã

Những thay đổi sau, cùng với đề xuất từ ​​các điểm đánh giá ở trên có thể được sử dụng để giảm đáng kể độ dài của mã:

  • đặt các tùy chọn vào một đối tượng có thể chứa chỉ mục hiện tại và làm cho đối tượng trở thành thuộc tính của một đối tượng trong đó tên thuộc tính (ví dụ: khóa) là kiểu của đối tượng - ví dụ:

      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
        },
      }
    
  • thay vì sử dụng idcác thuộc tính cho các nút radio, chỉ cần cung cấp cho chúng valuecác thuộc tính

  • tham chiếu các phần tử biểu mẫu qua document.forms.elements

  • xác định nút radio nào được chọn qua RadioNodeList.value

  • sử dụng một <output>phần tử để hiển thị sự vật .

  • sử dụng một lớp để đóng gói các chỉ mục, cùng với các phương thức để lấy một mục dựa trên chế độ

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>