에이잭스된 콘텐츠에서 모든 (스크립트/함수) 강제 재실행
dr;dr
아약스컨텐츠가 취득되어 페이지에 추가됩니다.된 「」, 「」외에 「 않습니다.div
.
스크립트는 초기 페이지 로드 시 문제 없이 로드되고 실행되지만, Ajax를 통해 새로운 콘텐츠를 추가할 때는 문제가 없습니다.콘솔 오류는 발생하지 않으며 URL을 직접 방문해도 문제가 없습니다.
관련:
- AJAX Loaded 페이지에서 스크립트 강제 실행 - 특정 스크립트 1개와 관련됩니다.Cloudflare 앱의 동적 스크립트를 포함하여 모든 스크립트를 수정(refire)하고 싶다.
- Wordpress에서 jQuery 스크립트를 Ajax와 함께 사용 - 위와 같이 이것은 하나의 특정 스크립트에만 관련됩니다.
- Ajax 로드된 콘텐츠, 스크립트가 실행되고 있지 않습니다.
도입부:
WordPress 웹사이트에서 AWS(Ajaxify WordPress Site)를 사용하고 있습니다.
하면, 「」를 할 수 .div
.div
, Ajaxax 사용
html 마크업
<html>
<head></head>
<body>
<div id="page">
<header></header>
<main id="ajax"> <!-- This is what I want to ajaxify -->
<div class="container">
main page content
</div>
</main> <!-- end of ajaxfied content -->
<footer></footer>
</div> <!-- #page -->
</body>
</html>
문제
플러그인은 동작하고, 새로운 컨텐츠를 로드해 스타일링 합니다만, 문제가 있습니다.페이지 스크립트와 함수 호출 중 일부는 Ajax를 사용하는 div 외부에 있습니다.두 가지 예가 있습니다.
되어 1- 석조로 됩니다.<footer>
<html>
<head></head>
<body>
<div id="page">
<header></header>
<main id="ajax"> <!-- This is what I want to ajaxify -->
<div class="container">
main page content
</div>
</main> <!-- end of ajaxfied content -->
<footer></footer> <!-- Masonry script is loaded and called here -->
</div> <!-- #page -->
</body>
</html>
은 2-Google 지도 콜에 .<head>
<html>
<head></head> <!-- Google maps is called here -->
<body>
<div id="page">
<header></header>
<main id="ajax"> <!-- This is what I want to ajaxify -->
<div class="container">
main page content
</div>
</main> <!-- end of ajaxfied content -->
<footer></footer>
</div> <!-- #page -->
</body>
</html>
이것들은 단지 두 가지 예에 불과합니다.다른 장소에도 있어요.이러한 스크립트는 페이지에 새로고침되는 유일한 스크립트로 다시 호출되지 않습니다.<main id="ajax">
새로운 콘텐츠가 있는 동안 올바르게 렌더링하기 위해 필요한 스크립트 중 일부가 호출되지 않아 요소가 누락되거나 레이아웃이 깨집니다.
이 문제에 직면한 것은 저뿐만이 아닙니다.wordpress.org에서 플러그인 지원 포럼을 간단히 살펴보면 이 문제가 일반적인 것임을 알 수 있습니다.
주의: 플러그인에 다른 문제가 많이 있는 경우에는 수정하지 않습니다.난 다시 시작할 대본만 있으면 돼
공식적인 응답은 플러그인의 php 파일에 다음을 추가하여 스크립트를 새로고침/재실행할 수 있다는 것입니다.
$.getScript(rootUrl + 'PATH TO SCRIPT');
어느 쪽이 효과가 있는지.잘 된다.예를 들면,
$.getScript(rootUrl + '/Assets/masonry.js');
후, 「」가 아약스된 「masonry.js」의 , 되면, 됩니다.div
github에 있는 플러그인의 파일을 참조해 주세요.이 수정이 실제로 어떤 역할을 하는지 알기 쉽게 설명해 주세요(이 경우 어떤 일이 일어나는지 이해할 수 없습니다.$.getScript
★★★★★★★★★★★★★★★★★)
정리하다
공식 수정은 에이잭스된 콘텐츠에 대해 재작성해야 하는 스크립트가 3~4개 있는 경우 정상적으로 작동합니다.
이것은 내 목표에 맞지 않는다 왜냐하면
- 너무 딱딱하고 하드코드가 되어 있어
- 일부 스크립트는 Cloudflare 앱을 통해 페이지에 동적으로 추가됩니다.
할 수 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " 에서 됩니다.div
질문:.
페이지의 특정 부분만 Ajax를 통해 새로고침되었을 때 동적으로 추가된 스크립트를 포함한 모든 스크립트를 강제로 다시 실행하려면 어떻게 해야 합니까?
주의:
사전에 콜에 대한 지식이 필요하기 때문에 스크립트를 하나씩 호출하는 것을 피하려고 합니다.제가 너무 무리한 말을 하고 있는 것 같습니다만...
대부분의 조건부 스크립트가 실행되는 페이지 로드 및/또는 문서 준비 이벤트를 모방하려고 합니다(잘못된 경우 수정).
<main>
새로운 아약스 콘텐츠가 추가될 때 URL을 직접 사용하거나 다른 유사한 접근 방식을 사용하여 페이지가 로드될 때 문서에 영향을 주지 않고 html에 저장된다.참고로 플러그인이 꺼져 있는 동안 페이지의 이벤트 청취자 목록을 보여 줍니다.내가 촉발시키지 않아도 될 것들이 있다는 걸 알아참고로 덧붙였습니다.또, 이것은 어느쪽인가의 페이지에서 추출한 샘플입니다.다른 페이지는 다를 수 있습니다.
DOMContentLoaded
beforeunload
blur
click
focus
focusin
focusout
hashchange
keydown
keyup
load
message
mousedown
mousemove
mouseout
mouseover
mouseup
mousewheel
orientationchange
readystatechange
resize
scroll
submit
touchscreen
unload
여기서 선택하는 솔루션은 스크립트의 초기화 방법에 따라 달라집니다.몇 가지 일반적인 가능성이 있습니다.
스크립트의 액션은 스크립트를 로드하는 즉시 호출됩니다.이 경우 스크립트는 다음과 같습니다.
(function() { console.log('Running script...'); })();
스크립트의 작업은 일부 이벤트(예: 문서 준비(JQuery) 또는 창 온로드(JavaScript) 이벤트)에 대한 응답으로 호출됩니다.이 경우 스크립트는 다음과 같습니다.
$(window).on('load', function() { console.log('Running script...'); });
이 두 가지 가능성에 대한 몇 가지 옵션은 다음과 같습니다.
로드 즉시 실행되는 스크립트의 경우
가지 뺄 수 있어요.<script>
DOM 。사용하면 JQuery를 실행할 수 .
$('script').remove().appendTo('html');
위의 이 그 <script>
태그를 지정하면 모든 스크립트를 지속적으로 분리 및 재연결하는 무한 루프가 생성됩니다.또한 재실행하지 않는 스크립트가 있을 수 있습니다.이 경우 스크립트에 클래스를 추가하여 긍정 또는 부정으로 선택할 수 있습니다.를 들어 '예: '예: '예:
// Positively select scripts with class 'reload-on-ajax'
$('script.reload-on-ajax').remove().appendTo('html');
// Negatively select scripts with class 'no-reload'
$('script').not('no-reload').remove().appendTo('html')
이 경우 AJAX를 완료하기 위해 위의 스니펫 중 하나를 이벤트핸들러에 배치하겠습니다다음 예제에서는 AJAX 완료 이벤트 대신 버튼클릭을 사용하지만 개념은 동일합니다(이 예는 StackOverflow 샌드박스 내에서 제대로 작동하지 않으므로 최적의 결과를 위해 별도의 페이지로 로드해 보십시오).
<html>
<head></head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script class="reload-on-ajax">
console.log('Script after head run.');
</script>
<body>
<button id="reload-scripts-button">Reload Scripts</button>
</body>
<script class="reload-on-ajax">
console.log('Script after body run.');
</script>
<script>
$('#reload-scripts-button').click( () => $('script.reload-on-ajax').remove().appendTo('html') );
</script>
</html>
인라인 상태가 Import를 됨)에해 주십시오.src
attribute캐시에서 . 좋은 모든 , 、 in 、 in 、 선 、 선 、 in 、 in 、 in in 。<script>
는, AJAX 해, 의 「AJAX」라고 하는 합니다.getScript()
AJAX ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」이렇게 하면 적절한 시간(AJAX 콘텐츠 로드 후)에 스크립트를 로드/실행할 수 있습니다.
// In AJAX success event handler
$.getScript('script1.js');
$.getScript('script2.js');
이 두 가지 접근 방식의 잠재적인 문제는 스크립트의 비동기 로딩이 크로스 오리진 제한을 받는다는 것입니다.따라서 스크립트가 다른 도메인에서 호스트되고 크로스 오리진 요청이 허용되지 않으면 작동하지 않습니다.
이벤트에 응답하여 실행되는 스크립트의 경우
윈도우 로드 시 스크립트가 트리거되면 다음 이벤트를 트리거할 수 있습니다.
$(window).trigger('load');
안타깝게도 스크립트 자체가 JQuery의 Document Ready 이벤트를 사용하는 경우 수동으로 트리거할 수 있는 쉬운 방법을 알 수 없습니다.또한 스크립트가 다른 이벤트에 응답하여 실행될 수도 있습니다.
필요에 따라서, 상기의 어프로치를 조합할 수 있습니다.그리고 다른 사용자가 언급했듯이 스크립트에 호출할 수 있는 초기화 함수가 있다면 이것이 가장 깔끔한 방법입니다.
외부 스크립트에서 글로벌 초기화 함수 또는 코드 블록을 식별할 수 있는 경우 'ajax Complete' 이벤트를 살펴볼 수 있습니다.이 코드를 페이지 헤드에 넣고 초기화 함수 호출 또는 코드 블록을 ajaxComplete 콜백 안에 넣을 수 있습니다.
$(document).ajaxComplete(function(){
module1.init();
$('#my_id').module2_init({
foo : 'bar',
baz : 123
});
});
당신이 말하는 스크립트가 그렇게 사용하기 쉬운 초기 설정 기능을 가지고 있지 않고, 스크립트 로드로 초기화할 때, 모든 스크립트에서 즉시 사용할 수 있는 방법은 없을 것이라고 생각합니다.
당신이 시도할 수 있는 것은 다음과 같습니다.
masonry나 Google Map과 같은 대부분의 스크립트는 창 크기를 조정할 때 다시 시작하도록 설정되어 있습니다.따라서 에이잭스 완료 후 크기 조정 이벤트를 트리거하면 이러한 스크립트를 자동으로 다시 실행할 수 있습니다.
다음 코드를 시험합니다.
$( document ).ajaxComplete( function() {
$( window ).trigger('resize');
} );
이렇게 하면 콘텐츠 로드 후 크기 조정 이벤트가 트리거되므로 Ajax가 완료되면 스크립트가 강제로 다시 시작됩니다.
수도 , '어느 정도', '어느 정도'를 수 있어야 .DOMSubtreeModified
<main>
구성 요소를 지정합니다.
$('#ajaxed').bind('DOMSubtreeModified', function(){
//your reload code
});
그러면 새로고침 영역에 모든 스크립트를 다시 추가할 수 있습니다.
var scripts = document.getElementsByTagName('script');
for (var i=0;i<scripts.length;i++){
var src = scripts[i].src;
var sTag = document.createElement('script');
sTag.type = 'text/javascript';
sTag.src = src;
$('head').append(sTag);
}
또 다른 옵션은 자체 이벤트청취자를 생성하여 동일한 새로고침 코드를 포함하는 것입니다.
$(document).on('ajaxContentLoaded', function(){//same reload code});
그런 다음 콘텐츠가 업데이트되면 플러그인에서 이벤트를 트리거할 수 있습니다.
$(document).trigger('ajaxContentLoaded');
또는 플러그 인을 편집하여 수신기를 트리거하고 코드 베이스에 추가하여 수신기를 새로고침하지 않고 재실행해야 한다고 느끼는 모든 것을 다시 실행할 수도 있습니다.
$(document).on('ajaxContentLoaded', function(){
//Javascript object re-initialization
myObj.init();
//Just a portion of my Javascript?
myObj.somePortion();
});
솔루션이 모든 스크립트를 복제하고 있을 수 있습니다.
$(document).ajaxSuccess((event, xhr, settings) => {
// check if the request is your reload content
if(settings.url !== "myReloadedContentCall") {
return;
}
return window
.setTimeout(rejs, 100)
;
});
function rejs() {
const scripts = $('script[src]');
// or, maybe alls but not child of #ajax
// const scripts = $('*:not(#ajax) script[src]');
Array
.prototype
.forEach
.call(scripts, (script, index) => {
const $script = $(script);
const s = $('<script />', {
src: $script.attr('src')
});
// const s = $script.clone(); // should also work
return s
.insertAfter($script)
.promise()
.then(() => $script.remove()) // finally remove it
;
})
;
}
wordpress에서 브라우저 상태와 history.js를 사용하여 페이지를 새로고침하려고 할 때 이 문제가 발생했습니다.플러그인을 사용하지 않고 history.js를 직접 큐잉했습니다.
새 페이지를 클릭할 때마다 "재실행"해야 하는 JS가 수없이 많았습니다..global_scripts();
먼저 이 JS파일이 footer.php에 입력되어 있는지 확인합니다.
다음과 같이 보일 수 있습니다.
wp_enqueue_script('ajax_js', 'url/to/file.js', 'google-maps', 1, true);
제가 큐잉한 javascript는 아래와 같습니다.
jQuery(document).ready(function($) {
// scripts that need to be called on every page load
window.global_scripts = function(reload) {
// Below are samples of the javascript I ran that I needed to re run.
// This includes lazy image loading, paragraph truncation.
/* I would put your masonry and google maps code in here. */
bLazy = new Blazy({
selector: '.featured-image:not(.no-blazy), .blazy', // all images
offset: 100
});
/* truncate meeeee */
$('.post-wrapper .post-info .dotdotdot').dotdotdot({
watch: 'window'
});
}
// call the method on initial page load (optional)
//global_scripts();
});
그런 다음 페이지가 history.js로 로드되어 global_scripts()로 호출될 때마다 실행되는 JS에 접속했습니다.
사용하고 있는 플러그인도 history.js를 사용하고 있는 것 같습니다.특별히 당신의 플러그인으로 테스트한 것은 아니지만, 아래에 게재한 것(앱에서 사용하고 있는 것)을 시험해 보세요.이 파일은 위의 JS 파일과 동일합니다.
History.Adapter.bind(window, 'statechange', function() {
global_scripts();
}
내 코드는 위에 단순히 붙여진 것보다 조금 더 복잡하다.실제로 이벤트를 체크하여 어떤 콘텐츠를 로드하고 있는지 확인하고, 이를 바탕으로 특정 JS 함수를 로드합니다.새로고침되는 항목을 더 잘 제어할 수 있습니다.
주의: 함수를 선언할 때 window.global_scripts를 사용합니다.이는 이 코드를 유지하는 별도의 JS 파일이 있기 때문입니다.모든 항목이 같은 경우 이 항목을 제거할 수 있습니다.
주의 2: 이 답변은 새로고침해야 할 내용을 정확하게 알아야 한다는 것을 알고 있기 때문에 이러한 지식이 필요하지 않다는 마지막 메모를 무시합니다.그래도 답을 찾는 데 도움이 될 거예요.
간단한 답변:일반적인 방법으로는 이것을 할 수 없다.스크립트는 어떤 이벤트를 실행해야 하는지 어떻게 알 수 있습니까?
더 긴 답변:그것은 프로그램적인 질문이라기 보다는 구조적인 질문에 가깝다.원하는 기능은 누가 담당합니까?예를 들어 석조 건축을 예로 들어 보겠습니다.
Masonry.js 자체는 어떤 이벤트도 듣지 않습니다.Wordpress 플러그인의 domready에서 실행되는 masonary instance를 직접 작성해야 합니다.크기 조정 옵션을 활성화하면 크기 조정 이벤트에 청취자가 추가됩니다.그러나 실제로 필요한 것은 "DOM 콘텐츠 변경"에 대한 청취자입니다(가능한 솔루션에 대해서는 https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver 참조).masonry.js는 이러한 기능을 제공하지 않으므로 다음과 같은 옵션을 사용할 수 있습니다.
- masonry.js에서의 구현을 기다립니다(또는 직접 실행).
- masonry Wordpress 플러그인으로 구현(또는 직접 실행)을 기다립니다.
- 다른 곳에 기능 추가(템플릿, Ajax 플러그인 등) 4.
보시다시피 모든 옵션에는 수행해야 할 작업이 포함되어 있으며, 이 작업은 AJAX에서 호출된 DOM 변경을 재생하는 모든 스크립트에 대해 수행해야 합니다.
언급URL : https://stackoverflow.com/questions/45626475/force-re-firing-of-all-scripts-functions-on-ajaxed-content
'bestsource' 카테고리의 다른 글
Visual Studio Code에서 사용하는 TypeScript 버전은 무엇입니까?업데이트 방법 (0) | 2023.04.04 |
---|---|
유닛 테스트에서의 자동 배선 빈 덮어쓰기 (0) | 2023.04.04 |
jQuery에서 React.js로 전환하는 방법 (0) | 2023.04.04 |
단순 ng-include가 작동하지 않음 (0) | 2023.04.04 |
파일 또는 어셈블리 "시스템"을 로드할 수 없습니다.Net.Http, 버전=4.0.0, 문화=중립, 공개키토큰=b03f5f7f11d50a3a" (0) | 2023.04.04 |