Tại sao JavaScript của tôi không hoạt động trong HTML?

Nếu JavaScript không hoạt động, làm mới hoặc tải trong trình duyệt Google Chrome, hướng dẫn này sẽ giúp bạn khắc phục sự cố. Sự cố này có thể xảy ra trên một trang web cụ thể hoặc tất cả các trang web. Dù bằng cách nào, bạn có thể thoát khỏi vấn đề này với sự trợ giúp của các mẹo và thủ thuật này

Tại sao JavaScript của tôi không hoạt động trong HTML?

Lý do chính khiến Chrome không thể tải JavaScript là do bạn vô tình hoặc cố ý vô hiệu hóa JavaScript. Có hơn năm cài đặt cần được bật mọi lúc để cho phép Chrome tải JavaScript trên bất kỳ trang web nào. Bài viết này giải thích lần lượt tất cả các cài đặt mà bạn cần kiểm tra để sử dụng JavaScript trên bất kỳ trang web nào

Chrome JavaScript không hoạt động, làm mới hoặc tải

Nếu Chrome JavaScript không hoạt động, làm mới hoặc tải, hãy làm theo các bước sau

  1. Bật JavaScript trong Chrome
  2. Kích hoạt JavaScript cho một trang web cụ thể
  3. Xác minh cài đặt Chính sách nhóm
  4. Kiểm tra các giá trị Registry
  5. Tắt tiện ích mở rộng

Để tìm hiểu thêm về các bước này, hãy tiếp tục đọc

1] Bật JavaScript trong Chrome

Tại sao JavaScript của tôi không hoạt động trong HTML?

Ngày nay, hầu hết tất cả các trang web đều chứa JavaScript, một ngôn ngữ lập trình kịch bản chạy trên trình duyệt web của khách truy cập. Nó làm cho các trang web hoạt động cho các mục đích cụ thể và nếu bị vô hiệu hóa vì một số lý do, nội dung hoặc chức năng của trang web có thể bị hạn chế hoặc không khả dụng. Tại đây, bạn có thể tìm thấy hướng dẫn về cách bật (kích hoạt) JavaScript trong năm trình duyệt được sử dụng phổ biến nhất

Đặt tập lệnh ở dưới cùng của phần tử sẽ cải thiện tốc độ hiển thị, vì việc giải thích tập lệnh làm chậm màn hình


JavaScript bên ngoài

Tập lệnh cũng có thể được đặt trong các tệp bên ngoài

tệp bên ngoài. myScript. js

hàm myFunction() {
tài liệu. getElementById("bản trình diễn"). innerHTML = "Đoạn đã thay đổi. “;
}

Tập lệnh bên ngoài là thực tế khi cùng một mã được sử dụng trong nhiều trang web khác nhau

Các tệp JavaScript có phần mở rộng tệp. js

Để sử dụng tập lệnh bên ngoài, hãy đặt tên của tệp tập lệnh trong thuộc tính (nguồn) src của

Tôi thường cấu trúc các dự án của mình như thế này

sử dụng điều này để kiểm tra trước khi tôi bắt đầu bất kỳ phát triển nào, theo cách đó tôi biết mọi thứ được kết nối

HTML



  
    
    
    Sample Project Folder Demo
    
  
  
    Sample Project Folder Demo
    
Tại sao JavaScript của tôi không hoạt động trong HTML?

CSS

body {
  background-color: red;
}

JavaScript

console.log('script.js says "I\'m here"');

cung cấp cho cái này

Bây giờ chúng ta sẽ xem xét các sự cố JavaScript phổ biến trên nhiều trình duyệt và cách khắc phục chúng. Điều này bao gồm thông tin về cách sử dụng các công cụ dành cho nhà phát triển trình duyệt để theo dõi và khắc phục sự cố, cách sử dụng Polyfill và thư viện để khắc phục sự cố, giúp các tính năng JavaScript hiện đại hoạt động trong các trình duyệt cũ hơn, v.v.

điều kiện tiên quyết. Quen thuộc với các ngôn ngữ HTML, CSS và JavaScript cốt lõi; . Khách quan. Để có thể chẩn đoán các sự cố phổ biến trên nhiều trình duyệt JavaScript và sử dụng các công cụ và kỹ thuật thích hợp để khắc phục chúng

Trong lịch sử, JavaScript đã gặp khó khăn với các vấn đề tương thích giữa nhiều trình duyệt - trở lại những năm 1990, các lựa chọn trình duyệt chính khi đó (Internet Explorer và Netscape) đã triển khai tập lệnh theo các hương vị ngôn ngữ khác nhau (Netscape có JavaScript, IE có JScript và cũng cung cấp VBScript dưới dạng

Những vấn đề không tương thích như vậy vẫn tồn tại cho đến đầu những năm 2000, vì các trình duyệt cũ vẫn đang được sử dụng và vẫn cần được hỗ trợ. Đây là một trong những lý do chính khiến các thư viện như jQuery ra đời — để loại bỏ những khác biệt trong việc triển khai trình duyệt (e. g. xem đoạn mã trong ) để các nhà phát triển chỉ phải viết một đoạn mã đơn giản (xem

function showHeroes(jsonObj) {
  let heroes = jsonObj['members'];

  for (const hero of heroes) {
    // …
   }

   // …
 }
7). jQuery (hoặc bất kỳ thư viện nào bạn đang sử dụng) sau đó sẽ xử lý các khác biệt trong nền, vì vậy bạn không cần phải

Mọi thứ đã được cải thiện đáng kể kể từ đó;

Ngày nay, hầu hết các sự cố JavaScript trên nhiều trình duyệt đều được nhìn thấy

  • Khi mã đánh hơi trình duyệt kém chất lượng, mã phát hiện tính năng và việc sử dụng tiền tố của nhà cung cấp chặn trình duyệt chạy mã thì chúng vẫn có thể sử dụng bình thường
  • Khi các nhà phát triển sử dụng các tính năng JavaScript mới/mới, API Web hiện đại, v.v. ) trong mã của họ và thấy rằng các tính năng như vậy không hoạt động trong các trình duyệt cũ hơn

Chúng ta sẽ khám phá tất cả những vấn đề này và nhiều vấn đề khác bên dưới

Như chúng tôi đã nói trong phần về HTML/CSS, bạn nên đảm bảo rằng mã của mình đang hoạt động bình thường, trước khi tiếp tục tập trung vào các vấn đề liên trình duyệt. Nếu bạn chưa quen với kiến ​​thức cơ bản về Khắc phục sự cố JavaScript, bạn nên nghiên cứu bài viết đó trước khi tiếp tục. Có một số vấn đề phổ biến về JavaScript mà bạn sẽ muốn lưu ý, chẳng hạn như

  • Các vấn đề logic và cú pháp cơ bản (một lần nữa, hãy xem Khắc phục sự cố JavaScript)
  • Đảm bảo các biến, v.v. được xác định trong phạm vi chính xác và bạn không gặp phải xung đột giữa các mục được khai báo ở những nơi khác nhau (xem phần )
  • Nhầm lẫn về điều này, về phạm vi mà nó áp dụng và do đó, nếu giá trị của nó là những gì bạn dự định. Bạn có thể đọc để giới thiệu nhẹ;
  • Sử dụng sai các hàm bên trong các vòng lặp lặp lại với một biến toàn cục (nói chung là "sai phạm vi"). Ví dụ, trong vòng lặp xấu. html (xem mã nguồn), chúng tôi lặp qua 10 lần lặp lại bằng cách sử dụng một biến được xác định bằng
    let requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
    let request = new XMLHttpRequest();
    request.open('GET', requestURL);
    request.send();
    
    let superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    
    0, mỗi lần tạo một đoạn văn và thêm trình xử lý sự kiện onclick vào đoạn văn đó. Khi được nhấp vào, chúng tôi muốn mỗi cái hiển thị một thông báo cảnh báo có chứa số của nó (giá trị của
    let requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
    let request = new XMLHttpRequest();
    request.open('GET', requestURL);
    request.send();
    
    let superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    
    1 tại thời điểm nó được tạo). Thay vào đó, tất cả chúng đều báo cáo
    let requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
    let request = new XMLHttpRequest();
    request.open('GET', requestURL);
    request.send();
    
    let superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    
    1 là 11 — bởi vì vòng lặp
    let requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
    let request = new XMLHttpRequest();
    request.open('GET', requestURL);
    request.send();
    
    let superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    
    3 thực hiện tất cả các bước lặp của nó trước khi các hàm lồng nhau được gọi

    Ghi chú. Giải pháp đơn giản nhất là khai báo biến lặp với

    let requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
    let request = new XMLHttpRequest();
    request.open('GET', requestURL);
    request.send();
    
    let superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    
    4 thay vì
    let requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
    let request = new XMLHttpRequest();
    request.open('GET', requestURL);
    request.send();
    
    let superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    
    0—giá trị của
    let requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
    let request = new XMLHttpRequest();
    request.open('GET', requestURL);
    request.send();
    
    let superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    
    1 được liên kết với hàm sau đó là duy nhất cho mỗi lần lặp. Thật không may, điều này không hoạt động chính xác với IE11, đó là lý do tại sao chúng tôi chưa sử dụng phương pháp này trong vòng lặp "tốt"

    Nếu bạn muốn điều này hoạt động chính xác, bạn có thể xác định một hàm để thêm trình xử lý một cách riêng biệt, gọi nó trên mỗi lần lặp lại và chuyển cho nó giá trị hiện tại của
    let requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
    let request = new XMLHttpRequest();
    request.open('GET', requestURL);
    request.send();
    
    let superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    
    7 và
    let requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
    let request = new XMLHttpRequest();
    request.open('GET', requestURL);
    request.send();
    
    let superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    
    1 mỗi lần (hoặc một cái gì đó tương tự). Xem vòng lặp tốt. html (cũng xem mã nguồn) để biết phiên bản hoạt động
  • Đảm bảo rằng các hoạt động không đồng bộ đã được trả về trước khi thử sử dụng các giá trị mà chúng trả về. Ví dụ: kiểm tra để đảm bảo yêu cầu đã hoàn tất và phản hồi đã được trả về trước khi cố gắng sử dụng phản hồi cho bất kỳ điều gì. Loại hoạt động này đã được thực hiện dễ dàng hơn bằng cách giới thiệu Lời hứa cho ngôn ngữ JavaScript

Ghi chú. Mã JavaScript lỗi. 10 lỗi phổ biến nhất mà các nhà phát triển JavaScript mắc phải có một số cuộc thảo luận thú vị về những lỗi phổ biến này và hơn thế nữa

Cũng giống như , bạn có thể đảm bảo mã JavaScript có chất lượng tốt hơn, ít lỗi hơn bằng cách sử dụng trình nói dối, chỉ ra lỗi và cũng có thể gắn cờ cảnh báo về các phương pháp không phù hợp, v.v. và được tùy chỉnh để chặt chẽ hơn hoặc thoải mái hơn trong báo cáo lỗi/cảnh báo của họ. JavaScript/ECMAScript linters chúng tôi khuyên dùng là JSHint và ESLint;

Trực tuyến

Trang chủ JSHint cung cấp một trình nói dối trực tuyến, cho phép bạn nhập mã JavaScript ở bên trái và cung cấp kết quả ở bên phải, bao gồm số liệu, cảnh báo và lỗi

Tại sao JavaScript của tôi không hoạt động trong HTML?

Plugin chỉnh sửa mã

Sẽ không thuận tiện lắm khi phải sao chép và dán mã của bạn vào một trang web để kiểm tra tính hợp lệ của nó nhiều lần. Những gì bạn thực sự muốn là một kẻ nói dối sẽ phù hợp với quy trình làm việc tiêu chuẩn của bạn với ít rắc rối nhất. Nhiều trình chỉnh sửa mã có plugin linter, ví dụ trình chỉnh sửa mã Atom của GitHub có sẵn plugin JSHint

Để cài đặt nó

  1. Cài đặt Atom (nếu bạn chưa cài đặt phiên bản cập nhật) — tải xuống từ trang Atom được liên kết ở trên
  2. Chuyển đến hộp thoại Preferences… của Atom (e. g. bằng cách Chọn Atom > Preferences… trên Mac, hoặc File > Preferences… trên Windows/Linux) và chọn tùy chọn Install trong menu bên trái
  3. Trong trường văn bản Tìm kiếm gói, nhập "jslint" và nhấn Enter/Return để tìm kiếm các gói liên quan đến xơ vải
  4. Bạn sẽ thấy một gói có tên là lint ở đầu danh sách. Cài đặt cái này trước (bằng cách sử dụng nút Cài đặt), vì các phần mềm khác dựa vào nó để hoạt động. Sau đó, cài đặt plugin linter-jshint
  5. Sau khi các gói cài đặt xong, hãy thử tải lên một tệp JavaScript. bạn sẽ thấy bất kỳ sự cố nào được đánh dấu bằng các vòng tròn màu lục (đối với cảnh báo) và màu đỏ (đối với lỗi) bên cạnh số dòng và một bảng điều khiển riêng biệt ở dưới cùng cung cấp số dòng, thông báo lỗi và đôi khi là các giá trị được đề xuất hoặc các bản sửa lỗi khác

Tại sao JavaScript của tôi không hoạt động trong HTML?
Các trình chỉnh sửa phổ biến khác có sẵn các gói linting tương tự. Ví dụ: xem phần "Plugin cho trình soạn thảo văn bản và IDE" trên trang cài đặt JSHint

sử dụng khác

Có nhiều cách khác để sử dụng xơ vải như vậy;

Điều đáng nói là sử dụng dòng lệnh — bạn có thể cài đặt các công cụ này dưới dạng tiện ích dòng lệnh (có sẵn qua CLI — giao diện dòng lệnh) bằng cách sử dụng npm (Trình quản lý gói nút — trước tiên bạn sẽ phải cài đặt NodeJS). Ví dụ: lệnh sau cài đặt JSHint

npm install -g jshint

Sau đó, bạn có thể trỏ các công cụ này vào các tệp JavaScript mà bạn muốn lint chẳng hạn

Tại sao JavaScript của tôi không hoạt động trong HTML?

Bạn cũng có thể sử dụng các công cụ này với một công cụ xây dựng/chạy tác vụ như Gulp hoặc Webpack để tự động lint JavaScript của bạn trong quá trình phát triển. (xem ở bài viết sau. ) Xem phần tích hợp ESLint để biết các tùy chọn ESLint; . g. Trình tải JSHint cho Webpack

Ghi chú. ESLint cần thiết lập và cấu hình nhiều hơn một chút so với JSHint, nhưng nó cũng mạnh hơn

Các công cụ dành cho nhà phát triển trình duyệt có nhiều tính năng hữu ích giúp gỡ lỗi JavaScript. Để bắt đầu, bảng điều khiển JavaScript sẽ báo lỗi trong mã của bạn

Tạo một bản sao cục bộ của ajax bị hỏng của chúng tôi. html ví dụ (cũng xem mã nguồn)

Nếu bạn nhìn vào bảng điều khiển, bạn sẽ thấy thông báo lỗi "Uncaught TypeError. không thể truy cập thuộc tính "độ dài", anh hùng không được xác định và số dòng được tham chiếu là 49. Nếu chúng ta xem mã nguồn, phần mã có liên quan là đây

function showHeroes(jsonObj) {
  let heroes = jsonObj['members'];

  for (const hero of heroes) {
    // …
   }

   // …
 }

Vì vậy, mã bị lỗi ngay khi chúng tôi cố gắng truy cập thuộc tính của

let requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
let request = new XMLHttpRequest();
request.open('GET', requestURL);
request.send();

let superHeroes = request.response;
populateHeader(superHeroes);
showHeroes(superHeroes);
9 (như bạn có thể mong đợi, được coi là một đối tượng JSON). Điều này được cho là được tìm nạp từ tệp
console.log('Response value: ', superHeroes);
0 bên ngoài bằng lệnh gọi XMLHttpRequest sau

let requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
let request = new XMLHttpRequest();
request.open('GET', requestURL);
request.send();

let superHeroes = request.response;
populateHeader(superHeroes);
showHeroes(superHeroes);

Nhưng điều này không thành công

API bảng điều khiển

Bạn có thể đã biết điều gì sai với mã này, nhưng hãy khám phá nó thêm một chút để chỉ ra cách bạn có thể điều tra điều này. Để bắt đầu, có API bảng điều khiển cho phép mã JavaScript tương tác với bảng điều khiển JavaScript của trình duyệt. Nó có sẵn một số tính năng, nhưng tính năng chính bạn sẽ sử dụng thường xuyên là

console.log('Response value: ', superHeroes);
1, in một thông báo tùy chỉnh tới bảng điều khiển

Hãy thử chèn dòng sau ngay bên dưới dòng 31 (được in đậm ở trên)

console.log('Response value: ', superHeroes);

Làm mới trang trong trình duyệt và bạn sẽ nhận được kết quả trong bảng điều khiển "Giá trị phản hồi. ", cùng với thông báo lỗi mà chúng tôi đã thấy trước đây

Đầu ra

console.log('Response value: ', superHeroes);
1 cho thấy đối tượng
console.log('Response value: ', superHeroes);
3 dường như không chứa bất kỳ thứ gì. Một vấn đề rất phổ biến với các yêu cầu không đồng bộ như thế này là khi bạn cố gắng làm điều gì đó với đối tượng
console.log('Response value: ', superHeroes);
4 trước khi nó thực sự được trả về từ mạng. Hãy khắc phục sự cố này bằng cách chạy mã sau khi sự kiện
console.log('Response value: ', superHeroes);
5 đã được kích hoạt — xóa dòng
console.log('Response value: ', superHeroes);
1 và cập nhật khối mã này

const superHeroes = request.response;
populateHeader(superHeroes);
showHeroes(superHeroes);

theo sau

request.onload = function() {
  let superHeroes = request.response;
  populateHeader(superHeroes);
  showHeroes(superHeroes);
}

Tóm lại, bất cứ khi nào một cái gì đó không hoạt động và một giá trị dường như không đúng với ý nghĩa của nó tại một số điểm trong mã của bạn, bạn có thể sử dụng

console.log('Response value: ', superHeroes);
1 để in nó ra và xem điều gì đang xảy ra

Sử dụng trình gỡ lỗi JavaScript

Thật không may, chúng tôi vẫn gặp lỗi tương tự — sự cố vẫn chưa biến mất. Hãy điều tra vấn đề này ngay bây giờ, sử dụng một tính năng tinh vi hơn của các công cụ dành cho nhà phát triển trình duyệt. trình gỡ lỗi JavaScript như nó được gọi trong Firefox

Ghi chú. Các công cụ tương tự có sẵn trong các trình duyệt khác;

Trong Firefox, tab Trình gỡ lỗi trông như sau

Tại sao JavaScript của tôi không hoạt động trong HTML?

  • Ở bên trái, bạn có thể chọn tập lệnh bạn muốn gỡ lỗi (trong trường hợp này, chúng tôi chỉ có một tập lệnh)
  • Bảng điều khiển trung tâm hiển thị mã trong tập lệnh đã chọn
  • Bảng điều khiển bên phải hiển thị các chi tiết hữu ích liên quan đến môi trường hiện tại - Điểm dừng, Callstack và Phạm vi hiện đang hoạt động

Tính năng chính của những công cụ như vậy là khả năng thêm các điểm dừng vào mã — đây là những điểm mà quá trình thực thi mã dừng lại và tại thời điểm đó, bạn có thể kiểm tra môi trường ở trạng thái hiện tại và xem điều gì đang xảy ra

Cùng bắt tay vào làm. Lỗi hiện đang được đưa ra ở dòng 51. Nhấp vào dòng số 51 trong bảng điều khiển trung tâm để thêm một điểm dừng cho nó (bạn sẽ thấy một mũi tên màu xanh lam xuất hiện trên đỉnh của nó). Bây giờ hãy làm mới trang (Cmd/Ctrl + R) — trình duyệt sẽ tạm dừng thực thi mã ở dòng 51. Lúc này, bên tay phải sẽ cập nhật để hiển thị một số thông tin rất hữu ích

Tại sao JavaScript của tôi không hoạt động trong HTML?

  • Trong Điểm ngắt, bạn sẽ thấy chi tiết về điểm dừng mà bạn đã đặt
  • Trong Ngăn xếp cuộc gọi, bạn sẽ thấy một vài mục - về cơ bản, đây là danh sách một loạt các chức năng đã được gọi để khiến chức năng hiện tại được gọi. Ở trên cùng, chúng ta có hàm
    console.log('Response value: ', superHeroes);
    
    8 mà chúng ta đang sử dụng, và thứ hai, chúng ta có hàm
    console.log('Response value: ', superHeroes);
    
    9, hàm này lưu trữ hàm xử lý sự kiện có chứa cuộc gọi đến
    console.log('Response value: ', superHeroes);
    
    8
  • Trong Phạm vi, bạn sẽ thấy phạm vi hiện đang hoạt động cho chức năng mà chúng tôi đang xem xét. Chúng tôi chỉ có ba —
    const superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    
    1,
    const superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    
    2 và
    const superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    
    3 (phạm vi toàn cầu). Mỗi phạm vi có thể được mở rộng để hiển thị giá trị của các biến bên trong phạm vi khi quá trình thực thi mã bị dừng

Chúng ta có thể tìm hiểu một số thông tin rất hữu ích tại đây

  1. Mở rộng phạm vi
    const superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    
    1 — từ đây bạn có thể thấy rằng biến anh hùng là
    const superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    
    5, cho biết rằng việc truy cập thuộc tính
    const superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    
    6 của
    let requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
    let request = new XMLHttpRequest();
    request.open('GET', requestURL);
    request.send();
    
    let superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    
    9 (dòng đầu tiên của hàm) không hoạt động
  2. Bạn cũng có thể thấy rằng biến
    let requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
    let request = new XMLHttpRequest();
    request.open('GET', requestURL);
    request.send();
    
    let superHeroes = request.response;
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    
    9 đang lưu trữ một chuỗi văn bản, không phải đối tượng JSON
  3. Khám phá thêm bên dưới ngăn xếp cuộc gọi, nhấp vào
    console.log('Response value: ', superHeroes);
    
    9 trong phần Ngăn xếp cuộc gọi. Chế độ xem sẽ cập nhật để hiển thị hàm
    request.onload = function() {
      let superHeroes = request.response;
      populateHeader(superHeroes);
      showHeroes(superHeroes);
    }
    
    0 trong bảng trung tâm và phạm vi của nó trong phần Phạm vi
  4. Nếu bạn mở rộng phạm vi
    console.log('Response value: ', superHeroes);
    
    9, bạn sẽ thấy rằng biến
    console.log('Response value: ', superHeroes);
    
    3 cũng là một chuỗi văn bản, không phải là một đối tượng. Điều này giải quyết nó - cuộc gọi
    request.onload = function() {
      let superHeroes = request.response;
      populateHeader(superHeroes);
      showHeroes(superHeroes);
    }
    
    3 của chúng tôi đang trả về JSON dưới dạng văn bản, không phải JSON

Chúng tôi muốn bạn thử tự khắc phục sự cố này. Để cung cấp cho bạn manh mối, bạn có thể yêu cầu đối tượng XMLHttpRequest trả về định dạng JSON một cách rõ ràng hoặc sau khi có phản hồi. Nếu bạn gặp khó khăn, hãy tham khảo ajax cố định của chúng tôi. ví dụ html

Ghi chú. Tab trình gỡ lỗi có nhiều tính năng hữu ích khác mà chúng tôi chưa thảo luận ở đây, chẳng hạn như các điểm dừng có điều kiện và biểu thức xem. Để biết thêm thông tin, hãy xem trang Trình gỡ lỗi

Khi ứng dụng của bạn trở nên phức tạp hơn và bạn bắt đầu sử dụng nhiều JavaScript hơn, bạn có thể bắt đầu gặp phải các vấn đề về hiệu suất, đặc biệt là khi xem ứng dụng trên các thiết bị chậm hơn. Hiệu suất là một chủ đề lớn và chúng tôi không có thời gian để trình bày chi tiết ở đây. Một số mẹo nhanh như sau

  • Để tránh tải nhiều JavaScript hơn mức bạn cần, hãy gộp các tập lệnh của bạn vào một tệp duy nhất bằng giải pháp như Browserify. Nói chung, việc giảm số lượng yêu cầu HTTP rất tốt cho hiệu suất
  • Làm cho các tệp của bạn thậm chí còn nhỏ hơn bằng cách thu nhỏ chúng trước khi bạn tải chúng lên máy chủ sản xuất của mình. Giảm thiểu nén tất cả các mã lại với nhau thành một dòng lớn, làm cho nó chiếm ít kích thước tệp hơn. Nó xấu xí, nhưng bạn không cần phải đọc nó khi nó kết thúc. Điều này được thực hiện tốt nhất bằng cách sử dụng công cụ thu nhỏ như Uglify (cũng có phiên bản trực tuyến — xem JSCompress. com)
  • Khi sử dụng API, đảm bảo bạn tắt các tính năng của API khi chúng không được sử dụng; . Ví dụ: khi hiển thị luồng video, hãy nhớ tắt luồng đó khi bạn không thể xem được. Khi theo dõi vị trí của thiết bị bằng lệnh gọi Định vị địa lý lặp đi lặp lại, hãy đảm bảo bạn tắt tính năng này khi người dùng ngừng sử dụng tính năng này
  • Hoạt hình có thể thực sự tốn kém cho hiệu suất. Rất nhiều thư viện JavaScript cung cấp khả năng hoạt ảnh được lập trình bởi JavaScript, nhưng sẽ hiệu quả hơn nhiều khi thực hiện hoạt ảnh thông qua các tính năng trình duyệt gốc như Hoạt ảnh CSS (hoặc API Hoạt ảnh Web mới ra đời) so với JavaScript. Đọc Animating like you just don't care của Brian Birtles với Element. animate để biết một số lý thuyết thực sự hữu ích về lý do tại sao hoạt ảnh lại đắt tiền, các mẹo về cách cải thiện hiệu suất hoạt ảnh và thông tin về Web Animations API

Ghi chú. Addy Osmani's Viết JavaScript nhanh, tiết kiệm bộ nhớ chứa rất nhiều chi tiết và một số mẹo tuyệt vời để tăng hiệu suất JavaScript

Trong phần này, chúng ta sẽ xem xét một số sự cố JavaScript trên nhiều trình duyệt phổ biến hơn. Chúng tôi sẽ chia nó thành

  • Sử dụng các tính năng JavaScript cốt lõi hiện đại
  • Sử dụng các tính năng API Web hiện đại
  • Sử dụng mã đánh hơi trình duyệt xấu
  • Vấn đề hiệu suất

Trong phần này, chúng tôi đã mô tả một số cách xử lý các lỗi HTML và CSS cũng như các tính năng không nhận dạng được do bản chất của ngôn ngữ. Tuy nhiên, JavaScript không được phép như HTML và CSS - nếu công cụ JavaScript gặp phải lỗi hoặc cú pháp không được nhận dạng, thường thì nó sẽ đưa ra lỗi

Có một số tính năng ngôn ngữ JavaScript hiện đại được xác định trong các phiên bản gần đây của thông số kỹ thuật sẽ không hoạt động trong các trình duyệt cũ hơn. Một số trong số này là đường cú pháp (về cơ bản là cách viết dễ dàng hơn, đẹp hơn những gì bạn có thể làm bằng các tính năng hiện có) và một số cung cấp các khả năng mới thú vị

Ví dụ

  • Lời hứa là một tính năng mới tuyệt vời để thực hiện các hoạt động không đồng bộ và đảm bảo các hoạt động đó hoàn tất trước khi mã dựa trên kết quả của chúng được sử dụng cho mục đích khác. Ví dụ: API tìm nạp (tương đương hiện đại với XMLHTTPRequest) sử dụng lời hứa tìm nạp tài nguyên trên mạng và đảm bảo rằng phản hồi đã được trả về trước khi chúng được sử dụng (ví dụ: hiển thị hình ảnh bên trong phần tử
    request.onload = function() {
      let superHeroes = request.response;
      populateHeader(superHeroes);
      showHeroes(superHeroes);
    }
    
    4). Chúng hoàn toàn không được hỗ trợ trong IE nhưng được hỗ trợ trên tất cả các trình duyệt hiện đại
  • Các hàm mũi tên cung cấp một cú pháp ngắn hơn, thuận tiện hơn để viết. Để biết ví dụ nhanh, hãy xem chức năng mũi tên. html (cũng xem mã nguồn). Các chức năng mũi tên được hỗ trợ trên tất cả các trình duyệt hiện đại, ngoại trừ IE
  • Việc khai báo chế độ nghiêm ngặt ở đầu mã JavaScript của bạn sẽ khiến nó được phân tích cú pháp bằng một bộ quy tắc chặt chẽ hơn, nghĩa là sẽ có nhiều cảnh báo và lỗi hơn, đồng thời một số nội dung sẽ không được phép mà lẽ ra có thể chấp nhận được. Người ta cho rằng nên sử dụng chế độ nghiêm ngặt, vì nó tạo ra mã tốt hơn, hiệu quả hơn, tuy nhiên, nó có hỗ trợ hạn chế/chắp vá trên các trình duyệt (xem phần )
  • Các mảng đã nhập cho phép mã JavaScript truy cập và thao tác với dữ liệu nhị phân thô, điều này cần thiết vì chẳng hạn như các API của trình duyệt bắt đầu thao tác với các luồng dữ liệu âm thanh và video thô. Chúng có sẵn trong IE10 trở lên và tất cả các trình duyệt hiện đại

Ngoài ra còn có nhiều API mới xuất hiện trong các trình duyệt gần đây, chẳng hạn như không hoạt động trong các trình duyệt cũ hơn

  • API IndexedDB, API lưu trữ web và các API khác để lưu trữ dữ liệu trang web ở phía máy khách
  • Web Worker API để chạy JavaScript trong một luồng riêng biệt, giúp cải thiện hiệu suất
  • API WebGL cho đồ họa 3D thực
  • API âm thanh web để thao tác âm thanh nâng cao
  • API WebRTC cho kết nối video/âm thanh thời gian thực, nhiều người (e. g. hội nghị truyền hình)
  • WebVR API dành cho kỹ thuật trải nghiệm thực tế ảo trong trình duyệt (e. g. kiểm soát chế độ xem 3D với dữ liệu đầu vào từ Phần cứng VR)

Có một số chiến lược để xử lý sự không tương thích giữa các trình duyệt liên quan đến hỗ trợ tính năng;

Ghi chú. Các chiến lược này không tồn tại trong các silo riêng biệt — tất nhiên, bạn có thể kết hợp chúng khi cần thiết. Ví dụ: bạn có thể sử dụng tính năng phát hiện tính năng để xác định xem một tính năng có được hỗ trợ hay không;

phát hiện tính năng

Ý tưởng đằng sau tính năng phát hiện tính năng là bạn có thể chạy thử nghiệm để xác định xem một tính năng JavaScript có được hỗ trợ trong trình duyệt hiện tại hay không, sau đó chạy mã có điều kiện để cung cấp trải nghiệm chấp nhận được cả trong các trình duyệt hỗ trợ và không hỗ trợ tính năng này. Lấy ví dụ nhanh, API định vị địa lý (hiển thị dữ liệu vị trí khả dụng cho thiết bị mà trình duyệt web đang chạy) có một điểm vào chính để sử dụng nó — một thuộc tính

request.onload = function() {
  let superHeroes = request.response;
  populateHeader(superHeroes);
  showHeroes(superHeroes);
}
5 có sẵn trên đối tượng Bộ điều hướng chung. Do đó, bạn có thể phát hiện xem trình duyệt có hỗ trợ định vị địa lý hay không bằng cách sử dụng một số thứ như sau

if ("geolocation" in navigator) {
  navigator.geolocation.getCurrentPosition((position) => {
    // show the location on a map, perhaps using the Google Maps API
  });
} else {
  // Give the user a choice of static maps instead perhaps
}

Bạn cũng có thể viết một bài kiểm tra như vậy cho một tính năng CSS, chẳng hạn bằng cách kiểm tra sự tồn tại của phần tử. Phong cách. tài sản (e. g.

request.onload = function() {
  let superHeroes = request.response;
  populateHeader(superHeroes);
  showHeroes(superHeroes);
}
6). Nhưng đối với cả CSS và JavaScript, có lẽ tốt hơn là sử dụng thư viện phát hiện tính năng đã được thiết lập thay vì viết thư của riêng bạn mọi lúc. Modernizr là tiêu chuẩn công nghiệp cho các bài kiểm tra phát hiện tính năng

Điểm cuối cùng, đừng nhầm lẫn giữa phát hiện tính năng với trình duyệt đánh hơi (phát hiện trình duyệt cụ thể nào đang truy cập trang web) — đây là một thực tế tồi tệ nên được ngăn chặn bằng mọi giá. Xem, sau này, để biết thêm chi tiết

Ghi chú. Một số tính năng được biết là không thể phát hiện — xem danh sách Không thể phát hiện của Modernizr

Ghi chú. Phát hiện tính năng sẽ được trình bày chi tiết hơn trong bài viết riêng của nó, ở phần sau của mô-đun

thư viện

Các thư viện JavaScript về cơ bản là các đơn vị mã của bên thứ ba mà bạn có thể đính kèm vào trang của mình, cung cấp cho bạn vô số chức năng làm sẵn có thể sử dụng ngay, giúp bạn tiết kiệm rất nhiều thời gian trong quá trình này. Rất nhiều thư viện JavaScript có thể ra đời vì nhà phát triển của chúng đang viết một tập hợp các hàm tiện ích phổ biến để tiết kiệm thời gian khi viết các dự án trong tương lai và quyết định phát hành chúng vào tự nhiên vì những người khác cũng có thể thấy chúng hữu ích

Các thư viện JavaScript có xu hướng có một số loại chính (một số thư viện sẽ phục vụ nhiều hơn một trong những mục đích này)

  • thư viện tiện ích. Cung cấp một loạt các chức năng để quản lý các tác vụ thông thường dễ dàng hơn và đỡ nhàm chán hơn. Ví dụ, jQuery cung cấp các bộ chọn và thư viện thao tác DOM đầy đủ tính năng của riêng nó, để cho phép loại bộ chọn CSS chọn các phần tử trong JavaScript và xây dựng DOM dễ dàng hơn. Điều đó không quá quan trọng khi chúng ta có các tính năng hiện đại như phương thức
    request.onload = function() {
      let superHeroes = request.response;
      populateHeader(superHeroes);
      showHeroes(superHeroes);
    }
    
    7/
    request.onload = function() {
      let superHeroes = request.response;
      populateHeader(superHeroes);
      showHeroes(superHeroes);
    }
    
    8/
    request.onload = function() {
      let superHeroes = request.response;
      populateHeader(superHeroes);
      showHeroes(superHeroes);
    }
    
    9 trên các trình duyệt, nhưng nó vẫn có thể hữu ích khi các trình duyệt cũ hơn cần hỗ trợ
  • thư viện tiện ích. Làm cho những điều khó khăn dễ dàng hơn để làm. Ví dụ: API WebGL thực sự phức tạp và khó sử dụng khi bạn viết trực tiếp, vì vậy Ba. js (và các thư viện khác) được xây dựng trên WebGL và cung cấp API dễ dàng hơn nhiều để tạo các đối tượng 3D, ánh sáng, kết cấu, v.v. Service Worker API cũng rất phức tạp để sử dụng, vì vậy các thư viện mã đã bắt đầu xuất hiện để làm cho các trường hợp sử dụng Service Worker phổ biến dễ triển khai hơn nhiều (xem Service Worker Cookbook để biết một số mẫu mã hữu ích)
  • thư viện hiệu ứng. Các thư viện này được thiết kế để cho phép bạn dễ dàng thêm các hiệu ứng đặc biệt vào trang web của mình. Điều này hữu ích hơn khi "DHTML" là một từ thông dụng phổ biến và việc triển khai hiệu ứng liên quan đến nhiều JavaScript phức tạp, nhưng ngày nay, các trình duyệt có rất nhiều tính năng CSS và API tích hợp để triển khai hiệu ứng dễ dàng hơn
  • thư viện giao diện người dùng. Cung cấp các phương pháp để triển khai các tính năng giao diện người dùng phức tạp mà nếu không sẽ khó triển khai và làm việc trên nhiều trình duyệt, ví dụ: Foundation, Bootstrap và Material-UI (cái sau là một tập hợp các thành phần để sử dụng với khung React). Chúng có xu hướng được sử dụng làm cơ sở của toàn bộ bố cục trang web;
  • thư viện chuẩn hóa. Cung cấp cho bạn một cú pháp đơn giản cho phép bạn dễ dàng hoàn thành một tác vụ mà không phải lo lắng về sự khác biệt giữa các trình duyệt. Thư viện sẽ thao tác các API thích hợp trong nền để chức năng sẽ hoạt động trên bất kỳ trình duyệt nào (về lý thuyết). Ví dụ: LocalForage là thư viện lưu trữ dữ liệu phía máy khách, cung cấp cú pháp đơn giản để lưu trữ và truy xuất dữ liệu. Ở chế độ nền, nó sử dụng API tốt nhất mà trình duyệt có sẵn để lưu trữ dữ liệu, cho dù đó là IndexedDB, Web Storage hay thậm chí là Web SQL (hiện không được dùng nữa nhưng vẫn được hỗ trợ trong các trình duyệt dựa trên Chromium trong ngữ cảnh bảo mật). Một ví dụ khác, jQuery

Khi chọn một thư viện để sử dụng, hãy đảm bảo rằng thư viện đó hoạt động trên bộ trình duyệt mà bạn muốn hỗ trợ và kiểm tra kỹ lưỡng việc triển khai của bạn. Ngoài ra, hãy đảm bảo rằng thư viện phổ biến và được hỗ trợ tốt và không có khả năng trở nên lỗi thời vào tuần tới. Nói chuyện với các nhà phát triển khác để tìm hiểu những gì họ đề xuất, xem thư viện có bao nhiêu hoạt động và bao nhiêu người đóng góp trên GitHub (hoặc bất kỳ nơi nào khác mà thư viện được lưu trữ), v.v.

Việc sử dụng thư viện ở mức cơ bản có xu hướng bao gồm việc tải xuống các tệp của thư viện (JavaScript, có thể là một số CSS hoặc các tệp phụ thuộc khác) và đính kèm chúng vào trang của bạn (e. g. thông qua phần tử

if ("geolocation" in navigator) {
  navigator.geolocation.getCurrentPosition((position) => {
    // show the location on a map, perhaps using the Google Maps API
  });
} else {
  // Give the user a choice of static maps instead perhaps
}
0), mặc dù thông thường có nhiều tùy chọn sử dụng khác cho các thư viện như vậy, như cài đặt chúng dưới dạng các thành phần Bower hoặc bao gồm chúng dưới dạng phụ thuộc thông qua gói mô-đun Webpack. Bạn sẽ phải đọc các trang cài đặt riêng lẻ của thư viện để biết thêm thông tin

Ghi chú. Bạn cũng sẽ bắt gặp các khung JavaScript trong hành trình của mình trên Web, như Ember và Angular. Trong khi các thư viện thường được sử dụng để giải quyết các vấn đề riêng lẻ và thả vào các trang web hiện có, thì các khung có xu hướng phù hợp hơn với các giải pháp hoàn chỉnh để phát triển các ứng dụng web phức tạp.

polyfill

Polyfill cũng bao gồm các tệp JavaScript của bên thứ 3 mà bạn có thể thả vào dự án của mình, nhưng chúng khác với thư viện — trong khi thư viện có xu hướng nâng cao chức năng hiện có và giúp mọi thứ dễ dàng hơn, polyfill cung cấp chức năng hoàn toàn không tồn tại. Polyfill sử dụng hoàn toàn JavaScript hoặc các công nghệ khác để xây dựng hỗ trợ cho một tính năng mà trình duyệt không hỗ trợ nguyên bản. Ví dụ: bạn có thể sử dụng một polyfill như es6-promise để thực hiện các lời hứa hoạt động trong các trình duyệt không được hỗ trợ nguyên bản

Danh sách Polyfill trình duyệt chéo HTML5 của Modernizr là một nơi hữu ích để tìm các polyfill cho các mục đích khác nhau. Một lần nữa, bạn nên nghiên cứu chúng trước khi sử dụng — đảm bảo rằng chúng hoạt động và được bảo trì

Hãy cùng thực hiện một bài tập — trong ví dụ này, chúng ta sẽ sử dụng Fetch polyfill để cung cấp hỗ trợ cho Fetch API trong các trình duyệt cũ hơn;

  1. Để bắt đầu, hãy tạo một bản sao cục bộ của tìm nạp-polyfill của chúng tôi. ví dụ html và hình ảnh đẹp của chúng tôi về một số bông hoa trong một thư mục mới. Chúng tôi sẽ viết mã để lấy hình ảnh hoa và hiển thị nó trong trang
  2. Tiếp theo, lưu một bản sao của Fetch polyfill trong cùng thư mục với HTML
  3. Áp dụng các tập lệnh polyfill cho trang bằng cách sử dụng mã sau — đặt các tập lệnh này phía trên phần tử
    if ("geolocation" in navigator) {
      navigator.geolocation.getCurrentPosition((position) => {
        // show the location on a map, perhaps using the Google Maps API
      });
    } else {
      // Give the user a choice of static maps instead perhaps
    }
    
    0 hiện có để chúng có sẵn trên trang khi chúng tôi bắt đầu thử sử dụng Tìm nạp (chúng tôi cũng đang tải một Promise polyfill từ CDN, giống như IE11 thực hiện

    <script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js"></script>
    <script src="fetch.js"></script>
    

  4. Bên trong bản gốc
    if ("geolocation" in navigator) {
      navigator.geolocation.getCurrentPosition((position) => {
        // show the location on a map, perhaps using the Google Maps API
      });
    } else {
      // Give the user a choice of static maps instead perhaps
    }
    
    0, thêm đoạn mã sau

    const myImage = document.querySelector('.my-image');
    
    fetch('flowers.jpg').then((response) => {
      response.blob().then((myBlob) => {
        const objectURL = URL.createObjectURL(myBlob);
        myImage.src = objectURL;
      });
    });
    

  5. Nếu bạn tải nó trong trình duyệt không hỗ trợ Tìm nạp, bạn vẫn sẽ thấy hình ảnh bông hoa xuất hiện — thật tuyệt.
    Tại sao JavaScript của tôi không hoạt động trong HTML?

Ghi chú. Bạn có thể tìm thấy phiên bản đã hoàn thành của chúng tôi tại tìm nạp-polyfill-finished. html (xem thêm mã nguồn)

Ghi chú. Một lần nữa, có nhiều cách khác nhau để sử dụng các polyfill khác nhau mà bạn sẽ gặp — tham khảo tài liệu riêng của từng polyfill

Một điều bạn có thể nghĩ là "tại sao chúng ta phải luôn tải mã polyfill, ngay cả khi chúng ta không cần nó?" . , bạn có thể bắt đầu tải nhiều mã bổ sung, điều này có thể bắt đầu ảnh hưởng đến hiệu suất, đặc biệt là trên các thiết bị yếu hơn. Thật hợp lý khi chỉ tải các tệp khi cần thiết

Làm điều này yêu cầu một số thiết lập bổ sung trong JavaScript của bạn. Bạn cần một số loại kiểm tra phát hiện tính năng để phát hiện xem trình duyệt có hỗ trợ tính năng mà chúng tôi đang cố gắng sử dụng hay không

if (browserSupportsAllFeatures()) {
  main();
} else {
  loadScript('polyfills.js', main);
}

function main(err) {
  // actual app code goes in here
}

Vì vậy, trước tiên, chúng tôi chạy một điều kiện để kiểm tra xem hàm

if ("geolocation" in navigator) {
  navigator.geolocation.getCurrentPosition((position) => {
    // show the location on a map, perhaps using the Google Maps API
  });
} else {
  // Give the user a choice of static maps instead perhaps
}
3 có trả về true hay không. Nếu đúng như vậy, chúng tôi sẽ chạy hàm
if ("geolocation" in navigator) {
  navigator.geolocation.getCurrentPosition((position) => {
    // show the location on a map, perhaps using the Google Maps API
  });
} else {
  // Give the user a choice of static maps instead perhaps
}
4, hàm này sẽ chứa tất cả mã ứng dụng của chúng tôi.
if ("geolocation" in navigator) {
  navigator.geolocation.getCurrentPosition((position) => {
    // show the location on a map, perhaps using the Google Maps API
  });
} else {
  // Give the user a choice of static maps instead perhaps
}
3 trông như thế này

function showHeroes(jsonObj) {
  let heroes = jsonObj['members'];

  for (const hero of heroes) {
    // …
   }

   // …
 }
0

Ở đây chúng tôi đang kiểm tra xem đối tượng

if ("geolocation" in navigator) {
  navigator.geolocation.getCurrentPosition((position) => {
    // show the location on a map, perhaps using the Google Maps API
  });
} else {
  // Give the user a choice of static maps instead perhaps
}
6 và chức năng
if ("geolocation" in navigator) {
  navigator.geolocation.getCurrentPosition((position) => {
    // show the location on a map, perhaps using the Google Maps API
  });
} else {
  // Give the user a choice of static maps instead perhaps
}
7 có tồn tại trong trình duyệt hay không. Nếu cả hai đều như vậy, hàm trả về true. Nếu hàm trả về
if ("geolocation" in navigator) {
  navigator.geolocation.getCurrentPosition((position) => {
    // show the location on a map, perhaps using the Google Maps API
  });
} else {
  // Give the user a choice of static maps instead perhaps
}
8, thì chúng tôi chạy mã bên trong phần thứ hai của điều kiện — phần này chạy một hàm gọi là loadScript(), tải các polyfill vào trang, sau đó chạy
if ("geolocation" in navigator) {
  navigator.geolocation.getCurrentPosition((position) => {
    // show the location on a map, perhaps using the Google Maps API
  });
} else {
  // Give the user a choice of static maps instead perhaps
}
4 sau khi tải xong.
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js"></script>
<script src="fetch.js"></script>
0 trông như thế này

function showHeroes(jsonObj) {
  let heroes = jsonObj['members'];

  for (const hero of heroes) {
    // …
   }

   // …
 }
1

Hàm này tạo một phần tử

if ("geolocation" in navigator) {
  navigator.geolocation.getCurrentPosition((position) => {
    // show the location on a map, perhaps using the Google Maps API
  });
} else {
  // Give the user a choice of static maps instead perhaps
}
0 mới, sau đó đặt thuộc tính
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js"></script>
<script src="fetch.js"></script>
2 của nó thành đường dẫn mà chúng ta đã chỉ định làm đối số đầu tiên (
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js"></script>
<script src="fetch.js"></script>
3 khi chúng ta gọi nó trong đoạn mã trên). Khi nó đã được tải, chúng tôi chạy hàm mà chúng tôi đã chỉ định làm đối số thứ hai (
if ("geolocation" in navigator) {
  navigator.geolocation.getCurrentPosition((position) => {
    // show the location on a map, perhaps using the Google Maps API
  });
} else {
  // Give the user a choice of static maps instead perhaps
}
4). Nếu xảy ra lỗi trong quá trình tải tập lệnh, chúng tôi vẫn gọi hàm nhưng với lỗi tùy chỉnh mà chúng tôi có thể truy xuất để giúp gỡ lỗi sự cố nếu xảy ra

Lưu ý rằng polyfill. js về cơ bản là hai polyfill mà chúng tôi đang sử dụng được kết hợp với nhau thành một tệp. Chúng tôi đã thực hiện việc này theo cách thủ công nhưng có những giải pháp thông minh hơn sẽ tự động tạo các gói cho bạn — xem Browserify (xem Bắt đầu với Browserify để có hướng dẫn cơ bản). Bạn nên gộp các tệp JS thành một tệp như thế này — giảm số lượng yêu cầu HTTP mà bạn cần để cải thiện hiệu suất trang web của mình

Bạn có thể thấy mã này hoạt động trong tìm nạp-chỉ-đa-điền-khi-cần. html (cũng xem mã nguồn). Chúng tôi muốn làm rõ rằng chúng tôi không thể công nhận mã này - nó được viết bởi Philip Walton. Hãy xem bài viết của anh ấy Chỉ tải các Polyfill khi cần thiết cho mã gốc, cộng với rất nhiều lời giải thích hữu ích xung quanh chủ đề rộng hơn)

Ghi chú. Có một số tùy chọn của bên thứ 3 để xem xét, ví dụ Polyfill. io — đây là thư viện meta-polyfill sẽ xem xét khả năng của từng trình duyệt và áp dụng các polyfill khi cần, tùy thuộc vào API và tính năng JS nào bạn đang sử dụng trong mã của mình

phiên mã JavaScript

Một tùy chọn khác hiện đang trở nên phổ biến đối với những người muốn sử dụng các tính năng JavaScript hiện đại là chuyển đổi mã sử dụng các tính năng ECMAScript 6/ECMAScript 2015 sang phiên bản sẽ hoạt động trong các trình duyệt cũ hơn

Ghi chú. Điều này được gọi là "chuyển mã" - bạn không biên dịch mã thành cấp thấp hơn để chạy trên máy tính (như bạn sẽ nói với mã C);

Vì vậy, ví dụ, chúng ta đã nói về hàm mũi tên (xem hàm mũi tên. html trực tiếp và xem mã nguồn) trước đó trong bài viết, mã này chỉ hoạt động trong các trình duyệt mới nhất

function showHeroes(jsonObj) {
  let heroes = jsonObj['members'];

  for (const hero of heroes) {
    // …
   }

   // …
 }
2

Chúng tôi có thể dịch mã này sang một chức năng ẩn danh kiểu cũ truyền thống, vì vậy nó sẽ hoạt động trong các trình duyệt cũ hơn

function showHeroes(jsonObj) {
  let heroes = jsonObj['members'];

  for (const hero of heroes) {
    // …
   }

   // …
 }
3

Công cụ được đề xuất để chuyển mã JavaScript hiện tại là Babel. Điều này cung cấp khả năng dịch cho các tính năng ngôn ngữ phù hợp với dịch. Đối với các tính năng không thể dễ dàng dịch mã thành một tính năng tương đương cũ hơn, Babel cũng cung cấp các polyfill để cung cấp hỗ trợ

Cách dễ nhất để dùng thử Babel là sử dụng phiên bản trực tuyến, cho phép bạn nhập mã nguồn của mình ở bên trái và xuất ra phiên bản đã biên dịch ở bên phải

Ghi chú. Có nhiều cách để sử dụng Babel (trình chạy tác vụ, công cụ tự động hóa, v.v. ), như bạn sẽ thấy trên trang thiết lập

Tất cả các trình duyệt đều có một chuỗi tác nhân người dùng, xác định trình duyệt đó là gì (phiên bản, tên, hệ điều hành, v.v. ). Trước đây, các nhà phát triển đã sử dụng mã đánh hơi trình duyệt để phát hiện trình duyệt nào người dùng đang sử dụng và cung cấp cho họ mã thích hợp để hoạt động trên trình duyệt đó

Mã được sử dụng để trông giống như thế này (mặc dù đây là một ví dụ đơn giản hóa)

function showHeroes(jsonObj) {
  let heroes = jsonObj['members'];

  for (const hero of heroes) {
    // …
   }

   // …
 }
4

Ý tưởng này có vẻ hợp lý — phát hiện trình duyệt nào đang xem trang web và cung cấp mã phù hợp với trình duyệt đó

Ghi chú. Hãy thử mở bảng điều khiển JavaScript của bạn ngay bây giờ và chạy

<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js"></script>
<script src="fetch.js"></script>
5, để xem những gì bạn nhận được

Tuy nhiên, thời gian trôi qua, các nhà phát triển bắt đầu thấy những vấn đề lớn với phương pháp này. Để bắt đầu, mã dễ bị lỗi. Điều gì sẽ xảy ra nếu bạn biết một tính năng không hoạt động trong Firefox 10 trở xuống và triển khai mã để phát hiện tính năng này, sau đó Firefox 11 ra mắt — hỗ trợ tính năng đó? . Bạn sẽ phải thay đổi tất cả mã đánh hơi của mình thường xuyên

Nhiều nhà phát triển đã triển khai mã đánh hơi trình duyệt xấu và không duy trì mã đó, đồng thời các trình duyệt bắt đầu không thể sử dụng các trang web chứa các tính năng mà họ đã triển khai kể từ đó. Điều này trở nên phổ biến đến mức các trình duyệt bắt đầu nói dối về trình duyệt của họ trong chuỗi tác nhân người dùng của họ (hoặc tuyên bố rằng tất cả họ đều là trình duyệt), để tìm mã đánh hơi. Các trình duyệt cũng triển khai các phương tiện để cho phép người dùng thay đổi chuỗi tác nhân người dùng mà trình duyệt đã báo cáo khi được truy vấn bằng JavaScript. Tất cả điều này làm cho trình duyệt đánh hơi dễ bị lỗi hơn và cuối cùng là vô nghĩa

Ghi chú. Bạn nên đọc Lịch sử chuỗi tác nhân người dùng trình duyệt của Aaron Andersen để biết cách xử lý tình huống này hữu ích và thú vị

Bài học rút ra ở đây là đừng bao giờ sử dụng trình duyệt đánh hơi. Trường hợp sử dụng thực sự duy nhất cho mã đánh hơi trình duyệt trong thời hiện đại là nếu bạn đang triển khai sửa lỗi trong một phiên bản rất cụ thể của một trình duyệt cụ thể. Nhưng ngay cả khi đó, hầu hết các lỗi đều được sửa khá nhanh trong các chu kỳ phát hành nhanh của nhà cung cấp trình duyệt. Nó sẽ không xuất hiện thường xuyên. hầu như luôn là một lựa chọn tốt hơn — nếu bạn phát hiện xem một tính năng có được hỗ trợ hay không, bạn sẽ không cần thay đổi mã của mình khi các phiên bản trình duyệt mới ra mắt và các thử nghiệm sẽ đáng tin cậy hơn nhiều

Nếu bạn bắt gặp trình duyệt đánh hơi khi tham gia một dự án hiện có, hãy xem liệu nó có thể được thay thế bằng thứ gì đó hợp lý hơn không. Trình duyệt đánh hơi gây ra tất cả các loại lỗi thú vị, chẳng hạn như lỗi 1308462

Trong bài viết trước, chúng tôi đã thảo luận khá nhiều về. Chà, các triển khai JavaScript mới đôi khi cũng sử dụng tiền tố, mặc dù JavaScript sử dụng trường hợp lạc đà thay vì gạch nối như CSS. Ví dụ: nếu một tiền tố đang được sử dụng trên một đối tượng API jshint mới có tên là

<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js"></script>
<script src="fetch.js"></script>
6

  • Mozilla sẽ sử dụng
    <script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js"></script>
    <script src="fetch.js"></script>
    
    7
  • Chrome/Opera/Safari sẽ sử dụng _______ 55 _______ 8
  • Microsoft sẽ sử dụng
    <script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js"></script>
    <script src="fetch.js"></script>
    
    9

Đây là một ví dụ, được lấy từ bản demo bạo lực theremin của chúng tôi (xem mã nguồn), sử dụng kết hợp API Canvas và API âm thanh trên web để tạo một công cụ vẽ thú vị (và ồn ào)

function showHeroes(jsonObj) {
  let heroes = jsonObj['members'];

  for (const hero of heroes) {
    // …
   }

   // …
 }
5

Trong trường hợp API âm thanh trên web, các điểm nhập chính để sử dụng API đã được hỗ trợ trong Chrome/Opera thông qua các phiên bản có tiền tố

const myImage = document.querySelector('.my-image');

fetch('flowers.jpg').then((response) => {
  response.blob().then((myBlob) => {
    const objectURL = URL.createObjectURL(myBlob);
    myImage.src = objectURL;
  });
});
0 (hiện tại chúng hỗ trợ các phiên bản không có tiền tố). Cách dễ dàng để giải quyết tình huống này là tạo một phiên bản mới của các đối tượng có tiền tố trong một số trình duyệt và làm cho nó bằng với phiên bản không có tiền tố, HOẶC phiên bản có tiền tố (HOẶC bất kỳ phiên bản có tiền tố nào khác cần xem xét) —

Sau đó, chúng tôi sử dụng đối tượng đó để thao tác API, thay vì đối tượng ban đầu. Trong trường hợp này, chúng tôi đang tạo một hàm tạo AudioContext đã sửa đổi, sau đó tạo một phiên bản ngữ cảnh âm thanh mới để sử dụng cho mã hóa Web Audio của chúng tôi

Mẫu này có thể được áp dụng cho bất kỳ tính năng JavaScript có tiền tố nào. Các thư viện/polyfill JavaScript cũng sử dụng loại mã này để trừu tượng hóa sự khác biệt của trình duyệt khỏi nhà phát triển càng nhiều càng tốt

Một lần nữa, các tính năng có tiền tố không bao giờ được phép sử dụng trong các trang web sản xuất — chúng có thể thay đổi hoặc xóa mà không có cảnh báo và gây ra sự cố trình duyệt chéo. Nếu bạn khăng khăng sử dụng các tính năng có tiền tố, hãy đảm bảo rằng bạn sử dụng đúng tính năng. Bạn có thể tra cứu những trình duyệt nào yêu cầu tiền tố cho các tính năng JavaScript/API khác nhau trên các trang tham khảo MDN và các trang web như caniuse. com. Nếu không chắc chắn, bạn cũng có thể tìm hiểu bằng cách thực hiện một số thử nghiệm trực tiếp trên trình duyệt

Ví dụ: hãy thử truy cập bảng điều khiển dành cho nhà phát triển của trình duyệt của bạn và bắt đầu nhập

function showHeroes(jsonObj) {
  let heroes = jsonObj['members'];

  for (const hero of heroes) {
    // …
   }

   // …
 }
6

Nếu tính năng này được hỗ trợ trong trình duyệt của bạn, nó sẽ tự động hoàn thành

Có nhiều vấn đề khác mà bạn sẽ gặp phải với JavaScript; . Tham khảo bài viết về HTML và CSS để có lời khuyên tốt nhất của chúng tôi

Vậy đó là JavaScript. Đơn giản hả?