programing

jquery가 로드될 때까지 스크립트 실행을 대기시키는 방법

starjava 2023. 8. 5. 09:44
반응형

jquery가 로드될 때까지 스크립트 실행을 대기시키는 방법

페이지가 너무 빨리 로드되고 후속 스크립트에서 호출되기 전에 jquery가 로드를 완료하지 못하는 문제가 있습니다.jquery가 있는지 확인하고 없으면 잠시 기다렸다가 다시 해보는 방법이 있나요?


아래 답변/댓글에 대한 답변으로 마크업의 일부를 게시합니다.

상황은... asp.net 마스터 페이지와 하위 페이지입니다.

마스터 페이지에 jquery에 대한 참조가 있습니다.그러면 내용 페이지에 페이지별 스크립트에 대한 참조가 있습니다.페이지별 스크립트를 로드할 때 "$가 정의되지 않았습니다."라고 불평합니다.

마크업의 여러 지점에 경고를 표시하여 발사되는 순서를 확인하고 다음과 같은 순서로 실행되는 것을 확인했습니다.

  1. 마스터 페이지 머리글입니다.
  2. 하위 페이지 내용 블록 1(마스터 페이지의 머리 부분에 위치하지만 마스터 페이지 스크립트가 호출된 후).
  3. 하위 페이지 컨텐츠 블록 2.

마스터 페이지 상단의 마크업은 다음과 같습니다.

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="SiteMaster" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Reporting Portal</title>
    <link href="~/Styles/site.css" rel="stylesheet" type="text/css" />
    <link href="~/Styles/red/red.css" rel="stylesheet" type="text/css" />
    <script type="text/Scripts" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> 
    <script type="text/Scripts" language="javascript" src="../Scripts/jquery.dropdownPlain.js"></script>
    <script type="text/Scripts" language="javascript" src="../Scripts/facebox.js"></script>
    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
</head>

그런 다음 마스터 페이지 본문에 추가 ContentPlaceHolder가 있습니다.

 <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
                </asp:ContentPlaceHolder>

하위 페이지에서는 다음과 같이 표시됩니다.

<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Dashboard.aspx.cs" Inherits="Data.Dashboard" %>
<%@ Register src="../userControls/ucDropdownMenu.ascx" tagname="ucDropdownMenu" tagprefix="uc1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
    <link rel="stylesheet" type="text/css" href="../Styles/paserMap.css" />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
***CONTENT HERE***
    <script src="../Scripts/Dashboard.js" type="text/javascript"></script>
</asp:Content>

다음은 "..."의 내용입니다./Script/Dashboard.js" 파일:

    $(document).ready(function () {

    $('.tgl:first').show(); // Show the first div

    //Description: East panel parent tab navigation
    $('.tabNav label').click(function () {
        $('.tabNav li').removeClass('active')
        $(this).parent().addClass('active');

        var index = $(this).parent('li').index();
        var divToggle = $('.ui-layout-content').children('div.tgl');

        //hide all subToggle divs
        divToggle.hide();
        divToggle.eq(index).show();
    });

});

파티에 늦었고 Briguy37의 질문과 유사하지만, 향후 참조를 위해 다음 방법을 사용하고 jQuery가 로드될 때까지 연기하고 싶은 기능을 전달합니다.

function defer(method) {
    if (window.jQuery) {
        method();
    } else {
        setTimeout(function() { defer(method) }, 50);
    }
}

다음 시간까지 50ms마다 지연 메서드를 재귀적으로 호출합니다.window.jQuery종료하고 호출하는 시간에 존재합니다.method()

익명 함수의 예:

defer(function () {
    alert("jQuery is now loaded");
});

가장 쉽고 안전한 방법은 다음과 같은 것을 사용하는 것입니다.

var waitForJQuery = setInterval(function () {
    if (typeof $ != 'undefined') {

        // place your code here.

        clearInterval(waitForJQuery);
    }
}, 10);

지연 특성을 사용하여 실제 끝에 스크립트를 로드할 수 있습니다.

<script type='text/javascript' src='myscript.js' defer='defer'></script>

그러나 일반적으로 스크립트를 올바른 순서로 로드하면 효과가 있으므로 자신의 스크립트 앞에 jquery 포함을 배치해야 합니다.

코드가 페이지에 있고 별도의 js 파일에 없기 때문에 문서가 준비된 후에만 스크립트를 실행해야 하며 코드를 캡슐화하면 다음과 같이 작동합니다.

$(function(){
//here goes your code
});

Darbio의 연기 방법이 더 유연하긴 하지만 이를 위한 또 다른 방법입니다.

(function() {
  var nTimer = setInterval(function() {
    if (window.jQuery) {
      // Do something with jQuery
      clearInterval(nTimer);
    }
  }, 100);
})();

온로드 이벤트를 시도할 수 있습니다.모든 스크립트가 로드되었을 때 발생합니다.

window.onload = function () {
   //jquery ready for use here
}

그러나 window.onload에서 사용하는 다른 스크립트를 무시할 수 있습니다.

제안된 솔루션은 비동기 코드를 염두에 둔 상태에서만 작동한다는 것을 알게 되었습니다.다음은 두 가지 경우에 모두 사용할 수 있는 버전입니다.

document.addEventListener('DOMContentLoaded', function load() {
    if (!window.jQuery) return setTimeout(load, 50);
    //your synchronous or asynchronous jQuery-related code
}, false);

편집을

스크립트 태그에 맞는 유형을 사용해 볼 수 있습니까?당신이 사용하는 것을 봅니다.text/ScriptsJavascript에 적합한 MIME 유형이 아닙니다.

사용:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> 
<script type="text/javascript" src="../Scripts/jquery.dropdownPlain.js"></script>
<script type="text/javascript" src="../Scripts/facebox.js"></script>

편집 종료

아니면 당신은 당신의 자바스크립트 코드를 위한 로더인 require.js를 볼 수 있습니다.

하지만 당신의 프로젝트에 따라, 이것은 약간 과잉 살상일 수 있습니다.

보다는 "기다려"를 setTimeout창하여 이 도 있습니다.), 를 참조하십시오.이는 다음을 사용하여 정의된 속성 정의를 통해 달성할 수 있습니다.Object.defineProperty.

(function(){
  var _jQuery;
  Object.defineProperty(window, 'jQuery', {
    get: function() { return _jQuery; },
    set: function($) {
      _jQuery = $;

      // put code or call to function that uses jQuery here

    }
  });
})();

사용:

$(document).ready(function() {
    // put all your jQuery goodness in here.
});

자세한 내용은 다음을 참조하십시오. http://www.learningjquery.com/2006/09/introducing-document-ready

참고: JQuery 라이브러리에 대한 스크립트 가져오기가 이 호출을 초과하는 경우 이 작업이 수행됩니다.

업데이트:

어떤 이유로 코드가 동기적으로 로드되지 않는 경우(어느 것이 저는 만난 적이 없지만 아래 댓글을 보면 가능할 것 같습니다. 발생하면 안됨), 다음과 같이 코드화할 수 있습니다.

function yourFunctionToRun(){
    //Your JQuery goodness here
}

function runYourFunctionWhenJQueryIsLoaded() {
    if (window.$){
        //possibly some other JQuery checks to make sure that everything is loaded here

        yourFunctionToRun();
    } else {
        setTimeout(runYourFunctionWhenJQueryIsLoaded, 50);
    }
}

runYourFunctionWhenJQueryIsLoaded();

일반적인 문제입니다. 멋진 PHP 템플릿 엔진을 사용하여 기본 레이아웃을 사용한다고 가정해 보십시오.

HEADER
BODY ==> dynamic CONTENT/PAGE
FOOTER

그리고 물론 당신은 페이지 하단에 Javascript를 로드하는 것이 더 낫다는 것을 어디선가 읽을 수 있습니다. 그래서 당신의 동적 콘텐츠는 누가 jQuery(또는 $)인지 알지 못합니다.

또한 당신은 어디선가 작은 자바스크립트를 줄 세우는 것이 좋기 때문에, 페이지에 jQuery가 필요하다고 상상해 보세요, baboom, $는 정의되지 않습니다 (..아직 ^^).

Facebook이 제공하는 솔루션이 마음에 듭니다.

window.fbAsyncInit = function() { alert('FB is ready !'); }

따라서 게으른 프로그래머(훌륭한 프로그래머 ^^라고 할 수 있습니다)는 동등한 기능(페이지 내)을 사용할 수 있습니다.

window.jqReady = function() {}

그리고 레이아웃 하단에 jQuery 다음을 추가합니다.

if (window.hasOwnProperty('jqReady')) $(function() {window.jqReady();});

저는 중간중간에 하는 것을 별로 좋아하지 않습니다.제가 재쿼리를 연기하고 싶을 때, 혹은 실제로는 이런 식으로 진행됩니다.

시작:

<html>
 <head>
  <script>var $d=[];var $=(n)=>{$d.push(n)}</script>
 </head>

그러면:

 <body>
  <div id="thediv"></div>

  <script>
    $(function(){
       $('#thediv').html('thecode');
    });
  </script>

  <script src="http://code.jquery.com/jquery-3.2.1.min.js" type="text/javascript"></script>

마지막으로:

  <script>for(var f in $d){$d[f]();}</script>
 </body>
<html>

아니면 덜 떨리는 버전:

<script>var def=[];function defer(n){def.push(n)}</script>
<script>
defer(function(){
   $('#thediv').html('thecode');
});
</script>
<script src="http://code.jquery.com/jquery-3.2.1.min.js" type="text/javascript"></script>
<script>for(var f in def){def[f]();}</script>

그리고 비동기의 경우 jquery on load에서 푸시된 기능을 실행할 수 있습니다.

<script async onload="for(var f in def){def[f]();}" 
src="jquery.min.js" type="text/javascript"></script>

또는 다음과 같습니다.

function loadscript(src, callback){
  var script = document.createElement('script');
  script.src = src
  script.async = true;
  script.onload = callback;
  document.body.appendChild(script);
};
loadscript("jquery.min", function(){for(var f in def){def[f]();}});

확장합니다.defer()다리오에서 더 재사용할 수 있습니다.

function defer(toWaitFor, method) {
    if (window[toWaitFor]) {
        method();
    } else {
        setTimeout(function () { defer(toWaitFor, method) }, 50);
    }
}

그런 다음 실행:

function waitFor() {
    defer('jQuery', () => {console.log('jq done')});
    defer('utag', () => {console.log('utag done')});
}

그건 당신 문제가 아닌 것 같아요.스크립트 로드는 기본적으로 동기화되므로 사용하지 않는 한defer다른 AJAX 요청을 통해 jQuery 자체를 로드하거나 속성을 지정합니다. 당신의 문제는 아마도 404에 더 가깝습니다.당신은 당신의 마크업을 보여줄 수 있습니까? 그리고 만약 당신이 파이어버그나 웹 인스펙터에서 의심스러운 것을 본다면 우리에게 알려줄 수 있습니까?

확인:

https://jsfiddle.net/neohunter/ey2pqt5z/

가짜 jQuery 객체를 생성하여 jquery의 onload 메서드를 사용할 수 있으며 jquery가 로드되는 즉시 실행됩니다.

그건 완벽하지 않다.

// This have to be on <HEAD> preferibly inline
var delayed_jquery = [];
jQuery = function() {
  if (typeof arguments[0] == "function") {
    jQuery(document).ready(arguments[0]);
  } else {
    return {
      ready: function(fn) {
        console.log("registering function");
        delayed_jquery.push(fn);
      }
    }
  }
};
$ = jQuery;
var waitForLoad = function() {
  if (typeof jQuery.fn != "undefined") {
    console.log("jquery loaded!!!");
    for (k in delayed_jquery) {
      delayed_jquery[k]();
    }
  } else {
    console.log("jquery not loaded..");
    window.setTimeout(waitForLoad, 500);
  }
};
window.setTimeout(waitForLoad, 500);
// end



// now lets use jQuery (the fake version)
jQuery(document).ready(function() {
  alert('Jquery now exists!');
});

jQuery(function() {
  alert('Jquery now exists, this is using an alternative call');
})

// And lets load the real jquery after 3 seconds..
window.setTimeout(function() {
  var newscript = document.createElement('script');
  newscript.type = 'text/javascript';
  newscript.async = true;
  newscript.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js';
  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(newscript);
}, 3000);

부하가 사용하는 접근 방식에 대한 접선 메모setTimeout또는setInterval이러한 경우 검사를 다시 실행할 때 DOM이 이미 로드되고 브라우저가DOMContentLoaded이벤트가 발생하므로 이러한 접근 방식을 사용하여 해당 이벤트를 안정적으로 탐지할 수 없습니다.제가 찾은 것은 jQuery의ready그래도 여전히 작동하기 때문에 당신은 당신의 일상을 담을 수 있습니다.

jQuery(document).ready(function ($) { ... }

마음속에setTimeout또는setInterval모든 것이 정상적으로 작동해야 합니다.

언급URL : https://stackoverflow.com/questions/7486309/how-to-make-script-execution-wait-until-jquery-is-loaded

반응형