Khi nào các thẻ <script> sẽ hiển thị và tại sao chúng có thể?


142

Một scriptyếu tố có kiểu dáng như display:blockcó thể nhìn thấy. Tại sao nó có thể và có bất kỳ trường hợp sử dụng thực sự mà nó mong muốn?

td > * {
  display: block;
}
<table>
  <tr>
    <td>
      <script type="text/javascript">
        var test = 1;
      </script>von 1
    </td>
  </tr>
</table>


55
Tôi đã thấy một CSS hiển thị <style>với nội dung có thể chỉnh sửa. Cách tốt đẹp để xem các hiệu ứng trong thời gian thực.
John Dvorak

19
Đối với thử thách tiếp theo của bạn, hãy nghĩ ra cách để bình luận hiển thị.
Ông Lister

11
Đến đây để đề cập đến điều tương tự, @JanDvorak. Thổi hồn vào lần đầu tiên tôi nhìn thấy nó. Tôi đã có một minh chứng về điều này trên codepen
Kjeld Schmidt

6
Nhắc nhở tôi về The Voyage of the Dawn Tread khi Lucy đọc một câu thần chú khiến Aslan có thể nhìn thấy, và cô ấy ngạc nhiên rằng ma thuật sẽ ảnh hưởng đến anh ta , và về cơ bản anh ta nói, bạn có nghĩ rằng tôi sẽ không tuân theo quy tắc của riêng mình không?
David Conrad

4
Tôi đến đây nghĩ rằng đây là một câu hỏi cơ bản và đã học được điều gì đó mới. Tôi <3 sof.
Jacksonkr

Câu trả lời:


104

Đặc tả HTML5 xác định một biểu định kiểu mà các tác nhân người dùng (như trình duyệt) dự kiến ​​sẽ sử dụng. Mục 10.3.1 liệt kê các kiểu cho "Các phần tử ẩn":

@namespace url(http://www.w3.org/1999/xhtml);

[hidden], area, base, basefont, datalist, head, link,
meta, noembed, noframes, param, rp, script, source, style, template, track, title {
  display: none;
}

embed[hidden] { display: inline; height: 0; width: 0; }

Như bạn có thể thấy, nó áp dụng display: none;cho script.

Đây là "rào cản" duy nhất giữa người dùng của bạn và các scriptyếu tố ẩn . Nó hoàn toàn ổn và dự định có thể ghi đè lên các kiểu từ các biểu định kiểu tác nhân người dùng trong các trang kiểu tác giả (và tất nhiên cũng trong các biểu định kiểu người dùng).

Tại sao ai đó có thể muốn sử dụng nó? Một trường hợp sử dụng là hiển thị nội dung mà không phải thoát các ký tự như </> , tương tự như xmpphần tử cũ . Phần scripttử có thể được sử dụng không chỉ cho các tập lệnh mà còn cho các khối dữ liệu (nghĩa là cho bất kỳ thứ gì có kiểu MIME).


Dữ liệu phải được mã hóa vào <script>- khối dữ liệu không thể được tải bởi src.

@PauliSudarshanTerho: Có, nếu được sử dụng làm khối dữ liệu, srcthuộc tính không được phép trên scriptphần tử.
unor

71

Tại sao <script>Thẻ có thể hiển thị?

Bởi vì chúng là các phần tử HTML giống như bất kỳ phần tử nào khác và không có lý do để viết các quy tắc trường hợp đặc biệt trong đặc tả HTML (sẽ thêm độ phức tạp) để ngăn CSS áp dụng cho chúng.

Bất kỳ yếu tố có thể được tạo kiểu. Lấy ví dụ:

head { display: block; }
title { display: block; }
meta { display: block; }
meta[charset]:after { display: block; content: attr(charset); }
meta[content]:after { display: block; content: attr(content); }

Có Usecase nào mà nó muốn không?

Chắc chắn không có quy tắc chung, nhưng các quy tắc chung không được thiết kế để có ý nghĩa đối với mọi thứ mà bạn có thể áp dụng chúng. Chúng được thiết kế cho các trường hợp phổ biến.


9
Trên thực tế nếu bạn nhìn vào thẻ tập lệnh trong trình kiểm tra Chrome, bạn sẽ thấyuser agent stylesheet: script {display:none}
Niet the Dark Absol

8
Tôi sẽ tạo ra "các phần tử DOM như bất kỳ phần tử nào khác". Trong thực tế, chúng là các thẻ HTML khá đặc biệt với các quy tắc phân tích cú pháp của chúng.
Bergi

2
Sự thật thú vị: vì nội dung tập lệnh được phân tích cú pháp dưới dạng CDATA, trước đây bạn có thể sử dụng <script type="text/plain">như bạn có thể <xmp>, nhưng vẫn tương thích với trình xác nhận W3C.
Ông Lister

2
Tại sao script {display: block !important;}không hoạt động khi không có quy tắc trường hợp đặc biệt?
wutzebaer

3
@wutzebaer Nó hoạt động tốt với tôi. Bạn có chắc là bạn đang làm mọi thứ đúng không? Lưu ý rằng scriptthẻ cũng phải nằm trong một yếu tố có thể nhìn thấy - nó sẽ chỉ hiển thị bạn scripttrong cơ thể, chứ không phải headtheo mặc định.
Luaan

36

Một trường hợp sử dụng (không phổ biến) khác:

Đôi khi tôi sử dụng <script>các thẻ cho các ví dụ mã HTML ngắn gọn trong hướng dẫn kiểu. Bằng cách đó, tôi không phải thoát các thẻ HTML và các ký tự đặc biệt. Và thẻ soạn thảo văn bản tự động hoàn thành và tô sáng cú pháp vẫn hoạt động. Nhưng không có cách dễ dàng để thêm đánh dấu cú pháp trong trình duyệt.

script[type="text/example"] {
    background-color: #33373c;
    border: 1px solid #ccc;
    color: #aed9ef;
    display: block;
    font-family: monospace;
    overflow: auto;
    padding: 2px 10px 16px;
    white-space: pre-wrap;
    word-break: break-all;
    word-wrap: break-word;
}
<p>Here comes a code example:</p>
<script type="text/example">
  <div class="cool-component">
     Some code example
  </div>
</script>


2
Không tệ, mặc dù tôi sẽ đề xuất sử dụng loại MIME hợp lệ: text/htmlvà sử dụng một cái gì đó như class="codesample"để áp dụng các kiểu. Chỉ vì lý do phạm vi: D
Niet the Dark Tuyệt đối

5
@NiettheDarkAbsol: Có thể an toàn hơn khi không sử dụng loại MIME "thực" (hoặc bất cứ thứ gì có thể trở thành một trong tương lai), chỉ trong trường hợp một số trình duyệt một ngày nào đó có thể quyết định phân tích và thực thi các phần tử script theo kiểu đó. Điều đó nói rằng, tôi thích sử dụng x-tiền tố tiêu chuẩn cho các loại tùy chỉnh, nghĩa là tạo nó text/x-example.
Ilmari Karonen

14

Trường hợp sử dụng có thể: cho mục đích gỡ lỗi.

Bạn có thể áp dụng một lớp ở cấp độ tài liệu, ví dụ. <body class="debugscript">, sau đó sử dụng một số CSS:

body.debugscript script {
    display: block;
    background: #fcc;
    border: 1px solid red;
    padding: 2px;
}
body.debugscript script:before {
    content: 'Script:';
    display: block;
    font-weight: bold;
}
body.debugscript script[src]:before {
    content: 'Script: ' attr(src);
}

1
Tại sao không <html class="debugscript">?
Bergi

@Bergi Đó cũng là một lựa chọn, mặc dù có thể nó sẽ không tiết lộ <head>các tập lệnh vì <head>bản thân nó cũng có display:nonenên bạn cần phải tiết lộ điều đó, điều này có thể dẫn đến các biến chứng tiếp theo.
Niet the Dark Tuyệt đối

10
Bạn có nghĩa là "vui hơn nữa" hoặc "tiềm năng gỡ lỗi thêm" :-)
Bergi

1

Thẻ script được ẩn theo mặc định bằng cách sử dụng display:none;. Unor 1 giải thích các đặc tả ngôn ngữ cơ bản. Tuy nhiên, chúng vẫn là một phần của DOM và có thể được tạo kiểu tương ứng.

Điều đó nói rằng, điều quan trọng là phải ghi nhớ chính xác những gì một thẻ script đang làm. Mặc dù nó được sử dụng kèm theo các loại và ngôn ngữ, nhưng điều đó không còn cần thiết nữa. Bây giờ người ta cho rằng JavaScript có trong đó và kết quả là các trình duyệt sẽ diễn giải và thực thi tập lệnh khi nó gặp phải (hoặc được tải) từ các thẻ này.

Khi tập lệnh đã được thực thi, nội dung của thẻ chỉ là văn bản (thường bị ẩn) trên trang. Văn bản này có thể được tiết lộ, nhưng nó cũng có thể bị xóa vì nó chỉ là văn bản.

Ở dưới cùng của trang của bạn, ngay trước </html>thẻ đóng , bạn có thể dễ dàng xóa các thẻ này cùng với văn bản của chúng và sẽ không có thay đổi nào đối với trang.

Ví dụ:

(function(){
    var scripts = document.querySelectorAll("script");
    for(var i = 0; i < scripts.length; i++){
        scripts[i].parentNode.removeChild(scripts[i]);
    }
})()

Điều này sẽ không xóa bất kỳ chức năng nào, vì trạng thái của trang đã bị thay đổi và được phản ánh trong bối cảnh thực thi toàn cầu hiện tại. Ví dụ: nếu trang đã tải một thư viện như jQuery, việc xóa các thẻ sẽ không có nghĩa là jQuery không còn được hiển thị nữa vì nó đã được thêm vào môi trường thời gian chạy của trang. Về cơ bản, nó chỉ làm cho công cụ kiểm tra DOM không hiển thị các thành phần tập lệnh, nhưng nó làm nổi bật rằng các thành phần tập lệnh một khi được thực thi thực sự chỉ là văn bản.

1. unor, Thu Jul 07 2016, wutzebaer, "Khi nào các thẻ nên được hiển thị và tại sao chúng có thể?", 1 tháng 7 lúc 10:53, https://stackoverflow.com/a/38147398/1026459

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.