source

외부 스크립트가 로드되었는지 확인

lovecheck 2023. 5. 7. 11:34
반응형

외부 스크립트가 로드되었는지 확인

jquery 플러그인을 만들고 있는데 외부 스크립트가 로드되었는지 확인하고 싶습니다.이는 내부 웹 앱용이며 스크립트 이름/위치를 일관되게 유지할 수 있습니다(mysscript.js).이 플러그인은 페이지에서 여러 번 호출할 수 있는 아약스 플러그인이기도 합니다.

스크립트가 로드되지 않았는지 확인할 수 있으면 다음을 사용하여 로드합니다.

jQuery.getScript()

페이지에 동일한 스크립트가 두 번 이상 로드되지 않도록 하려면 스크립트가 로드되었는지 확인하려면 어떻게 해야 합니까?이것이 스크립트 캐싱 때문에 걱정할 필요가 없는 것입니까?

업데이트: 조직에서 이 플러그인을 사용하는 사용자를 제어할 수 없으며 스크립트가 특정 ID를 사용하거나 사용하지 않는 페이지에 존재하지 않도록 강제할 수 없지만 스크립트 이름은 항상 동일한 위치에 있습니다.스크립트 이름을 사용하여 실제로 로드되었는지 확인할 수 있기를 바랍니다.

스크립트가 전역 공간에 변수 또는 함수를 생성하는 경우 해당 변수 또는 함수의 존재를 확인할 수 있습니다.

외부 JS(글로벌 범위 내) --

var myCustomFlag = true;

실행되었는지 확인하는 방법:

if (typeof window.myCustomFlag == 'undefined') {
    //the flag was not found, so the code has not run
    $.getScript('<external JS>');
}

갱신하다

은 여존재부수있다니습인의 할 수 .<script>문의태그모선여택하두를제▁▁of▁the를 모두 선택하여 합니다.<script> 및 점검src속성:

//get the number of `<script>` elements that have the correct `src` attribute
var len = $('script').filter(function () {
    return ($(this).attr('src') == '<external JS>');
}).length;

//if there are no scripts that match, the load it
if (len === 0) {
    $.getScript('<external JS>');
}

아니면 그냥 구우셔도 됩니다..filter()셀렉터에 바로 연결되는 기능:

var len = $('script[src="<external JS>"]').length;

이에 대한 답변은 적지만, 이 솔루션을 추가할 가치가 있다고 생각합니다.그것은 몇 가지 다른 대답을 결합합니다.

저에게 중요한 점은

  • 찾기 쉽고 중복되지 않도록 #id 태그 추가
  • 스크립트를 사용하기 전에 스크립트 로드가 완료될 때까지 기다리려면 .onload()를 사용합니다.

    mounted() {
      // First check if the script already exists on the dom
      // by searching for an id
      let id = 'googleMaps'
      if(document.getElementById(id) === null) {
        let script = document.createElement('script')
        script.setAttribute('src', 'https://maps.googleapis.com/maps/api/js?key=' + apiKey)
        script.setAttribute('id', id)
        document.body.appendChild(script) 
    
        // now wait for it to load...
        script.onload = () => {
            // script has loaded, you can now use it safely
            alert('thank me later')
            // ... do something with the newly loaded script
        }      
      }
    }
    

@jasper의 대답은 전적으로 옳지만 최신 브라우저에서 표준 자바스크립트 솔루션은 다음과 같습니다.

function isScriptLoaded(src)
{
    return Boolean(document.querySelector('script[src="' + src + '"]'));
}

2021년 7월 업데이트:

위에서 승인된 솔루션은 시간이 지남에 따라 많이 변화하고 개선되었습니다.위의 제 이전 답변의 범위는 스크립트가 로드할 문서에 삽입되었는지 여부를 감지하는 것입니다(스크립트 로드가 실제로 완료되었는지 여부는 아님).

스크립트가 이미 로드되었는지 여부를 감지하려면 일반적으로 다음 방법을 사용합니다.

  1. 모든 스크립트를 동적으로 로드하는 공통 라이브러리 함수를 만듭니다.
  2. 로하기전사다용다니합음을에드▁the를 사용합니다.isScriptLoaded(src)스크립트가 이미 추가되었는지 여부를 확인합니다(예: 다른 모듈에 의해).
  3. 합니다.loadScript()스크립트 로드가 성공적으로 완료되었는지 호출 모듈에 알리기 위해 콜백 함수를 사용하는 스크립트를 로드하는 함수입니다.
  4. 또한 스크립트 로드가 실패할 경우(일시적인 네트워크 문제의 경우) 추가 논리를 사용하여 다시 시도합니다.
    1. 는 재도는제수다행니됩여를 됩니다.<script>본문에서 태그를 추가하고 다시 추가합니다.
    2. 에는,<script>태그가 본문에서 제거되었습니다.
    3. 저는 단순성을 위해 다음 코드에서 그 논리를 제거했습니다.그것은 추가하기 쉬울 것입니다.

/** 
 * Mark/store the script as fully loaded in a global variable.
 * @param src URL of the script
 */
function markScriptFullyLoaded(src) {
    window.scriptLoadMap[src] = true;
}

/** 
 * Returns true if the script has been added to the page
 * @param src URL of the script
 */
function isScriptAdded(src) {
    return Boolean(document.querySelector('script[src="' + src + '"]'));
}

/** 
 * Returns true if the script has been fully loaded
 * @param src URL of the script
 */
function isScriptFullyLoaded(src) {
    return src in window.scriptLoadMap && window.scriptLoadMap[src];
}

/** 
 * Load a script. 
 * @param src URL of the script
 * @param onLoadCallback Callback function when the script is fully loaded
 * @param onLoadErrorCallback Callback function when the script fails to load
 * @param retryCount How many times retry laoding the script? (Not implimented here. Logic goes into js.onerror function)
 */
function loadScript(src, onLoadCallback, onLoadErrorCallback, retryCount) {
    if (!src) return;
    
    // Check if the script is already loaded
    if ( isScriptAdded(src) )
    {
        // If script already loaded successfully, trigger the callback function
        if (isScriptFullyLoaded(src)) onLoadCallback();
        
        console.warn("Script already loaded. Skipping: ", src);
        return;
    }

    // Loading the script...
    const js = document.createElement('script');
    js.setAttribute("async", "");
    js.src = src;
    
    js.onload = () => {
        markScriptFullyLoaded(src)
        
        // Optional callback on script load
        if (onLoadCallback) onLoadCallback();
    };
    
    js.onerror = () => {
        // Remove the script node (to be able to try again later)
        const js2 = document.querySelector('script[src="' + src +'"]');
        js2.parentNode.removeChild(js2);
        
        // Optional callback on script load failure
        if (onLoadErrorCallback) onLoadErrorCallback();
    };

    document.head.appendChild(js);
}

해결책을 제시해 준 모든 답변 덕분에 이제 어떻게 해야 할지 알게 되었으니 매우 간단한 일이었습니다.스크립트 소스를 지정하기 위해 $.getScript()를 포기해야 했습니다.때로는 수동으로 하는 것이 가장 좋습니다.

해결책

//great suggestion @Jasper
var len = $('script[src*="Javascript/MyScript.js"]').length; 

if (len === 0) {
        alert('script not loaded');

        loadScript('Javascript/MyScript.js');

        if ($('script[src*="Javascript/MyScript.js"]').length === 0) {
            alert('still not loaded');
        }
        else {
            alert('loaded now');
        }
    }
    else {
        alert('script loaded');
    }


function loadScript(scriptLocationAndName) {
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = scriptLocationAndName;
    head.appendChild(script);
}

특정 ID로 스크립트 태그를 만든 다음 해당 ID가 있는지 확인하십시오.

또는 스크립트 태그를 반복하여 스크립트 'src'를 확인하고 해당 태그에 사용하지 않으려는 값과 동일한 값이 로드되지 않았는지 확인하십시오.

편집: 코드 예제가 유용하다는 피드백을 따릅니다.

(function(){
    var desiredSource = 'https://sitename.com/js/script.js';
    var scripts       = document.getElementsByTagName('script');
    var alreadyLoaded = false;

    if(scripts.length){
        for(var scriptIndex in scripts) {
            if(!alreadyLoaded && desiredSource === scripts[scriptIndex].src) {
                alreadyLoaded = true;
            }
        }
    }
    if(!alreadyLoaded){
        // Run your code in this block?
    }
})();

코멘트(https://stackoverflow.com/users/1358777/alwin-kesler), 에서 언급한 바와 같이, 이것은 (벤치마크가 아닌) 대안이 될 수 있습니다.

(function(){
    var desiredSource = 'https://sitename.com/js/script.js';
    var scripts = document.getElementsByTagName('script');
    var alreadyLoaded = false;

    for(var scriptIndex in document.scripts) {
        if(!alreadyLoaded && desiredSource === scripts[scriptIndex].src) {
            alreadyLoaded = true;
        }
    }
    if(!alreadyLoaded){
        // Run your code in this block?
    }
})();

글로벌 변수를 사용할 수 있는지 확인하고, 사용할 수 없는 경우 다시 확인합니다.최대 통화 스택이 초과되는 것을 방지하려면 검사에서 100ms의 시간 초과를 설정합니다.

function check_script_loaded(glob_var) {
    if(typeof(glob_var) !== 'undefined') {
    // do your thing
    } else {
    setTimeout(function() {
    check_script_loaded(glob_var)
    }, 100)
    }
}

외부 스크립트가 로드되었는지 여부를 확인하는 또 다른 방법은 jquery의 데이터 기능을 사용하고 유효성 검사 플래그를 저장할 수 있습니다.예:

if(!$("body").data("google-map"))
    {
        console.log("no js");

        $.getScript("https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=initilize",function(){
            $("body").data("google-map",true);

            },function(){
                alert("error while loading script");
            });
        }
    }
    else
    {
        console.log("js already loaded");
    }

window.addEventListener('error')를 사용하여 스크립트 로드 오류를 캡처한 후 다시 로드하는 것이 좋을 것 같습니다.CDN 서버에서 스크립트를 로드할 때 유용합니다.CDN에서 스크립트를 로드할 수 없는 경우 서버에서 스크립트를 로드할 수 있습니다.

window.addEventListener('error', function(e) {
  if (e.target.nodeName === 'SCRIPT') {
    var scriptTag = document.createElement('script');
    scriptTag.src = e.target.src.replace('https://static.cdn.com/', '/our-server/static/');
    document.head.appendChild(scriptTag);
  }
}, true);

위의 여러 답변을 사용하기 쉬운 기능으로 통합

function GetScriptIfNotLoaded(scriptLocationAndName)
{
  var len = $('script[src*="' + scriptLocationAndName +'"]').length;

  //script already loaded!
  if (len > 0)
      return;

  var head = document.getElementsByTagName('head')[0];
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = scriptLocationAndName;
  head.appendChild(script);
}

스크립트 로딩 시 오류가 발생하면 오류 로그를 듣는 것이 제 생각입니다.

const checkSegmentBlocked = (e) => {
  if (e.target.nodeName === 'SCRIPT' && e.target.src.includes('analytics.min.js')) {
      window.isSegmentBlocked = true;
      e.target.removeEventListener(e.type, checkSegmentBlocked);
  }
};
window.addEventListener('error', checkSegmentBlocked, true);
    

이 페이지의 일부 답변이 잘못되었습니다.은 그은그존확다니인합재를들들의 를 확인합니다.<script>태그 - 하지만 그것만으로는 충분하지 않습니다.이것은 스크립트 로드가 완료되었다는 것이 아니라 태그가 DOM에 삽입되었다는 것을 알려줍니다.

질문을 통해 스크립트를 삽입하는 코드와 스크립트가 로드되었는지 확인하는 코드의 두 부분이 있다고 가정합니다.

스크립트를 동적으로 삽입하는 코드:

let tag    = document.createElement('script');
tag.type   = 'text/javascript';
tag.id     = 'foo';
tag.src    = 'https://cdn.example.com/foo.min.js';
tag.onload = () => tag.setAttribute('data-loaded', true);   // magic sauce
document.body.appendChild(tag);

스크립트가 로드되었는지 확인하는 다른 코드:

let script   = document.getElementById('foo');
let isLoaded = script && script.getAttribute('data-loaded') === 'true';
console.log(isLoaded);     // true

이 두 가지(삽입 및 확인)가 모두 동일한 코드 블록에 있는 경우 위 내용을 단순화할 수 있습니다.

tag.onload = () => console.log('loaded');

코드를 시작하기 전에 시간을 절약할 수 있는 간단한 팁을 찾았습니다.웹 페이지에서 devtools를 확인하고 네트워크 탭을 클릭합니다.js 스크립트는 서버에서 200 응답으로 로드된 경우 표시됩니다.

언급URL : https://stackoverflow.com/questions/9521298/verify-external-script-is-loaded

반응형