5

I've seen a lot of different questions similar to this, but all of them generally targeted a specific selector. Please let me know if there is a duplicate somewhere and I've missed it.

Take this scenario:

You want to build a jquery plugin for a wordpress, drupal, or basically any site that uses third party functionality. Since you don't know ahead of time every specific event and selector you will need to target how would you add jquery/javascript functionality to elements that are created dynamically. Plus you don't know how the element is created (callback using ajax/php/etc).

Example:

I recently tried adding select2 or selectize to my entire site. Unfortunately, since I can't determine ahead of time when select elements (from other plugins/modules) will be added, I can't ensure that the select jquery will work on newly created selects.

Select2

This is the normal way but doesn't work on dynamically created or cloned selects:

<script type='text/javascript'>
    jQuery(document).ready(function($) {
        $("select").select2();
    });
</script>

If I knew all the events that added these selects I could simply do the following:

 $( ".some_button_that_creates_new_selects" ).on( "click", function() {
        jQuery("select").select2(); 
    });
 });

However, since I don't know all the selectors of dynamic selects ahead of time (since many are added by 3rd party plugins), select2 will not work on new selects. So the above would only work on a per case senerio.

I need to find a way to traverse through the dom tree and recognize when new selects are created.

I tried targeting several events with .on but it didn't work well at all.

I read that the javascript document.getElementsByTagName recognizes changes in the dom and are reflected in the collection. I also looked into querySelectorAll, but not sure exactly how it works.

I also tried messing with the MutationObserver and checking if the .addednodes.length of select tags changed, but I didn't really get anywhere.

UPDATE

After doing some testing I realized that the problem might lie within the select2 plugin itself. Select2 loads dynamic selects but doesnt get the positioning. Chrome eventually throws typeerros : cannot read property 'find' of null, cannot read property 'hasclass' of null.

Example adding the select2 plugin to wordpress. Clicking quick edit adds new fields

New selects don't load properly. and there is no dropdown when clicking on them.

Clicking once on the select and then below it will load the select2 overlay wrong

4

2 に答える 2

6

解決:

「動的に作成された要素にjavscript / jqueryイベントを添付する」という基本的な質問に答えます。

動的に作成された要素にイベントを追加するには、要素のイベントトリガーが伝播するときに、イベントデリゲーションを利用する必要があります。

したがって、ルート要素にイベント ハンドラーをアタッチする場合 (ボディまたはこのイベントをアタッチするときに存在する任意の親要素にすることができます)

$("body").on("click","elementSelector", function(){

});

これで、動的に作成された要素からもイベントがキャプチャされます。

于 2014-06-07T09:45:10.247 に答える
2

最も簡単な解決策は、ページにコントロールを動的に追加するたびに呼び出される JavaScript で関数を作成し、その関数にチェックを配置して、イベントが新しいコンポーネントにのみ登録されるようにすることです。例えば

function registerEvents()
{
    //Get all the select events from the page and register events only on those controls which are new ..
    $("select").each(function() {

        if (!$(this).hasClass("registeredEvent")) {

              $(this).addClass("registeredEvent");
              $(this).select2();
        }
    });

}

さまざまなアプローチで同じ結果を得ることができます。

また、jqueryの.liveイベントを確認してください..新しい要素が同じタグまたはクラスで追加されると、イベントが自動的に登録されます..

于 2014-06-07T10:22:14.037 に答える