백엔드에 위젯이 추가 될 때 Javascript 실행


20

자바 스크립트 컨트롤이 첨부 된 위젯이 있습니다.

위젯 관리 페이지가로드 될 때 위젯이 있으면 컨트롤이 올바르게 작동합니다.

새 위젯을 추가하면 제대로 작동하지 않고 마크 업이 발생하지만 자바 스크립트 이벤트는 적용되지 않습니다.

새 위젯을 저장하면 양식이 다시로드 될 때 컨트롤이 올바르게 작성되어 작동합니다.

페이지를 새로 고치면 문제가 해결되지만 기존 위젯에만 해당됩니다. 새 위젯에는 여전히이 문제가 있습니다.

특히 다음과 같은 시점에서 선택 입력에서 selectize를 실행하고 있습니다.

  • 문서 준비
  • 아약스 컴플리트

원하는대로 각 이벤트에서 코드가 실행되는지 확인했지만 결과가 예상과 다릅니다.

다음은 문제를 보여주는 테스트 플러그인입니다.

https://gist.github.com/Tarendai/8466299

변환 할 수있는 모든 선택 요소와 함께 증가하는 카운터가 있음을 알 수 있습니다.

노트:

  • 위젯 페이지가로드되면 JS 콘솔에서 카운터가 예상대로 증가하는 것을 볼 수 있습니다
  • 새 위젯을 추가하면 코드가 실행되지만 found.length에서 0으로 표시되는 것처럼 실행할 수있는 선택 요소를 찾을 수 없습니다. 해당 유형의 모든 새 위젯은 선택 요소가있다
  • select 요소에는이를 식별하는 클래스가 있습니다.이 클래스는 selectize 라이브러리가 적용되면 기존 위젯에서 중복 및 재 처리를 방지하기 위해 제거됩니다.
  • selectize를 사용하기 전에 동일한 문제가있는 Select2를 사용했습니다.
  • AJAX 코드를 주석 처리하면 새 위젯에 표준 선택 입력이 필요합니다. 그들은하지 않습니다. 왜 그런지 모르겠다

그렇다면 변경하기 전에 사용자에게 저장을 새로 고치거나 클릭하도록 지시하지 않고 선택 제어 작업을 수행하려면 어떻게해야합니까?


이벤트 위임 문제입니다. jQuerys .on()메소드 를 사용하여 조사해야합니다 . 이벤트를 문서에 바인딩해야합니다. 그러나 어떤 행사가 적절한 지 지금은 확실하지 않습니다. 궁극적으로 원본 바인딩은 페이지가로드 될 때 DOM의 초기 버전을 나타내며 대부분은 아약스를 통해 추가되는 새로운 요소 (위젯 컨텐츠)에 대해 눈에 띄지 않기 때문입니다. 내가 직장에있을 때 더 잘 대답 할 수 있다면 올바른 방향으로 당신을 가리킬 수 있기를 바랍니다.

이것이 내가 기대 jQuery( document ).ajaxStop( function() {한 것과 새로로드 된 위젯에서 컨트롤을 초기화 할 수 있도록 파트를 추가 한 이유 입니다. 그러나 해당 줄을 제거하면 새 위젯에 표준 HTML 선택 입력이있을 것으로 예상되지만 = s는 아닙니다.
Tom J Nowell

@ aaron-holbrook가 언급했듯이, widget-updatedand widget-added이벤트 를 사용하여 접근 방식이 가장 깨끗 합니다. 또한 @michaeljames 코드에서 요소 id의 사용을 강조하고 싶습니다 #widgets-right. JS 코드 내에서 활성 위젯 요소 를 대상으로 지정하려면이를 사용하십시오. 그렇지 않으면 화면 왼쪽에서 숨겨진 비활성 위젯 요소를 선택할 수도 있으므로 위젯이 중복 될 수 있습니다 (위젯이 추가 될 때 복제 됨).
Julien

답변:


12

좋은 소식,

나는 그것을 고쳤다.

내 초기 의견에서 요점을 놓치고 이미 구현 한 답변을 제공 한 것에 대해 사과드립니다. 기차를 타면서 전화로 응답하도록 가르쳐 줄 것입니다!

귀하의 ajaxstop 사용이 정확합니다. 대부분의 JS가 올바르게 작동하면 CSS 스타일이 초기화되고 DOM의 변경 사항을 볼 수 있습니다.

문제는 실제로 선택기에 있습니다.

이는 위젯 컨텐츠가 ajax를 통해로드되지 않기 때문입니다. 실제로 숨겨져있는 왼쪽 열에서이를 복제 한 다음 ajax 호출을 실행하여 오른쪽 열에 위젯 위치를 저장합니다. 이것은 왜 ajaxstop이 대우를 하는가, 콘텐츠가 복제되었다고 생각 하는지를 설명합니다. 그러나 왼쪽 열에 위젯의 숨겨진 버전이 있으므로 JS가 인스턴스화됩니다. 따라서 오른쪽 열로 드래그하면 숨겨진 위젯의 엉망진창이 나타납니다.

따라서 왼쪽에서 하나를 선택해야합니다. 아래는 올바른 코드입니다.

<script>
jQuery( document ).ready( function( $ ) {
    function runSelect() {
        var found = $( '#widgets-right select.testselectize' );
        found.each( function( index, value ) {

            $( value ).selectize();
                .removeClass( 'testselectize' )
                .addClass( 'run-' + window.counter );

            console.log( $val );
            window.counter++;
        } );
    }

    window.counter = 1;

    runSelect();

    $( document ).ajaxStop( function() {
        runSelect();
    } );
} );
</script>

거룩한 몰리, 나는 이것을 테스트해야합니다 <3
Tom J Nowell

주요 두통에 대한 매우 우아한 솔루션!
bosco

3
모든 'ajaxStop'이벤트에서 실행하지 말고 'widget-added'및 'widget-updated'이벤트를 사용하는 것이 좋습니다.
Tyrun

16

@ aaron-holbrook는 다음과 같이 깔끔한 접근 방식을 언급했습니다.

jQuery(document).on('widget-updated widget-added', function(){
    // your code to run
});

대부분의 경우 위젯이 업데이트 될 때뿐만 아니라 페이지가로드 될 때 JS를 실행하려고 할 수도 있습니다. 이렇게 할 수 있습니다.

function handle_widget_loading(){
   // your code to run
}
jQuery(document).ready( handle_widget_loading );
jQuery(document).on('widget-updated widget-added', handle_widget_loading );

답변을 참조하기 위해 여기에 붙여 넣기하면 해당 의견을 찾기가 훨씬 쉽습니다.


2
아마도 $ 대신 jQuery를 사용해야 할 것입니다.
Mark Kaplun
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.