|
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:
- Bỏ dấu tiếng Việt
- Chuyển chữ viết hoa thành viết thường
- Chỉ lấy các ký tự là số và chữ cho vào hash fragment và ID
- 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; }
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é.