初始化动态创建的select2

Initialising select2 created dynamically

我有一个 select2 下拉列表,我为其提供了一个匹配器函数。它在初始页面加载时像这样初始化:

jQuery(document).ready(function() {
    jQuery(".my_select2").select2({
        matcher: function(term, text) {...}
    });
});

在初始页面加载时可以找到。

现在,我有额外的下拉菜单(select 动态创建的元素(通过 AJAX 拉入,即 jQuery(match).load(url)。这些额外的下拉菜单不会初始化为 select2小部件,这是可以理解的,即使它们匹配原始的 select2 选择器。

那么,我如何告诉 jQuery 将这些动态创建的 select 元素视为需要初始化的 select2 项?我可以在匹配元素上设置某种 "watch" 以便每次将匹配元素添加到页面时 select2 初始化都会启动吗?

我记得 live() 前段时间在 jQuery 中介绍过,如果我理解正确的话,它支持在创建元素之前进行匹配。我从未使用过该功能,现在看来已弃用。但它确实是我正在寻找的那种东西。

这是一个WordPress插件,目前使用jQuery v1.11.2。

您可以尝试使用 DOMNodeInserted 并查找 select 或您分配给他们的 class

Demo

$('body').on('DOMNodeInserted', 'select', function () {
    $(this).select2();
});

更新

DOMNodeInserted

Deprecated This feature has been removed from the Web standards. Though some browsers may still support it, it is in the process of being dropped. Avoid using it and update existing code if possible;

建议的方法与 MutationObserver

类似

$(function() {
  $("button").on("click", function() {
    $("#dynamic-container").append($("<select><option>test</option><select/>"));
  });

  // select the target node
  var target = document.getElementById('dynamic-container');

  if (target) {
    // create an observer instance
    var observer = new MutationObserver(function(mutations) {
      //loop through the detected mutations(added controls)
      mutations.forEach(function(mutation) {
      //addedNodes contains all detected new controls
        if (mutation && mutation.addedNodes) {
          mutation.addedNodes.forEach(function(elm) {
          //only apply select2 to select elements
            if (elm && elm.nodeName === "SELECT") {
              $(elm).select2();
            }
          });
        }
      });
    }); 
    
    // pass in the target node, as well as the observer options
    observer.observe(target, {
      childList: true
    });

    // later, you can stop observing
    //observer.disconnect();
  }
});
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>


<button>Add new select</button>
  <div id="dynamic-container">

  </div>

我最近遇到了类似的情况,但用的是很平常的方式:

$(document).ready(function() {

 //function to initialize select2
  function initializeSelect2(selectElementObj) {
    selectElementObj.select2({
      width: "80%",
      tags: true
    });
  }


 //onload: call the above function 
  $(".select-to-select2").each(function() {
    initializeSelect2($(this));
  });

 //dynamically added selects

  $(".add-new-select").on("click", function() {
    var newSelect = $("<select class='select-to-select2'  multiple><option>option 1</option><option>option 2</option></select>");
    $(".select-container").append(newSelect);
    initializeSelect2(newSelect);
  });


});
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/css/select2.css" rel="stylesheet" />

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/js/select2.min.js"></script>
<div class="select-container">
  <select class='select-to-select2' multiple>
    <option value='1'>option1</option>
    <option value='2'>option2</option>
  </select>

  <select class='select-to-select2' multiple>
    <option value='1'>option1</option>
    <option value='2'>option2</option>
  </select>

</div>
<div>
  <button class="add-new-select">Add New Select</button>
</div>

在 .load 函数的情况下,找到要在 load 函数的回调中初始化的所有 select 元素,并对每个 select 元素调用 initializeSelect2。

我希望这对正在寻找简单解决方案的人有所帮助。

我按照 roshan 的解决方案解决了这个问题,但没有在函数中传递 select 对象。这是来自 ajax 调用的 table 输出。

$(document).ready(function() {

        function initSelect2() {
            $("[id^='DDAlertFreq']").select2({
                minimumResultsForSearch: Infinity,
                allowClear: false,
                theme: "bootstrap"
            });
        };

//define the dropdown and set to variable    
var DDAlertFrequency = '<select id="DDAlertFreq" ><option value="Fifteen_Minutes">15 Minutes</option><option value="Thirty_Minutes">30 Minutes</option><option value="Hour">Hour</option><option value="Two_Hours">2 Hours</option><option value="Three_Hours">3 Hours</option><option value="Four_Hours">4 Hours</option><option value="Six_Hours">6 Hours</option><option value="Eight_Hours">8 Hours</option><option value="Twelve_Hours">12 Hours</option><option value="Day">Day</option></select>'

function RetrieveUserAlerts(uid) {
                $.ajax({
                    url: 'SavedSearches.asmx/LoadUserAlerts',
                    dataType: 'json',
                    method: 'post',
                    data: { userid: uid },
                    success: function (data) {
                        var tbl = $("#tblAlerts > tbody");
                        tbl.empty();
                        $.each(data, function () {
                            userAlert.alert_idx = this['alert_idx'];
                            userAlert.Name = this['Name'];
                            userAlert.price_alert_low = this['price_alert_low'];
                            userAlert.alert_frequency = this['alert_frequency'];
                            userAlert.alert_max_per_day = this['alert_max_per_day'];
                            userAlert.alert_to_email = this['alert_to_email'];
                            userAlert.alert_to_sms = this['alert_to_sms'];
                            userAlert.active = this['active'];
                            userAlert.alert_start_date = moment(this['alert_start_date']).format("MM/DD/YY");
                            userAlert.alert_end_date = moment(this['alert_end_date']).format("MM/DD/YY");
                            userAlert.OpenSectionID = this['OpenSectionID'];
// modify the dropdown to assign unique id and match selection
                            var selectAlert = DDAlertFrequency.replace("DDAlertFreq", "DDAlertFreq_" + userAlert.alert_idx).replace('"' + userAlert.alert_frequency + '"', '"' + userAlert.alert_frequency + '" selected');
                            var tblRow = '<tr><td>'
                                + userAlert.Name
                             + '</td><td>'
                            + '<input id="txtPriceAlertLow_' + userAlert.alert_idx + '" type="text" class="form-control" value="' + userAlert.price_alert_low + '"/>'
                             + '</td><td>'
                            + '<input id="chkAlertToEmail_' + userAlert.alert_idx + '" type="checkbox" ' + ((userAlert.alert_to_email == true) ? "checked" : "") + ' />'
                             + '</td><td>'
                            + '<input id="chkAlertToEmail_' + userAlert.alert_idx + '" type="checkbox" ' + ((userAlert.alert_to_sms == true) ? "checked" : "") + ' />'
                             + '</td><td>'
                            + selectAlert //modified Select2 dropdown
                             + '</td><td>'
                             + '<input id="txtMaxPerDay_' + userAlert.alert_idx + '" type="text" class="form-control" value="' + userAlert.alert_max_per_day + '"/>'
                             + '</td><td>'
                            + userAlert.alert_start_date
                             + '</td><td>'
                            + userAlert.alert_end_date
                             + '</td><td>'
                           + '<input id="chkActive_' + userAlert.alert_idx + '" type="checkbox" ' + ((userAlert.active == true) ? "checked" : "") + ' />'
                             + '</td><tr>'
                            tbl.append(tblRow);
                            initSelect2(); //call the function to initialize all Select2 dropdowns created
                        });
                    },
                    error: function (err) {
                        console.log('Error (RetrieveUserAlerts): ' + JSON.stringify(err, null, 2));
                    }
                });
            };

抱歉留下无关的东西 - 我评论了感兴趣的领域。 希望这对其他人有帮助!

对我有用

<div id="somediv">
    <select class="component">
    ...
    </select>
</div>



<script>
    $(document).on('click', '#addComponent', function () {

        $('#somediv').append(data); //data is my new select
        $('.component:last').select2();
    });
</script>

我也遇到过同样的问题,摸索了好几天,找到了解决办法,但如果你期望好的性能,那就不好了。

因此,当 DOM 首次加载时,加载的任何 select 项都将具有 select2 功能,对于动态生成的字段,select2 功能将不可用因为 select2 个脚本已经加载。

因此,要使 select2 正常工作,请在单击时动态重新加载脚本。

function reload(id) {
    $(id).on("click", function () {
        $("head").append($("<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/css/select2.css' type='text/css' media='screen' />"));
        $.getScript("https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js", function () {
            $.getScript("https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/js/select2.min.js", function () { 
                $('select').select2();
            })
        })
    })
}

它的作用是将 select2 功能添加到 $.

与上述答案类似:

function initSelect2(element){
  element.select2({   });
}

// Dynamic add 
$('button[data-id="add-item"]').on('click', function(){
   // Add element
   obj.addItem();
   // Add Select2 to element
   initSelect2($('element'));
});