2017-03-01 2 views
0

외부 js가 있는데 이는 내 HTML에서 div 중 하나의 내부에서 호출됩니다.외부 함수 호출 js

var script = document.createElement("script"); 
script.innerHTML = '$("body").prepend(\'<input type="hidden" id="sid" value="0">\');var vl=0;$(".sbut").click(function(){vl ++; var snew=vl;$("#sid").val(snew).trigger("change");});';   
document.head.appendChild(script); 

$("#sid").change(function(){ 
    alert("change"); 
});   

경고가 트리거되지 않은 : 그 외부 파일에서 나는 다음과 같은 코드가 있습니다. 내가 이것을 시도하면 :

var script = document.createElement("script"); 
script.innerHTML = '$("body").prepend(\'<input type="hidden" id="sid" value="0">\');var vl=0;$(".sbut").click(function(){vl ++; var snew=vl;$("#sid").val(snew).trigger("change");});$("#sid").change(function(){somef();alert("change");}); ';  
document.head.appendChild(script); 

function somef(){ 
    alert("change"); 
} 

나는 나의 함수 somef가 정의되지 않는다. 나는 이것이 내 기능의 순서로 무언가를해야한다고 생각하지만 정확히 무엇이 정확한지는 모르겠다. 누군가 적절한 방법이 무엇인지 제안 할 수 있습니까? 또한 내 외부 스크립트 (fscript.js)는 HTML에서 div 중 하나에서 호출되며 HTML에 액세스 할 수 없으므로 변경할 수 없습니다. 그래서 나는 입력과 스크립트도 덧붙인다.

+0

페이지에서 '.sbut'요소는 어디에 있습니까? 스크립트보다 페이지에서 더 낮은'.sbut' 엘리먼트는 클릭 핸들러를 부착하지 않습니다. 또한 ES2015 (또는 그로부터 추출)를 사용할 수 있다면 주사하는 HTML은 템플릿 줄을 사용하여 훨씬 쉽게 읽을 수 있습니다. 그 이유는 줄 바꿈 문자를 사용할 수 있기 때문입니다. –

+0

생각해 보니 왜이 코드를 문자열로 쓰고 스크립트 태그를 삽입하는지 이해가 안됩니다. 이미 외부 스크립트를로드 중이므로 해당 파일에 기록 할 수있는 이유가 없어야합니다. 이 스크립트의 일부로 jQuery를 주입하지 않았다면 실행 순서를 보장하기 위해 다른 스크립트 태그를 표시하지 않았습니까? –

+0

비록 스크립트 문자열 외부에서 jQuery를 사용하기 때문에 이미 페이지에로드되어 있다고 가정하고 있습니까? –

답변

0

나는 이유를 볼 수 없습니다, 당신은 동적으로 sid 요소를 추가하고, 바인드 변경 이벤트 핸들러, 내가 코멘트에서 언급 한 바와 같이 이벤트 핸들러에게

$(document).on("change","#sid",function(){ 
    alert("change"); 
}); 
+0

아직도 작동하지 않습니다 – codexy

+0

입력 값이 올바르게 변경되고 콘솔에 오류가 없지만 변경 내용이 외부 파일에 캐시되지 않습니다 – codexy

+0

변경을 완료하면 입력 상자 바깥을 클릭해야합니다. 브라우저 캐시를 지우고 시도해보십시오. 한가지 더 중요한 것은'sid'가 DOM을 통해 유일해야한다는 것입니다. –

0

를 바인딩하는 코드 아래하려고 할 때 따라서는 사용할 수 없습니다 스크립트를 문자열로 작성하고 스크립트 태그로 삽입하십시오. fscript.js이 이미로드되어 코드를 작성할 수 있으므로 페이지의 스크립트 태그에있는 것처럼 동일한 컨텍스트에서 실행됩니다.

이것이 내가 작성하는 방법입니다.

// Use an IIFE to encapsulate our code so our variables don't leak into 
 
// the global namespace. This will ensure they don't collide with 
 
// and existing JS in the page avoiding creating bugs in both our code 
 
// and the surrounding page 
 
(function() { 
 
    'use strict'; 
 

 
    var vl = 0, 
 
    // create the sid element and store a reference to the 
 
    // returned jQuery object in a variable we can use to 
 
    // refer to it later 
 
    sid = $('<input type="hidden" id="sid" value="0">'); 
 

 
    // attach the change event to sid 
 
    sid.change(function() { 
 
    alert('Change, sid is now ' + sid.val()); 
 
    });  
 

 
    // inject sid into the DOM 
 
    $('body').prepend(sid); 
 

 
    // use event delegation to add the click event for .sbut 
 
    // this will ensure that any .sbut elements in the HTML 
 
    // after this script is run will have the click handler 
 
    // If you know that .sbut will always appear above the place 
 
    // where your script runs, you could just use a normal 
 
    // jQuery selector instead. 
 
    $(document).on('click', '.sbut', function() { 
 
     vl++; 
 
     // there doesn't seem to be any need to create the 
 
     // snew var here, its value is exactly the same as vl 
 
     // at this point, just use vl 
 
     sid.val(vl).trigger('change'); 
 
    }); 
 
}());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<button class="sbut">.sbut</button>

는 나는 그 반대로 페이지 에 다른 코드를 방해하지 않도록를 캡슐화하는 코드를 포장하는 Immediately-Invoked Function Expression (IIFE) 를 사용합니다. strict mode, 을 사용하면 일반적인 유형의 버그가 발생하지 않도록하고 모범 사례를 적용하는 것이 좋습니다.

스크립트를로드 한 후에 .sbut 요소가 발생하는지 알 수 없기 때문에 클릭 이벤트를 .sbut에 첨부하기 위해 event delegation을 사용했습니다. 그럴 수도 있습니다. 스크립트가로드되기 전에 .sbut이 항상 발생한다는 것을 알고 있다면 보통 $('.sbut').click(function() {}); 처리기로 변경할 수 있습니다.