Kiedy tagi <script> powinny być widoczne i dlaczego mogą?

142

scriptElementem, który został urządzony jak display:blockpojawia widoczne. Dlaczego jest to możliwe i czy jest jakiś prawdziwy przypadek użycia, w którym jest to pożądane?

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

wutzebaer
źródło
55
Widziałem widoczny CSS <style>z edytowalną zawartością. Niezły sposób, aby zobaczyć efekty w czasie rzeczywistym.
John Dvorak
19
W przypadku kolejnego wyzwania wymyśl sposób, aby komentarze były widoczne.
Pan Lister
11
Przyjechałem tutaj, aby wspomnieć o tym samym, @JanDvorak. Wysadził mój min, gdy pierwszy raz go zobaczyłem. Mam tego demonstrację na codepen
Kjeld Schmidt
6
Przypomina mi Podróż Wędrowca do Świtu, kiedy Lucy czyta zaklęcie, które uwidacznia Aslana, i jest zaskoczona, że ​​magia na niego wpłynie , a on zasadniczo mówi, czy myślisz, że sprzeciwiam się moim własnym zasadom?
David Conrad,
4
Przyszedłem tutaj, myśląc, że to podstawowe pytanie i wyszedłem, gdy nauczyłem się czegoś nowego. I <3 sof.
Jacksonkr,

Odpowiedzi:

104

Specyfikacja HTML5 definiuje arkusz stylów, którego powinny używać programy użytkownika (takie jak przeglądarki). Sekcja 10.3.1 zawiera listę stylów dla „Ukrytych elementów”:

@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; }

Jak widać, dotyczy display: none;to script.

To jedyna „bariera” między użytkownikami a ukrytymi scriptelementami. Jest to w porządku i ma na celu możliwość nadpisywania stylów z arkuszy stylów klienta w arkuszach stylów autora (i oczywiście także w arkuszach stylów użytkownika).

Dlaczego ktoś mógłby chcieć tego użyć? Jednym z przypadków użycia jest wyświetlanie treści bez konieczności zmiany znaczenia znaków, takich jak </> , podobnie jak w starym xmpelemencie. scriptElement może być używany nie tylko dla skryptów, ale także dla bloków danych (czyli do niczego o typie MIME).

unor
źródło
Dane muszą być już zakodowane w <script>blokach danych - nie można ich załadować src.
@PauliSudarshanTerho: Tak, jeśli jest używany jako blok danych, srcatrybut nie jest dozwolony w scriptelemencie.
unor
71

Dlaczego <script>tagi mogą być widoczne?

Ponieważ są to elementy HTML jak wszystkie inne i nie ma powodu, aby pisać specjalne reguły dotyczące wielkości liter w specyfikacji HTML (co zwiększyłoby złożoność), aby uniemożliwić stosowanie do nich CSS.

Każdy element można stylizować. Weź na przykład:

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); }

Czy jest jakikolwiek przypadek, w którym jest potrzebny?

Z pewnością nie ma powszechnych, ale ogólne zasady nie mają sensu we wszystkim , do czego można je zastosować. Są przeznaczone do typowych przypadków.

Quentin
źródło
9
W rzeczywistości, jeśli spojrzysz na tag skryptu w inspektorze Chrome, zobaczyszuser agent stylesheet: script {display:none}
Niet the Dark Absol
8
Zrobiłbym to „elementy DOM jak wszystkie inne”. W rzeczywistości są to dość specjalne znaczniki HTML z ich regułami analizy.
Bergi
2
Ciekawostka: ponieważ zawartość skryptu jest analizowana jako CDATA, możesz używać go <script type="text/plain">tak, jak <xmp>w przeszłości, ale nadal być kompatybilny z walidatorem W3C.
Pan Lister
2
dlaczego script {display: block !important;}nie działa, gdy nie ma reguły szczególnego przypadku?
wutzebaer
3
@wutzebaer U mnie działa dobrze. Czy na pewno wszystko robisz dobrze? Zwróć uwagę, że scripttag również musi znajdować się w widocznym elemencie - będzie pokazywał tylko Twoje scripttreści w treści, a nie np head. Domyślnie.
Luaan
36

Inny (rzadki) przypadek użycia:

Czasami używam <script>tagów do krótkich przykładów kodu HTML w przewodnikach stylistycznych. W ten sposób nie muszę uciekać od tagów HTML i znaków specjalnych. Autouzupełnianie tagów edytora tekstu i podświetlanie składni nadal działają. Ale nie ma łatwego sposobu na dodanie podświetlania składni w przeglądarce.

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>

jfrej
źródło
2
Nieźle, chociaż sugerowałbym użycie prawidłowego typu MIME: text/htmli użycie czegoś podobnego class="codesample"do stosowania stylów. Tylko z powodów pedantycznych: D
Niet the Dark Absol
5
@NiettheDarkAbsol: Prawdopodobnie bezpieczniej jest nie używać „prawdziwego” typu MIME (lub czegokolwiek, co mogłoby nim stać się w przyszłości), na wypadek gdyby któraś przeglądarka zdecydowała się przeanalizować i wykonać w jakiś sposób elementy skryptu tego typu. To powiedziawszy, wolałbym użyć standardowego x-przedrostka dla niestandardowych typów, tj. Zrobić to text/x-example.
Ilmari Karonen
14

Możliwy przypadek użycia: do celów debugowania.

Możesz zastosować zajęcia na poziomie dokumentu, np. <body class="debugscript">, a następnie użyj 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);
}
Niet the Dark Absol
źródło
1
Dlaczego nie <html class="debugscript">?
Bergi
@Bergi To też jest opcja, chociaż prawdopodobnie nie ujawni ona <head>skryptów, ponieważ <head>sama w sobie również ma, display:nonewięc musiałbyś to na siłę ujawnić, co może prowadzić do dalszych komplikacji.
Niet the Dark Absol
10
Masz na myśli „dalszą zabawę” lub „dalszy potencjał debugowania” :-)
Bergi
1

Tagi skryptów są domyślnie ukrywane przy użyciu display:none;. Unor 1 wyjaśnia podstawową specyfikację języka. Jednak nadal są częścią DOM i mogą być odpowiednio stylizowane.

To powiedziawszy, ważne jest, aby dokładnie pamiętać, co robi tag skryptu. Chociaż kiedyś towarzyszyły mu typy i języki, nie jest to już wymagane. Obecnie zakłada się, że jest tam JavaScript, w wyniku czego przeglądarki będą interpretować i wykonywać skrypt w momencie napotkania (lub załadowania) z tych tagów.

Po wykonaniu skryptu zawartość tagu to tylko tekst (często ukryty) na stronie. Ten tekst można ujawnić, ale można go również usunąć, ponieważ jest to zwykły tekst.

U dołu strony, tuż przed zamykającym </html>tagiem, możesz bardzo łatwo usunąć te tagi wraz z ich tekstem i nie byłoby żadnych zmian na stronie.

Na przykład:

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

Nie usunie to żadnej funkcjonalności, ponieważ stan strony został już zmieniony i jest odzwierciedlony w bieżącym globalnym kontekście wykonywania. Na przykład, jeśli strona załadowała bibliotekę, taką jak jQuery, usunięcie tagów nie będzie oznaczać, że jQuery nie jest już ujawniane, ponieważ zostało już dodane do środowiska wykonawczego strony. Zasadniczo sprawia, że ​​narzędzie do inspekcji DOM nie wyświetla elementów skryptu, ale podkreśla, że ​​raz wykonane elementy skryptu są w rzeczywistości tylko tekstem.

1. unor, czw. 07 lipca 2016 r., Wutzebaer, „Kiedy tagi powinny być widoczne i dlaczego mogą?”, 1 lipca o godz. 10:53, https://stackoverflow.com/a/38147398/1026459

Travis J.
źródło