2009-12-10 4 views
5

저는 외부 JS 파일을 포함하는 데 사용되는 자바 스크립트 함수가 있지만 한 번만 사용합니다. 이러한 함수가 필요한 이유는 AJAX를 통해 일부 내용이로드 될 때 호출되기 때문에 해당 내용에 대해 페이지 특정 코드를 실행해야하기 때문입니다 (아니요, 단지 .live을 사용하면 해당 내용을 처리하지 못합니다). 이 외부 파일을로드, 함수가 호출되고,로드 할 때 해당 파일이 실행되는 :자바 스크립트 파일을 동적으로 한 번만 포함합니다.

$.include_once = function(filename) { 
    if ($("script[src='" + filename + "']").length === 0) { 
     var $node = $("<script></script>") 
      .attr({ 
       src : filename, 
       type : "text/javascript" 
      }) 
     ; 
     $(document.body).append($node); 
    } 
}; 

이 잘 작동 :

여기에 간결 단축 내 시도입니다. 완전한.

문제는 항상 외부 파일을 다시로드한다는 것입니다. 스크립트의 존재 여부를 확인하기 위해 사용하는 쿼리는 항상 아무 것도 찾지 않습니다!

이 디버깅

, 나는 몇 줄 추가 :

alert($("script").length);  // alerts: 4 
$(document.body).append($node); 
alert($("script").length);  // alerts: 4 

동적 소스 (방화범의 HTML 탭)에서 상대를, 나는 모든 스크립트 태그를 찾을 수 없습니다.

내가 이전에 포함시킨 파일 배열을 유지할 수 있다는 것을 알고 있지만, (작동하는 경우)이 같은 방법을 사용하기를 바랬습니다. JS 파일이 이런 식으로 포함됩니다.

누구나이 두 번째 발췌 문장의 동작을 설명 할 수 있습니까?

답변

5
더블 로딩 코드를 ...) 생략

jQuery는이 경우 조금 바보입니다. 그것은 당신이 기대하는 바를 전혀하지 않습니다. append($node) jQuery가 수행 할 때 :

jQuery.ajax({ 
    url: $node.src, 
    async: false, 
    dataType: "script" 
}) 

Woops! 로컬 파일 (예 : 동일한 도메인)의 경우 jQuery는 .js 파일 본문에 대해 XMLHttpRequest 표준을 수행하고 <script> 태그 (다시!)를 만드는 전체 복잡한 회신 프로세스로 "평가"하고 ""내용을으로 설정합니다. .js 파일 본문. 이것은 eval을 시뮬레이트하지만 전역 컨텍스트에서입니다.

도메인 간 파일의 경우 동일한 도메인 정책으로 인해 표준 XMLHttpRequest을 수행 할 수 없으므로 jQuery는 다시 <script> 요소를 만들고 <head>에 삽입합니다. jQuery를 위의 로컬 및 도메인 간 경우 모두에서

마침내이 일을 주위에 가져옵니다

head.removeChild(script); 

그리고 당신의 .length 확인! 파머.

문제에 따라 jQuery를 사용하지 마십시오. 그냥 해달라.

document.getElementsByTagName('head')[0] 
    .appendChild(
    document.createElement('script') 
) 
    .src = filename; 

당신이 기대하는 것, 특히 나중에 그것을 질의하는 wrt.

+0

우수한 응답. 나는 jQuery가 그 자체 또는 뭔가를 위해 너무 영리하다고 생각했다. – nickf

+0

@nickf : 대부분의 jQuery의 내부에 대해 그렇게 느낍니다. (너무 영리합니다.) 거기에 많은 악이 있습니다. –

3

여러 번 이미 해결 된 문제를 해결하려고합니다. 예를 들어 LazyLoad을 시도하십시오. jQuery에도 비슷한 플러그인이있다.

0

script-tag의 source 속성을 설정하는 대신 script 태그의 "text"속성을 설정하십시오. 모든 현대 브라우저에서 작동합니다. (실제로 사용하는 응용 프로그램은 IE6을 지원하지 않으므로이 크립에 대해 알지 못합니다 ...).

실제로는 두 가지 포함을 생략하는 코드를 추가해야합니다. 예를 들어 모든 응용 프로그램이로드 된 스크립트의 단순한 배열과 같이 매우 특정한 응용 프로그램과 왜 코드를 두 번로드해야합니까? !

var script_source_code_string = <some dynamically loaded script source code>; 
var $n = $("<script></script>"); 
$n.get(0).text = script_source_code_string; 
$(document.body).append($n); 

심지어 간단한 (JQuery와 않고,이 단계에서 내 코드는 jQuery를 모르는, 그것은 또한) 동적으로로드 할 수있다 :

var script_source_code_string = <some dynamically loaded script source code>; 
var s = document.createElement('script'); 
document.getElementsByTagName('head')[0].appendChild(s); 
s.text = script_source_code_string; 
관련 문제