developer tip

로드되지 않은 경우 Javascript를 사용하여 CSS를 확인하고로드하는 방법은 무엇입니까?

copycodes 2021. 1. 6. 08:32
반응형

로드되지 않은 경우 Javascript를 사용하여 CSS를 확인하고로드하는 방법은 무엇입니까?


CSS 파일이로드되었는지 여부를 확인하고 (Javascript에서)로드하지 않으면로드해야합니다. jQuery는 괜찮습니다.


CSS 파일의 URL에 속성이 설정된 <link>요소가 있는지 확인하기 만하면됩니다 href.

if (!$("link[href='/path/to.css']").length)
    $('<link href="/path/to.css" rel="stylesheet">').appendTo("head");

document.styleSheets 컬렉션을 사용하는 일반 ol 'JS 메서드도 간단합니다 .

function loadCSSIfNotAlreadyLoadedForSomeReason () {
    var ss = document.styleSheets;
    for (var i = 0, max = ss.length; i < max; i++) {
        if (ss[i].href == "/path/to.css")
            return;
    }
    var link = document.createElement("link");
    link.rel = "stylesheet";
    link.href = "/path/to.css";

    document.getElementsByTagName("head")[0].appendChild(link);
}
loadCSSIfNotAlreadyLoadedForSomeReason();

그런 식으로 작성해야했고 공유하고 싶었습니다. 이것은 여러 경우에 대비합니다.

  • css 파일에 대한 요청이없는 경우 (css 파일이 연결되지 않음 ...)
  • css 파일에 대한 요청이 있지만 실패한 경우 (css 파일을 더 이상 사용할 수 없습니다 ...)

var styles = document.styleSheets;
for (var i = 0; i < styles.length; i++) {
    // checking if there is a request for template.css
    if (styles[i].href.match("template")) {
        console.log("(Iteration: " + i + ") Request for template.css is found.");
        // checking if the request is not successful
        // when it is successful .cssRules property is set to null
        if (styles[i].cssRules != null && styles[i].cssRules.length == 0) {
            console.log("(Iteration: " + i + ") Request for template.css failed.");
            // fallback, make your modification
            // since the request failed, we don't need to iterate through other stylesheets
            break;
        } else {
            console.log("(Iteration: " + i + ") Request for template.css is successful.");
            // template.css is loaded successfully, we don't need to iterate through other stylesheets
            break;
        }
    }
    // if there isn't a request, we fallback
    // but we need to fallback when the iteration is done
    // because we don't want to apply the fallback each iteration
    // it's not like our css file is the first css to be loaded
    else if (i == styles.length-1) {
        console.log("(Iteration: " + i + ") There is no request for template.css.");
        // fallback, make your modification
    }
}

TL; DR 버전

var styles = document.styleSheets;
for (var i = 0; i < styles.length; i++) {
    if (styles[i].href.match("css-file-name-here")) {
        if (styles[i].cssRules != null && styles[i].cssRules.length == 0) {
            // request for css file failed, make modification
            break;
        }
    } else if (i == styles.length-1) {
        // there is no request for the css file, make modification
    }
}

업데이트 : 내 답변이 몇 개의 찬성표를 얻었고 이로 인해 코드가 수정되었으므로 업데이트하기로 결정했습니다.

// document.styleSheets holds the style sheets from LINK and STYLE elements
for (var i = 0; i < document.styleSheets.length; i++) {

    // Checking if there is a request for the css file
    // We iterate the style sheets with href attribute that are created from LINK elements
    // STYLE elements don't have href attribute, so we ignore them
    // We also check if the href contains the css file name
    if (document.styleSheets[i].href && document.styleSheets[i].href.match("/template.css")) {

        console.log("There is a request for the css file.");

        // Checking if the request is unsuccessful
        // There is a request for the css file, but is it loaded?
        // If it is, the length of styleSheets.cssRules should be greater than 0
        // styleSheets.cssRules contains all of the rules in the css file
        // E.g. b { color: red; } that's a rule
        if (document.styleSheets[i].cssRules.length == 0) {

            // There is no rule in styleSheets.cssRules, this suggests two things
            // Either the browser couldn't load the css file, that the request failed
            // or the css file is empty. Browser might have loaded the css file,
            // but if it's empty, .cssRules will be empty. I couldn't find a way to
            // detect if the request for the css file failed or if the css file is empty

            console.log("Request for the css file failed.");

            // There is a request for the css file, but it failed. Fallback
            // We don't need to check other sheets, so we break;
            break;
        } else {
            // If styleSheets.cssRules.length is not 0 (>0), this means 
            // rules from css file is loaded and the request is successful
            console.log("Request for the css file is successful.");
            break;
        }
    }
    // If there isn't a request for the css file, we fallback
    // But only when the iteration is done
    // Because we don't want to apply the fallback at each iteration
    else if (i == document.styleSheets.length - 1) {
        // Fallback
        console.log("There is no request for the css file.");
    }
}

TL; DR

for (var i = 0; i < document.styleSheets.length; i++) {
    if (document.styleSheets[i].href && document.styleSheets[i].href.match("/template.css")) {
        if (document.styleSheets[i].cssRules.length == 0) {
            // Fallback. There is a request for the css file, but it failed.
            break;
        }
    } else if (i == document.styleSheets.length - 1) {
        // Fallback. There is no request for the css file.
    }
}

수락 된 답변에 대해 JFK가 작성한 의견을 확인하십시오.

나는 질문을 "요소가 존재하는지 확인하는 방법"보다는 "css 파일이로드되었는지 확인하는 방법"으로 이해했다.

요소가 존재할 수 있지만 경로도 정확할 수 있지만 이것이 CSS 파일이 성공적으로로드되었음을 의미하지는 않습니다.

를 통해 링크 요소에 액세스 getElementById하면 CSS 파일 내에 정의 된 스타일을 확인 / 읽을 수 없습니다.

스타일이 성공적으로로드되었는지 확인하려면 getComputedStyle(또는 currentStyleIE 용) 을 사용해야 합니다.

HTML

//somewhere in your html document

<div id="css_anchor"></div>

CSS

//somewhere in your main stylesheet

#css_anchor{display:none;}

자바 스크립트

//js function to check the computed value of a style element

function get_computed_style(id, name){

        var element = document.getElementById(id);

        return element.currentStyle ? element.currentStyle[name] : window.getComputedStyle ? window.getComputedStyle(element, null).getPropertyValue(name) : null;

}

 //on document ready check if #css_anchor has been loaded

    $(document).ready( function() {

            if(get_computed_style('css_anchor', 'display')!='none'){

            //if #css_anchor style doesn't exist append an alternate stylesheet

                var alternateCssUrl = 'http://example.com/my_alternate_stylesheet.css';

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

                stylesheet.href = alternateCssUrl;
                stylesheet.rel = 'stylesheet';
                stylesheet.type = 'text/css';
                document.getElementsByTagName('head')[0].appendChild(stylesheet);

            }
    });

답변의 일부는 다음과 같습니다. myDiv.style.display가 마스터 스타일 시트에 설정되면 공백을 반환합니다 .

데모 : http://jsfiddle.net/R9F7R/


다음과 같은 작업이 수행됩니다 (jQuery 사용).

function checkStyleSheet(url){
   var found = false;
   for(var i = 0; i < document.styleSheets.length; i++){
      if(document.styleSheets[i].href==url){
          found=true;
          break;
      }
   }
   if(!found){
       $('head').append(
           $('<link rel="stylesheet" type="text/css" href="' + url + '" />')
       );
   }
}

위의 모든 멋진 답변 외에도 마크 업과 CSS 파일에 더미 요소를 넣고 기본값이 아닌 다른 스타일을 지정할 수 있습니다. 그런 다음 코드에서 속성이 더미 요소에 적용되었는지 확인하고 그렇지 않은 경우 CSS를로드합니다. 하지만 당신이 원하는 일을하는 깔끔한 방법이 아니라 생각 만하십시오.


내 2 센트. CSS에 설정된 규칙이 있는지 여부를 확인하여 성공적으로로드되었는지 여부를 의미합니다.

if(jQuery("link[href='/style.css']").prop('sheet').cssRules.length == 0){
    //Load the css you want
}

문서 객체에는로드 된 모든 스타일 시트가있는 스타일 시트 컬렉션이 포함되어 있습니다.

참조는 http://www.javascriptkit.com/domref/stylesheet.shtml을 참조하십시오 .

이 컬렉션을 반복하여 확인하려는 스타일 시트가 그 안에 있고 브라우저에 의해로드되는지 확인할 수 있습니다.

document.styleSheets[0] //access the first external style sheet on the page

하지만주의해야 할 몇 가지 브라우저 비 호환성 문제가 있습니다.


한 가지 방법 : document.getElementsByTagName("link")각각에 대해 반복을 사용 하고 확인한 hrefCSS 파일과 동일한 지 확인하십시오.

또 다른 방법 : CSS 규칙이 해당 파일에만 설정되어 있다는 것을 알고 있다면이 규칙이 실제로 적용되는지 확인하십시오. 예를 들어 무언가의 배경이 정말 빨간색인지 확인하십시오.


다음과 같이 파일 이름이 마크 업 내에 있는지 확인할 수 있습니다.

var lnks    = document.getElementsByTagName('link'),
    loadcss = true;

for(var link in lnks) {
    href = link.getAttribute('href');

    if( href.indexOf('foooobar.css') > -1) ){
            loadcss = false;
            return false;
    }
});

if( loadcss ) {
        var lnk     = document.createElement('link'),
            head    = document.getElementsByTagName('head')[0] || document.documentElement;        

        lnk.rel     = 'stylesheet';
        lnk.type    = 'text/css';
        lnk.href    = '//' + location.host + 'foooobar.css';            

        head.insertBefore(lnk, head.firstChild);
}

또는 className스타일 시트가로드 된 경우 사용할 수 있어야 하는 특정 항목 확인할 수 있습니다. 이것은 아마도 기능 감지에 조금 더 가까워 질 것입니다.


var links = document.getElementsByTagName('link');
var file  = 'my/file.css';
var found = false;

for ( var i in links )
{
    if ( links[i].type == 'text/css' && file == links[i].href ) {
        found = true; break;
    }
}

if ( !( found ) ) {
    var styles = document.getElementsByTagName('style');
    var regexp = new RegExp('/\@import url\("?' + file + '"?\);/');

    for ( var i in styles )
    {
        if ( styles[i].src == file ) {
            found = true; break;
        } else if ( styles[i].innerHTML.match(regexp) ) {
            found = true; break;
        }
    }
}

if ( !( found ) ) {
    var elm = document.createElement('link');
        elm.href = file;
    document.documentElement.appendChild(elm);
}

For a nice consistent and repeatable experience, I've written these two jQuery plugins that mimic the $.getScript(url, callback) jQuery method (however they will NOT force reloading from the server like $.getScript(). There are two methods: one that will load a CSS file anytime it's called, and one that will only load it once. I find the former handy during development when I'm making changes, and the latter great for a speedy deployment.

/**
 * An AJAX method to asynchronously load a CACHED CSS resource
 * Note: This removes the jQuery default behaviour of forcing a refresh by means
 * of appending a datestamp to the request URL. Actual caching WILL be subject to
 * server/browser policies
 */
$.getCachedCss = function getCachedCss(url, callback)
{
    $('<link>',{rel:'stylesheet', type:'text/css', 'href':url, media:'screen'}).appendTo('head');

    if (typeof callback == 'function')
        callback();
}

/**
 * An AJAX method to asynchronously load a CACHED CSS resource Only ONCE.
 * Note: This removes the jQuery default behaviour of forcing a refresh by means
 * of appending a datestamp to the request URL. Actual caching WILL be subject to
 * server/browser policies
 */
$.getCachedCssOnce = function getCachedCssOnce(url, callback)
{
    if (!$("link[href='" + url + "']").length) {
        $.getCachedCss(url, callback);

        if (typeof callback == 'function')
            callback();
    }
}

Usage example:

$(function() {
    $.getCachedCssOnce("pathToMyCss/main.css");
)}

Usage example with callback:

$(function() {
    $.getCachedCssOnce("pathToMyCss/main.css", function() {
        // Do something once the CSS is loaded
});

use .sheet in jQuery:

HTML:

<link rel="stylesheet" href="custom.css">

jQuery:

if($("link[href='custom.css']")[0].sheet.cssRules.length==0){
//custom.css was not loaded, do your backup loading here
}

simple way using javascript..,

loadCssIfNotLoaded('https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css');
loadCssIfNotLoaded('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css');

function loadCssIfNotLoaded(url) {
    var element=document.querySelectorAll('link[href="' + url + '"]');
    if (element.length == 0)
    {
        var link = document.createElement('link');
        link.rel = 'stylesheet';
        link.href = url;
        document.getElementsByTagName("head")[0].appendChild(link);
    }
}

In one line, with jQuery. If the #witness div is visible, we have to load the css file.

In the HTML, we have a:

<div id="witness"></div>

In the CSS file to load, we have:

  #witness{display:none;}

So, if the css file is loaded, the #witness div is not visible. We can check with jQuery and make decision.

!$('#witness').is(':visible') || loadCss() ;

As a snippet:

function loadCss(){
  //...
  console.log('Css file required');
};


!$('#witness').is(':visible') || loadCss();
#witness{display:none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<div id="witness"></div>

ReferenceURL : https://stackoverflow.com/questions/4724606/how-to-use-javascript-to-check-and-load-css-if-not-loaded

반응형