programing tip

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

itbloger 2020. 8. 20. 07:57
반응형

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


페이지가 너무 빨리로드되는 문제가있어 jquery가 후속 스크립트에서 호출되기 전에로드가 완료되지 않았습니다. jquery의 존재를 확인하고 존재하지 않는 경우 잠시 기다렸다가 다시 시도하는 방법이 있습니까?


아래 답변 / 댓글에 대한 응답으로 일부 마크 업을 게시하고 있습니다.

상황 ... asp.net masterpage 및 childpage.

마스터 페이지에는 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();
    });

});

편집하다

스크립트 태그에 올바른 유형을 시도해 주시겠습니까? 나는 당신 text/Scripts이 자바 스크립트에 적합한 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살펴볼 수 있습니다 .

프로젝트에 따라 다소 과도 할 수 있습니다.


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

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

window.jQuery종료하고 호출 할 때까지 50ms마다 지연 메서드를 재귀 적으로 호출 합니다.method()

익명 함수의 예 :

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

defer 속성을 사용하여 실제로 마지막에 스크립트를로드 할 수 있습니다.

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

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

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

        // place your code here.

        clearInterval(waitForJQuery);
    }
}, 10);

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

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

일반적인 문제입니다. 멋진 PHP 템플릿 엔진을 사용한다고 가정하면 기본 레이아웃이 있습니다.

HEADER
BODY ==> dynamic CONTENT/PAGE
FOOTER

물론 페이지 하단에 자바 스크립트를로드하는 것이 더 나은 곳에서 읽었으므로 동적 콘텐츠는 누가 jQuery (또는 $)인지 알지 못합니다.

또한 작은 Javascript를 인라인하는 것이 좋은 곳에서 읽었으므로 페이지에 jQuery가 필요하다고 상상해보십시오. baboom, $가 정의되지 않았습니다 (.. 아직 ^^).

저는 Facebook이 제공하는 솔루션을 좋아합니다

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

따라서 게으른 프로그래머 (좋은 프로그래머라고 말해야합니다 ^^)로서 동등한 것을 사용할 수 있습니다 (페이지 내에서).

window.jqReady = function() {}

And add at the bottom of your layout, after jQuery include

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

Rather than "wait" (which is usually done using setTimeout), you could also use the defining of the jQuery object in the window itself as a hook to execute your code that relies on it. This is achievable through a property definition, defined using 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

    }
  });
})();

Use:

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

Check out this for more info: http://www.learningjquery.com/2006/09/introducing-document-ready

Note: This should work as long as the script import for your JQuery library is above this call.

Update:

If for some reason your code is not loading synchronously (which I have never run into, but apparently may be possible from the comment below should not happen), you could code it like the following.

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

I don't think that's your problem. Script loading is synchronous by default, so unless you're using the defer attribute or loading jQuery itself via another AJAX request, your problem is probably something more like a 404. Can you show your markup, and let us know if you see anything suspicious in firebug or web inspector?


Check this:

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

It will create a fake jQuery object, that allows you to use the onload methods of jquery, and they will be executed as soon as jquery is loaded.

It's not perfect.

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


I'm not super fond of the interval thingies. When I want to defer jquery, or anything actually, it usually goes something like this.

Start with:

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

Then:

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

Then finally:

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

Or the less mind-boggling version:

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

And in the case of async you could execute the pushed functions on jquery onload.

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

Alternatively:

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

A tangential note on the approaches here that load use setTimeout or setInterval. In those cases it's possible that when your check runs again, the DOM will already have loaded, and the browser's DOMContentLoaded event will have been fired, so you can't detect that event reliably using these approaches. What I found is that jQuery's ready still works, though, so you can embed your usual

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

inside your setTimeout or setInterval and everything should work as normal.

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

반응형