Arka Uça Bir Widget Eklendiğinde Javascript Çalıştırmak


20

Ekli javascript denetimleri olan widget'ları var.

Pencere öğesi yönetici sayfası yüklendiğinde pencere öğesi varsa, denetimler düzgün çalışır.

Yeni bir widget eklediğimde, düzgün çalışmıyorlar, biçimlendirmeyi alıyorum, ancak hiçbir javascript etkinliği etkili olmuyor.

Yeni widget'ı kaydedersem, form yeniden yüklendiğinde, denetimler doğru şekilde oluşturulur ve şimdi çalışır.

Sayfanın yenilenmesi sorunu da giderir, ancak yalnızca mevcut widget'lar için. Yeni widget'larda bu sorun hala var.

Özellikle bu noktalarda seçili girişlerde selectize çalıştırıyorum:

  • belge hazır
  • Ajaxcomplete

Kodumun her olayda istendiği gibi çalıştırıldığını doğruladım, ancak sonuçlar beklendiği gibi değil.

İşte sorunu gösteren bir test eklentisi:

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

Dönüşüm sağlayabildiği her seçme öğesi ile artan bir sayacım olduğunu göreceksiniz.

Notlar:

  • Widget sayfası yüklendiğinde, sayacın beklendiği gibi JS konsolunda arttığını görebiliyorum
  • Yeni bir widget eklediğimde, kod çalıştırılır, ancak found.length 0 ile gösterildiği gibi üzerinde çalışabileceği herhangi bir seçim öğesini bulamaz. Bu durum, bu türdeki her yeni widget'ın seçme elemanı var
  • select öğelerinin onları tanımlamak için bir sınıfı vardır, bu sınıf, varolan widget'larda çoğaltmayı ve yeniden işlemeyi önlemek için select kütüphanesi uygulandıktan sonra kaldırılır.
  • Select'i kullanmadan önce, aynı sorunu yaşayan Select2'yi kullandım
  • AJAX kodu yorum, ben yeni widget standart bir seçim girişi olmasını beklenir. Onlar yapmıyor. Neden böyle olduğunu bilmiyorum

Öyleyse kullanıcıya değişiklik yapmadan önce kaydetmeyi yenilemesini / tıklamasını bildirmeden seçme denetimini nasıl çalıştırabilirim?


Bu bir etkinlik yetkilendirme sorunu. JQuerys .on()yöntemini kullanarak bakmanız gerekecektir . Bu, bir olayı belgeye bağlamanızı gerektirir. Ancak hangi olayın uygun olacağından emin değilim. Sonuçta, orijinal bağlarınızın sayfa yüklendiğinde DOM'un ilk sürümünü temsil etmesi ve çoğunlukla ajax yoluyla eklenen yeni öğelere (widget içeriği) kör olmasından kaynaklanır. Umarım bu sizi doğru yöne yönlendirir, eğer değilse işteyken daha iyi cevap verebilirim.

Beklediğim budur jQuery( document ).ajaxStop( function() {ve yeni yüklenen widget'lardaki denetimleri başlatabilmek için parçayı neden ekledim . Ancak bu satırı kaldırsaydım, yeni widget'ların standart HTML seçme girişlerine sahip olmasını beklerdim, ancak = s
Tom J Nowell

@ Aaron-holbrook'un yorumladığı gibi, yaklaşımı widget-updatedve widget-addedolaylarını kullanarak en temiz yaklaşımdır . Ayrıca @michaeljames kodunda, element id kullanımını vurgulamak istiyorum #widgets-right. JS kodunuzdaki etkin widget öğelerini hedeflemek için kullandığınızdan emin olun, aksi takdirde kodunuz ekranın sol tarafında gizli etkin olmayan widget öğelerini de seçebileceğinden (ve widget eklendiğinde klonlanır).
Julien

Yanıtlar:


12

Harika haber,

Ben düzelttim.

İlk yorumumda özleminizi kaçırdığınız için özür diler ve daha önce uyguladığınız bir cevabı verirsiniz. Bu bana bir trendeyken telefonuma cevap vermeyi öğretecek!

Ajaxstop kullanımınız doğrudur. Cehennem JS çoğunlukla doğru çalışıyor, css stilleri başlatıldı ve DOM değişiklikleri görebilirsiniz.

Sorun aslında seçicinizde yatıyor.

Bunun nedeni, widget içeriğinin ajax aracılığıyla yüklenmemesidir, aslında gizli olduğu sol sütundan klonlar ve ardından widget'ın konumunu sağ sütuna kaydetmek için bir ajax çağrısı başlatır. Bu, ajaxstop'un neden bir tedavi yaptığını, hatta içerik klonlanmış olduğunu bile açıklıyor. Ancak, sol sütunda widget'ın gizli bir sürümü bulunduğundan, JS'niz bunu başlatır. Bu nedenle, sağ sütuna sürüklediğinizde, gizli widget'ın karıştırılmış bir klonunu alıyorsunuz.

Böylece sol taraftaki birini seçmeniz gerekir. Düzeltilmiş kod aşağıdadır:

<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>

Kutsal moly, bunu test etmeye gitmem gerek <3
Tom J Nowell

Büyük bir baş ağrısına çok zarif bir çözüm!
Bosco

3
Her bir 'ajaxStop' etkinliğinde çalışmamanızı tavsiye ederim ve bunun yerine 'widget-eklenen' yanı sıra 'widget-güncellenmiş' olayları kullanmanızı öneririz.
Tyrun

16

@ Aaron-holbrook'un yorumladığı gibi, daha temiz bir yaklaşımın yapılması:

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

Çoğu durumda, sayfa yüklendiğinde ve widget'lar güncellendiğinde JS'yi çalıştırmak isteyeceksiniz. Bunu böyle yapabilirsiniz.

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

Buraya referans olarak yapıştırmak, cevapları bulmak çok daha kolay


2
muhtemelen $ yerine jQuery kullanmalıdır
Mark Kaplun
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.