Javascript를 사용하여 CSS 파일을로드하는 방법은 무엇입니까?


316

Javascript를 사용하여 CSS 스타일 시트를 HTML 페이지로 가져올 수 있습니까? 그렇다면 어떻게 할 수 있습니까?

추신 : 자바 스크립트는 내 사이트에서 호스팅되지만 사용자가 <head>웹 사이트 의 태그 를 넣을 수 있기를 원하며 내 서버에서 호스팅 된 CSS 파일을 현재 웹 페이지로 가져올 수 있어야합니다. (css 파일과 javascript 파일 모두 내 서버에서 호스팅됩니다).


답변:


416

여기에 "오래된 학교"방식이 있습니다. 모든 브라우저에서 잘 작동합니다. 이론적으로, setAttribute불행히도 IE6는 일관되게 지원하지 않습니다.

var cssId = 'myCss';  // you could encode the css path itself to generate id..
if (!document.getElementById(cssId))
{
    var head  = document.getElementsByTagName('head')[0];
    var link  = document.createElement('link');
    link.id   = cssId;
    link.rel  = 'stylesheet';
    link.type = 'text/css';
    link.href = 'http://website.com/css/stylesheet.css';
    link.media = 'all';
    head.appendChild(link);
}

이 예제는 CSS가 이미 추가되었는지 확인하여 한 번만 추가합니다.

해당 코드를 자바 스크립트 파일에 넣고 최종 사용자가 단순히 자바 스크립트를 포함하도록하고 CSS 경로가 절대 서버에로드되도록하십시오.

바닐라 JS

다음은 일반 자바 스크립트를 사용 head하여 URL의 파일 이름 부분을 기반으로 요소에 CSS 링크를 삽입하는 예입니다 .

<script type="text/javascript">
var file = location.pathname.split( "/" ).pop();

var link = document.createElement( "link" );
link.href = file.substr( 0, file.lastIndexOf( "." ) ) + ".css";
link.type = "text/css";
link.rel = "stylesheet";
link.media = "screen,print";

document.getElementsByTagName( "head" )[0].appendChild( link );
</script>

닫는 head태그 바로 앞에 코드를 삽입하면 페이지가 렌더링되기 전에 CSS가로드됩니다. 외부 JavaScript ( .js) 파일을 사용하면 스타일이 지정되지 않은 콘텐츠 ( FOUC ) 의 플래시 가 나타납니다.


6
CSS 파일이로드되면 콜백을 실행하는 것은 어떻습니까?
jchook

1
이것은 안정적으로 수행하기가 훨씬 복잡합니다. 널리 사용되는 Javascript 라이브러리에는 일반적으로 콜백과 함께 Javascript 및 스타일 시트를로드하는 형식이 있습니다. 예를 들어, YUI Get을 참조 하십시오 .

9
아마도 그것은 쉽게 jQuery를 방해 할 수, 문서 바로 가기 $ 아닌 다른 문자를 사용하는 것이 좋을 것이다 (같은 내 경우 한))
Zathrus 작가

2
@jonnybojangles jQuery.noConflict를 사용하면 jQuery에 대한 모든 참조의 이름을 $로 바꿀 수 있습니다. CSS 로더에 다른 변수 이름을 사용하는 것이 훨씬 간단합니다.
tommypyatt

2
@jchook 추가 link.onload = function(){ ... }하기 전에 추가 하여 콜백을 첨부 할 수있었습니다
Lounge9

74

jquery를 사용하는 경우 :

$('head').append('<link rel="stylesheet" type="text/css" href="style.css">');

1
이것은 스타일 시트가 페이지로드 바로 전에 주입 된 경우에만 작동합니까? dropbox에서 호스팅 한 CSS 파일이있는로드 된 페이지의 콘솔 내 에서이 명령을 실행하면 작동하지 않습니다. 내가 어떻게이 작업을 수행 할 수 있는지 아는 아이디어 :$('head').append('<link rel="stylesheet" type="text/css" href="https://dl.dropboxusercontent.com/s/ep1nzckmvgjq7jr/remove_transitions_from_page.css">');
thomas

50

이 스크립트와 같은 것이 가능하다고 생각합니다.

<script type="text/javascript" src="/js/styles.js"></script>

이 JS 파일에는 다음 명령문이 포함되어 있습니다.

if (!document.getElementById) document.write('<link rel="stylesheet" type="text/css" href="https://stackoverflow.com/css/versions4.css">');

자바 스크립트와 CSS의 주소는 사이트를 참조하려면 절대적이어야합니다.

"분지 기술을 사용하여 CSS 해킹을 거부" 기사 에서 많은 CSS 가져 오기 기술에 대해 설명 합니다.

그러나 "JavaScript를 사용하여 포틀릿 CSS 스타일 시트를 동적으로 추가" 기사에는 CreateStyleSheet 가능성 (IE의 독점적 방법)도 언급되어 있습니다.

<script type="text/javascript">
//<![CDATA[
if(document.createStyleSheet) {
  document.createStyleSheet('http://server/stylesheet.css');
}
else {
  var styles = "@import url(' http://server/stylesheet.css ');";
  var newSS=document.createElement('link');
  newSS.rel='stylesheet';
  newSS.href='data:text/css,'+escape(styles);
  document.getElementsByTagName("head")[0].appendChild(newSS);
}
//]]>

다음은 document.createStyleSheet()브라우저에없는 브라우저 에 추가 하기 위해 작성한 것입니다 : stackoverflow.com/questions/524696/…
Christoph

1
어떤 경우인지 정확히 모르지만 경우 document.write에 따라 웹 사이트 전체를 덮어 쓰므로 권장하지 않습니다.
에두아르 루카

@VonC, via <style>의 첫 번째 자식이라고 가정하는 대신 요소 를 직접 가져 오는 기능이 있습니까? <head>("head")[0]
Pacerier

@Pacerier groups.google.com/forum/#!topic/prototype-scriptaculous/… 에서 논의 된 내용을 찾을 수 있다고 생각합니다 . 예를 들면 다음과 같습니다.var style = document.getElementsByTagName("style")[0];
VonC

20

Element.insertAdjacentHTML 은 브라우저를 매우 잘 지원하며 한 줄에 스타일 시트를 추가 할 수 있습니다.

document.getElementsByTagName("head")[0].insertAdjacentHTML(
    "beforeend",
    "<link rel=\"stylesheet\" href=\"path/to/style.css\" />");

12

스타일 자체가로드 될 때까지 알고 (또는 기다리려면) 다음과 같이 작동합니다.

// this will work in IE 10, 11 and Safari/Chrome/Firefox/Edge
// add ES6 poly-fill for the Promise, if needed (or rewrite to use a callback)

let fetchStyle = function(url) {
  return new Promise((resolve, reject) => {
    let link = document.createElement('link');
    link.type = 'text/css';
    link.rel = 'stylesheet';
    link.onload = function() { resolve(); console.log('style has loaded'); };
    link.href = url;

    let headScript = document.querySelector('script');
    headScript.parentNode.insertBefore(link, headScript);
  });
};

어떻게 사용합니까
Raj Sharma

fetchStyle (url) .then (function () {stuff goes here})은 약속을 읽습니다
Ben Taliadoros

8

나는 이것이 꽤 오래된 실이라는 것을 알고 있지만 여기 5 센트가 온다.

필요에 따라 다른 방법으로이를 수행 할 수 있습니다.

CSS 파일을 잠시 동안 만 활성화하려는 경우가 있습니다. CSS 전환처럼. CSS를 활성화 한 다음 다른 이벤트 후에이를 비활성화하십시오.

CSS를 동적으로로드 한 다음 제거하는 대신 새 CSS의 모든 요소 앞에 클래스 / ID를 추가 한 다음 CSS 기본 노드의 해당 클래스 / ID를 body 태그와 같이 전환하면됩니다.

이 솔루션을 사용하면 처음에 더 많은 CSS 파일이로드되지만 CSS 레이아웃을 전환하는보다 역동적 인 방법이 있습니다.


7

최신 브라우저에서는 다음 promise과 같이 사용할 수 있습니다 . 약속이있는 로더 함수를 작성하십시오.

function LoadCSS( cssURL ) {

    // 'cssURL' is the stylesheet's URL, i.e. /css/styles.css

    return new Promise( function( resolve, reject ) {

        var link = document.createElement( 'link' );

        link.rel  = 'stylesheet';

        link.href = cssURL;

        document.head.appendChild( link );

        link.onload = function() { 

            resolve(); 

            console.log( 'CSS has loaded!' ); 
        };
    } );
}

그런 다음 CSS 가로 드 된 후에 무언가를 원합니다. CSS가 다음과 같이로드 된 후에 실행해야하는 함수를 호출 할 수 있습니다.

LoadCSS( 'css/styles.css' ).then( function() {

    console.log( 'Another function is triggered after CSS had been loaded.' );

    return DoAfterCSSHasLoaded();
} );

작동 방식을 심층적으로 이해하려는 경우 유용한 링크 :

약속에 관한 공식 문서

약속에 유용한 지침서

약속에 관한 훌륭한 소개 비디오


6

이 코드를 사용하십시오 :

var element = document.createElement("link");
element.setAttribute("rel", "stylesheet");
element.setAttribute("type", "text/css");
element.setAttribute("href", "external.css");
document.getElementsByTagName("head")[0].appendChild(element);

4

요청에 따라 CSS 및 JS 파일을 동기화 및 동기화하는 일반 jquery 플러그인이 있습니다. 또한 이미로드 된 것을 추적합니다 :) 참조 : http://code.google.com/p/rloader/


4

jQuery의 요소 생성 방법 (내 환경 설정)과 콜백을 사용하는 방법은 다음과 같습니다 onLoad.

var css = $("<link>", {
  "rel" : "stylesheet",
  "type" :  "text/css",
  "href" : "style.css"
})[0];

css.onload = function(){
  console.log("CSS IN IFRAME LOADED");
};

document
  .getElementsByTagName("head")[0]
  .appendChild(css);



2

JS 및 / 또는 CSS를로드하는 데 사용하는 전체 코드 아래

function loadScript(directory, files){
  var head = document.getElementsByTagName("head")[0]
  var done = false
  var extension = '.js'
  for (var file of files){ 
    var path = directory + file + extension 
    var script = document.createElement("script")
    script.src = path        
    script.type = "text/javascript"
    script.onload = script.onreadystatechange = function() {
        if ( !done && (!this.readyState ||
            this.readyState == "loaded" || this.readyState == "complete") ) {
            done = true
            script.onload = script.onreadystatechange = null   // cleans up a little memory:
            head.removeChild(script)  // to avoid douple loading
        }
  };
  head.appendChild(script) 
  done = false
 }
}

function loadStyle(directory, files){
  var head = document.getElementsByTagName("head")[0]
  var extension = '.css'
  for (var file of files){ 
   var path = directory + file + extension 
   var link = document.createElement("link")
   link.href = path        
   link.type = "text/css"
   link.rel = "stylesheet" 
   head.appendChild(link) 
 }
}

(() => loadScript('libraries/', ['listen','functions', 'speak', 'commands', 'wsBrowser', 'main'])) ();
(() => loadScript('scripts/', ['index'])) ();

(() => loadStyle('styles/', ['index'])) ();

1

CSS뿐만 아니라 모든 자산 (js, CSS, 이미지) 을로드하고 여러 파일에 대한 onload 이벤트를 처리하는 또 다른 방법을 공유하고 싶습니다 . 그것은이다 async-assets-loader. 아래 예를 참조하십시오.

<script src="https://unpkg.com/async-assets-loader"></script>
<script>
var jsfile = "https://code.jquery.com/jquery-3.4.1.min.js";
var cssfile = "https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css";
var imgfile = "https://logos.keycdn.com/keycdn-logo-black.png";
var assetsLoader = new asyncAssetsLoader();
assetsLoader.load([
      {uri: jsfile, type: "script"},
      {uri: cssfile, type: "style"},
      {uri: imgfile, type: "img"}
    ], function () {
      console.log("Assets are loaded");
      console.log("Img width: " + assetsLoader.getLoadedTags()[imgfile].width);
    });
</script> 

async-assets-loader docs 에 따르면


0
var fileref = document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("th:href", "@{/filepath}")
fileref.setAttribute("href", "/filepath")

나는 thymeleaf를 사용하고 있으며 이것은 잘 작동합니다. 감사


th:href클라이언트 측에 속성 을 추가하는 요점은 무엇입니까 ? 그것은 Thymeleaf에 의해 처리되지 않으므로 여기서 중복되는 것처럼 보입니다.
Slava Semushin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.