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


80

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

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

jQuery.getScript()

동일한 스크립트가 페이지에 두 번 이상로드되는 것을 원하지 않기 때문에 스크립트가로드되었는지 어떻게 확인할 수 있습니까? 이것은 스크립트 캐싱 때문에 걱정할 필요가없는 것입니까?

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


이 스레드는 SO jquery 태그 FAQ의 맨 위에 있으며 기존 스크립트를 확인하는 다양한 방법을 가지고 있습니다. stackoverflow.com/questions/1014203/… 다양한 방법에 대한 많은 피드백
charlietfl

답변:


140

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

외부 JS (전역 범위)-

var myCustomFlag = true;

그리고 이것이 실행되었는지 확인하려면 :

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

최신 정보

<script>모든 <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;

이것은 좋은 대답이었습니다. 불행히도 jquery.getScript 메서드는 소스가 지정되지 않은 스크립트를 추가합니다. 그래서 나는 그것을 찾을 수 없었습니다. 이 문제를 해결하기 위해 답변의 일부를 사용했습니다.
AGoodDisplayName

@AGoodDisplayName 콜백에서 $.getScript()확인할 수있는 전역 플래그를 설정할 수 있습니다 $.getScript('<external JS>, function () { window.myCustomFlag = true; }').. 그런 다음 특정 <script>요소 또는 myCustomFlag변수 의 존재를 확인할 수 있습니다 .
Jasper

@jasper, 예, 아마도 가장 효율적인 방법 일 것이므로 귀하의 답변을 수락하고 있습니다. 내 솔루션을 넣었습니다 (글로벌 플래그를 포함해야 함).
AGoodDisplayName

24
스크립트 src 검사는 괜찮지 만 문제는 올바른 src가있는 스크립트 태그가 있다는 것이 바로 스크립트가로드되었음을 의미하지 않는다는 것입니다. 태그 삽입은 로딩 단계의 시작일뿐입니다.
Karol

3
@Jasper 질문에서 DOM에 태그를 삽입하여 스크립트가 동적으로로드된다고 가정했습니다. 이것은 동일한 스크립트를 여러 번 삽입 할 수있는 유일한 경우입니다 (아무도 HTML에 스크립트를 삽입 한 다음 동적으로 다시로드하려고 시도하지 않음). 따라서 스크립트 태그를 삽입하면 여전히로드 될 때까지 기다립니다.이 경우 스크립트 태그의 존재 여부 만 확인하기 때문에 답변이 작동하지 않습니다.
Karol

19

@jasper의 대답은 완전히 정확하지만 최신 브라우저에서는 표준 Javascript 솔루션이 다음과 같을 수 있습니다.

function isScriptLoaded(src)
{
    return document.querySelector('script[src="' + src + '"]') ? true : false;
}

2
Boolean원하는 경우 조건부 연산자 대신 사용할 수 있습니다.
SomePerformance

1
그것은 단지가 될 수return document.querySelector('script[src="' + src + '"]');
Harshal Parekh 씨

이것은 나를 위해 작동하지 않았습니다. 예 : document.querySelector('head').append(script_el); console.log(isScriptLoaded(script_el.src)반환 true하지만 스크립트가 아직 실행되지 않았습니다.
oriadam

13

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

나에게 핵심 포인트는

  • 찾기 쉽고 중복되지 않도록 #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
        }      
      }
    }
    

2
script.onload여기서 정답입니다. 공유해 주셔서 감사합니다!
Vigs

10

저를 솔루션으로 이끄는 모든 답변 덕분에 방법을 알게 된 지금은 매우 간단했습니다. 스크립트의 소스를 지정하기 위해 $ .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);
}

6

특정 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?
    }
})();

이것은 완벽한 솔루션입니다. 두 번째를 추천합니다.
Ilyas karim

이러한 아이디어로 코드를 작성할 수 있다면 좋을 것입니다.
Ilyas karim

document.scripts가 더 빠르지 document.getElementsByTagName('script')만 테스트하지는 않았습니다
Alwin Kesler

1
@AlwinKesler, 동의했습니다. 대안으로 코드를 업데이트했습니다. 벤치 마크를 얻는 것이 좋을 것입니다.
MyStream 2010

3

외부 스크립트가로드되었는지 확인하는 또 다른 방법 은 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");
    }

3

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

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

2

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

1

다시 확인 하지 않으면 전역 변수를 사용할 수 있는지 확인하기 만하면 됩니다 . 하기 위해 최대의 호출 스택을 방지 넘었되는 100ms로 설정된 타임 아웃 체크 온 :

function check_script_loaded(glob_var) {
    if(typeof(glob_var) !== 'undefined') {
    // do your thing
    } else {
    setTimeout(function() {
    check_script_loaded(glob_var)
    }, 100)
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.