Sửa lỗi table of contents trong Template Median UI 1.6

Sửa lỗi table of contents trong Template Median UI

Template Median UI tác giả viết để sử dụng cho ngôn ngữ là tiếng Anh hoặc các chữ viết không có dấu. Đấy chính là lý do với các chữ kiểu Ả Rập hoặc các ngôn ngữ khác mà mình cũng không biết hết có hẳn 1 bản riêng là RTL, đấy là bản dành riêng cho chữ viết ngược.

Còn với tiếng Việt Nam thì chữ lại có dấu, chính vì vậy table of contents sẽ bị một số lỗi như sau:

Các lỗi của table of contents trong Template Median

Lỗi 1: Hash fragment của link và ID các thẻ H1 - H6 không chuẩn định dạng dẫn tới không tốt cho SEO.

Ví dụ trong thẻ H2 "Sửa lỗi table of contents" bên dưới, hash fragment và ID nó sẽ bị lỗi như sau:

https://www.thucblog.com/sua-loi-table-of-contents.html#Sửa_lỗi_table_of_contents

Còn chuẩn định dạng thì nó phải là như thế này:

https://www.thucblog.com/sua-loi-table-of-contents.html#sua_loi_table_of_contents

Các bạn kiểm tra xem Blog của mình đang dùng Median UI có đúng bị lỗi như vậy không?

Lỗi 2: Trong Blogsport mình không hiểu sao rõ ràng trong code không có dấu cách nhưng trên bài viết đôi khi nó lại tự thêm dấu cách ở đầu hoặc cuối câu, và dẫn tới hash fragment và ID bị lỗi như sau:

https://www.thucblog.com/sua-loi-table-of-contents.html#_Sửa_lỗi_table_of_contents_

Bạn thấy nó thừa cái dấu _ ở đầu và cuối là do code nó đọc được ở đấy có dấu cách.

Lỗi 3: Nó không bỏ các ký tự đặc biệt trước khi tạo hash fragment và ID.

https://www.thucblog.com/sua-loi-table-of-contents.html#Có_nên_sửa_lỗi_table_of_contents?

Bạn thấy nó lấy luôn cả dấu hỏi trông rất ngớ ngẩn.

Sửa lỗi table of contents

Với những lỗi ngớ ngẩn như trên thì chúng ta cần fix lại cho chuẩn hơn gồm những vấn đề sau:

  1. Bỏ dấu tiếng Việt
  2. Chuyển chữ viết hoa thành viết thường
  3. Chỉ lấy các ký tự là số và chữ cho vào hash fragment và ID
  4. Bỏ các ký tự dấu cách bị sinh ra ở đầu hoặc cuối câu

Các bạn tìm đến đoạn code sau:

<script>
class TableOfContents { constructor({ from, to }) { this.fromElement = from; this.toElement = to; this.headingElements = this.fromElement.querySelectorAll("h1, h2, h3, h4, h5, h6"); this.tocElement = document.createElement("div"); }; getMostImportantHeadingLevel() { let mostImportantHeadingLevel = 6; for (let i = 0; i < this.headingElements.length; i++) { let headingLevel = TableOfContents.getHeadingLevel(this.headingElements[i]); mostImportantHeadingLevel = (headingLevel < mostImportantHeadingLevel) ? headingLevel : mostImportantHeadingLevel; } return mostImportantHeadingLevel; }; static generateId(headingElement) { return headingElement.textContent.replace(/\s+/g, "_"); }; static getHeadingLevel(headingElement) { switch (headingElement.tagName.toLowerCase()) { case "h1": return 1; case "h2": return 2; case "h3": return 3; case "h4": return 4; case "h5": return 5; case "h6": return 6; default: return 1; } }; generateToc() { let currentLevel = this.getMostImportantHeadingLevel() - 1, currentElement = this.tocElement; for (let i = 0; i < this.headingElements.length; i++) { let headingElement = this.headingElements[i], headingLevel = TableOfContents.getHeadingLevel(headingElement), headingLevelDifference = headingLevel - currentLevel, linkElement = document.createElement("a"); if (!headingElement.id) { headingElement.id = TableOfContents.generateId(headingElement); } linkElement.href = `#${headingElement.id}`; linkElement.textContent = headingElement.textContent; if (headingLevelDifference > 0) { for (let j = 0; j < headingLevelDifference; j++) { let listElement = document.createElement("ol"), listItemElement = document.createElement("li"); listElement.appendChild(listItemElement); currentElement.appendChild(listElement); currentElement = listItemElement; } currentElement.appendChild(linkElement); } else { for (let j = 0; j < -headingLevelDifference; j++) { currentElement = currentElement.parentNode.parentNode; } let listItemElement = document.createElement("li"); listItemElement.appendChild(linkElement); currentElement.parentNode.appendChild(listItemElement); currentElement = listItemElement; } currentLevel = headingLevel; } this.toElement.appendChild(this.tocElement.firstChild); } }</script>

Xóa nó đi và thay thế thành

<script type='text/javascript'>
    //<![CDATA[
    class TableOfContents {
    constructor({ from, to }) {
      this.fromElement = from;
      this.toElement = to;
      this.headingElements = this.fromElement.querySelectorAll("h1, h2, h3, h4, h5, h6");
      this.tocElement = document.createElement("div");
    }

    static removeVietnameseAccent(str) {
      return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
    }

    static generateId(headingElement) {
      const unaccentedText = TableOfContents.removeVietnameseAccent(headingElement.textContent)
        .replace(/đ/g, 'd')
        .toLowerCase()
        .replace(/[^\w\s]/g, '')
        .trim()
        .replace(/\s+/g, "_");

      return unaccentedText;
    }

    static getHeadingLevel(headingElement) {
      switch (headingElement.tagName.toLowerCase()) {
        case "h1": return 1;
        case "h2": return 2;
        case "h3": return 3;
        case "h4": return 4;
        case "h5": return 5;
        case "h6": return 6;
        default: return 1;
      }
    }

    generateToc() {
      let currentLevel = this.getMostImportantHeadingLevel() - 1,
          currentElement = this.tocElement;

      for (let i = 0; i < this.headingElements.length; i++) {
        const headingElement = this.headingElements[i],
            headingLevel = TableOfContents.getHeadingLevel(headingElement),
            headingLevelDifference = headingLevel - currentLevel,
            linkElement = document.createElement("a");

        if (!headingElement.id) {
          headingElement.id = TableOfContents.generateId(headingElement);
        }

        linkElement.href = `#${headingElement.id}`;
        linkElement.textContent = headingElement.textContent;

        if (headingLevelDifference > 0) {
          for (let j = 0; j < headingLevelDifference; j++) {
            const listElement = document.createElement("ol"),
                listItemElement = document.createElement("li");
            listElement.appendChild(listItemElement);
            currentElement.appendChild(listElement);
            currentElement = listItemElement;
          }
          

...

Nội dung tiếp theo đã bị ẩn bởi admin

Đoạn code trên đang bị thiếu, làm theo hướng dẫn sau để lấy mật khẩu mở nội dung nhé.

Bạn vào Google tìm từ khóa và tìm site rồi click giúp mình để lấy password nhé, pass ở cuối bài viết phần Countdown.

          currentElement.appendChild(linkElement);
        } else {
          for (let j = 0; j < -headingLevelDifference; j++) {
            currentElement = currentElement.parentNode.parentNode;
          }
          const listItemElement = document.createElement("li");
          listItemElement.appendChild(linkElement);
          currentElement.parentNode.appendChild(listItemElement);
          currentElement = listItemElement;
        }
        currentLevel = headingLevel;
      }
      this.toElement.appendChild(this.tocElement.firstChild);
    }

    getMostImportantHeadingLevel() {
      let mostImportantHeadingLevel = 6;
      for (let i = 0; i < this.headingElements.length; i++) {
        const headingLevel = TableOfContents.getHeadingLevel(this.headingElements[i]);
        mostImportantHeadingLevel = (headingLevel < mostImportantHeadingLevel) ? headingLevel : mostImportantHeadingLevel;
      }
      return mostImportantHeadingLevel;
    }
  }
    //]]>
</script>

Ok bây giờ lưu lại và kiểm tra xem nó đã hết lỗi như Blog của mình chưa nhé.

Đơn giản là nó đã phức tạp như vậy rồi

3 nhận xét

  1. bác ơi, làm thế nào để tạo ra cái phần mà nội dung ẩn có mật khẩu bảo vệ đấy ạ
    1. Blogspot code toàn dùng javascript nên có gì là giấu được đâu, bạn hỏi thế khó quá.
    2. Kkk thanks anh
© Blogger Thức Nguyễn. All rights reserved.