programing

jQuery에 의존하는 Javascript 위젯을 알 수없는 환경에 포함하는 방법

nasanasas 2020. 12. 1. 08:08
반응형

jQuery에 의존하는 Javascript 위젯을 알 수없는 환경에 포함하는 방법


jQuery에 의존하는 자바 스크립트 위젯을 개발 중입니다. 위젯은 이미 jQuery가로드 된 페이지에로드되거나로드되지 않을 수 있습니다. 이 경우 많은 문제가 발생합니다 ...

  1. 웹 페이지에 jQuery가없는 경우 고유 한 jQuery를로드해야합니다. 그러나 이것을 할 때 미묘한 타이밍 문제가있는 것 같습니다. 예를 들어 jQuery가로드 및 실행을 완료하기 전에 내 위젯이로드되고 실행되면 jQuery is not defined오류가 발생합니다.

  2. 웹 페이지에 jQuery가 있으면 일반적으로 작업 할 수 있습니다. 그러나 jQuery 버전이 오래된 경우 직접로드하고 싶습니다. 그러나 내가 직접로드하는 경우 $변수를 밟지 않도록해야 합니다. 내가 설정 jQuery.noConflict()하고 그들의 스크립트가에 의존 $한다면, 나는 방금 그들의 페이지를 깨뜨린 것입니다.

  3. 웹 페이지가 다른 자바 스크립트 라이브러리 (예 : 프로토 타입)를 사용하는 경우 프로토 타입의 $변수도 민감해야했습니다 .

위의 모든 것 때문에 jQuery에 의존하지 않는 것이 더 쉬워 보입니다. 하지만 대부분 위젯 코드를 다시 작성해야하는 그 길을 가기 전에 먼저 조언을 구하고 싶었습니다.

타이밍 버그 및 때때로 $버그를 포함하여 내 코드의 기본 골격은 다음과 같습니다.

<script type="text/javascript" charset="utf-8">
// <![CDATA
 if (typeof jQuery === 'undefined') {
  var head = document.getElementsByTagName('head')[0];
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = '{{ URL }}/jquery.js';
  head.appendChild(script);
 }
// ]]>
</script>
<script type="text/javascript" src="{{ URL }}/widget.js"></script>

내 위젯의 구조는 다음과 같습니다.

(function($) {
 var mywidget = {
  init: function() {
   ...
  }
 };
 $(document).ready(function() {
   mywidget.init();
 });
})(jQuery);

언급 된 모든 환경에서 작동 할 수있는 위젯을 얻기위한 포인터 나 리소스가 있다면 대단히 감사하겠습니다.


몇 가지 답변과 포인터를 검토하고 유용한 jQuery 해커를 찾은 후 다음과 같은 결과를 얻었습니다.

(function(window, document, version, callback) {
    var j, d;
    var loaded = false;
    if (!(j = window.jQuery) || version > j.fn.jquery || callback(j, loaded)) {
        var script = document.createElement("script");
        script.type = "text/javascript";
        script.src = "/media/jquery.js";
        script.onload = script.onreadystatechange = function() {
            if (!loaded && (!(d = this.readyState) || d == "loaded" || d == "complete")) {
                callback((j = window.jQuery).noConflict(1), loaded = true);
                j(script).remove();
            }
        };
        (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script);
    }
})(window, document, "1.3", function($, jquery_loaded) {
    // Widget code here
});

아직로드되지 않은 경우 jQuery를로드하고 콜백에 캡슐화하여 페이지의 기존 jQuery와 충돌하지 않도록합니다. 또한 최소 버전이 사용 가능한지 확인하거나 알려진 버전 (이 경우 v1.3)을로드합니다. 트리거가 필요한 경우 jQuery가로드되었는지 여부에 대한 부울 값을 콜백 (내 위젯)에 보냅니다. 그리고 jQuery가로드 된 후에야 내 위젯을 호출하여 jQuery를 전달합니다.


참조 웹 위젯 (jQuery를 사용하여) 구축 방법 알렉스 Marandon으로합니다.

(function() {

// Localize jQuery variable
var jQuery;

/******** Load jQuery if not present *********/
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.4.2') {
    var script_tag = document.createElement('script');
    script_tag.setAttribute("type","text/javascript");
    script_tag.setAttribute("src",
        "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js");
    if (script_tag.readyState) {
      script_tag.onreadystatechange = function () { // For old versions of IE
          if (this.readyState == 'complete' || this.readyState == 'loaded') {
              scriptLoadHandler();
          }
      };
    } else { // Other browsers
      script_tag.onload = scriptLoadHandler;
    }
    // Try to find the head, otherwise default to the documentElement
    (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
    // The jQuery version on the window is the one we want to use
    jQuery = window.jQuery;
    main();
}

/******** Called once jQuery has loaded ******/
function scriptLoadHandler() {
    // Restore $ and window.jQuery to their previous values and store the
    // new jQuery in our local jQuery variable
    jQuery = window.jQuery.noConflict(true);
    // Call our main function
    main(); 
}

/******** Our main function ********/
function main() { 
    jQuery(document).ready(function($) { 
        // We can use jQuery 1.4.2 here
    });
}

})(); // We call our anonymous function immediately

What if you also want to use some jQuery plugins? Is it safe to make yourself a single file with the minified versions of the plugins, and also load those, as below? (Loaded from S3, in this particular example.)

(function(window, document, version, callback) {
  var j, d;
  var loaded = false;
  if (!(j = window.jQuery) || version > j.fn.jquery || callback(j, loaded)) {
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js";
    script.onload = script.onreadystatechange = function() {
        if (!loaded && (!(d = this.readyState) || d == "loaded" || d == "complete")) {
            window.jQuery.getScript('http://mydomain.s3.amazonaws.com/assets/jquery-plugins.js', function() {
              callback((j = window.jQuery).noConflict(1), loaded = true);
              j(script).remove();
            });
        }
    };
    document.documentElement.childNodes[0].appendChild(script)
  }
})(window, document, "1.5.2", function($, jquery_loaded) {
  // widget code goes here
});

SEE Can I use multiple versions of jQuery on the same page?


Can you use document.write() to optionally add the jQuery script to the page? That should force jQuery to load synchronously. Try this:

<script type="text/javascript" charset="utf-8">
// <![CDATA
 if (typeof jQuery === 'undefined') {
  document.write('<script src="{{ URL }}/jquery.js"><' + '/script>');
 }
// ]]>
</script>
<script type="text/javascript" src="{{ URL }}/widget.js"></script>

If you want to do the jQuery check inside your widget script then I believe the following works cross-browser:

(function() {
 function your_call($) {
  // your widget code goes here
 }
 if (typeof jQuery !== 'undefined') your_call(jQuery);
 else {
  var head = document.getElementsByTagName('head')[0];
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = '{{ URL }}/jquery.js';
  var onload = function() {
   if (!script.readyState || script.readyState === "complete") your_call(jQuery);
  }
  if ("onreadystatechange" in script) script.onreadystatechange = onload;
  else script.onload = onload;
  head.appendChild(script);
 }
})()

I know this is an old topic... but i got something faster that your hack. Try in your widget

"init": function()

that will fix the trouble


I would download the jQuery source and modify the jQuery object to another (jQueryCustom).

And then find the instance that sets the $ symbol as a jQuery object and comment that routine.

I don't know how easy or difficult could that be, but I'd sure give it a try.

(Also, check your second option, as it is not bad, the site where the widget will be executing, might have a jQuery version older than the one you need).

EDIT: I just checked the source. You just have to replace jQuery with another string (jQcustom for example). Then, try commenting this line:

_$ = window.$

And you make reference to the custom jQuery like this:

jQcustom("#id").attr(...)

참고URL : https://stackoverflow.com/questions/2170439/how-to-embed-javascript-widget-that-depends-on-jquery-into-an-unknown-environmen

반응형