【问题标题】:Attach click-event to element in .select2-result将点击事件附加到 .select2-result 中的元素
【发布时间】:2013-03-16 04:52:28
【问题描述】:

我正在寻找一种将点击事件附加到 select2-result-item 的方法。 我已经通过

格式化了结果和选择
function format(state) {
    if (!state.id) return state.text; // optgroup
    return state.text + " <i class='info'>link</i>";
}

添加“信息”图标 我现在正在尝试将一个简单的点击事件附加到 .info 元素,但无法使其正常工作:

$('.info').on('click', function(event){
    event.preventDefault();
    alert("CLICK");
    $('#log').text( "clicked" );
});

有什么帮助吗? 有类似问题的人吗? 这可能吗?

我准备了一个 jsFiddle 在:http://jsfiddle.net/s2dqh/3/

【问题讨论】:

  • 你想要点击事件在整个项目中还是仅仅在链接上
  • 只是链接,Arun - 应保留原始 select2 功能(从下拉列表中选择一个选项)
  • select2 3.3版本不存在此问题

标签: javascript jquery-select2


【解决方案1】:

因为 Select2 lib 阻止了弹出列表上的任何点击事件,所以您不能直接将事件绑定到 .info。但是您可以重新定义onSelect 方法并在其中放置您想要的任何代码。

查看示例:http://jsfiddle.net/f8q2by55/

多选更新:http://jsfiddle.net/6jaodjzq/

【讨论】:

  • 太棒了,到目前为止感谢;我知道这超出了我原来的问题,但是我如何使 .select2-choice 中的链接继承相同的行为? (澄清:.select2-choice 是被选中的元素 - jsfiddle 显示点击事件仅适用于下拉选项,不适用于当前选择的元素)
  • @ant_Ti - 我遇到了太多关于“脏黑客”的问题(select2-dropdown 未关闭等),所以我继续为 .select2 的 info-icon 实施了一个解决方法-choice 在不干扰 select2 的原始功能的情况下做它需要做的事情。不过,请允许我再问一个关于第一个解决方案(覆盖'onSelect')的问题:我注意到在通过返回键进行选择时,这会导致“未捕获的类型错误:无法读取未定义的属性'目标'”-任何线索如何抓住最后的烦恼了吗?
  • @ant_Ti - 非常感谢您的快速回答(就像一个魅力!),在这里真的学到了很多东西!请允许我再问一个问题:如何将修改后的“onSelect”应用于 select2 的其他实例?
  • 我忘了补充一点,每个 select2 实例都有不同的选项。很高兴为此提出另一个问题!
  • @brckmann 看到我的更新来回答。对您的代码进行一点重构
【解决方案2】:

这个和netme的概念类似,但是select2事件是错误的(可能是版本不同),需要使用stopPropagation来防止item被选中:

http://jsfiddle.net/ZhfMg/

$('#mySelect2').on('select2-open', function() { 
    $('.select2-results .info').on('mouseup', function(e) { 
        e.stopPropagation();
        console.log('clicked');
    }); 
});

如果与 x-editable 一起使用。这样做是当 x-editable 进入编辑模式(显示事件)时,即 select2 存在并且您可以连接到它的 open 函数。

$('#myXEditable').on('shown', function () {
    $(this).data('editable').input.$input.on('select2-open', function() { 
        $('.select2-results .info').on('mouseup', function(e) { 
            e.stopPropagation();
            console.log('clicked');
        }); 
    });
});

【讨论】:

  • +1 通用部分 $('#mySelect2').on('select2-open', function() { 为我节省了构建自定义代码以满足我的需求的时间。
  • @MichelAyres 的答案是这里唯一对我有用的东西。
【解决方案3】:

对于 Select2 4.0.0 之前的版本(所以 3.5.x 及以下),您应该参考this answer about binding to onSelect

在 Select2 的较新版本中,事件不再在结果中被终止,因此您可以像往常一样绑定到 mouseup/mousedown 事件。您应该避免绑定到click 事件,因为默认情况下浏览器不会触发它。

$(".select2").select2({
  templateResult: function (data) {
    if (data.id == null) {
      return data.text;
    }
    
    var $option = $("<spam></span>");
    var $preview = $("<a target='_blank'> (preview)</a>");
    $preview.prop("href", data.id);
    $preview.on('mouseup', function (evt) {
      // Select2 will remove the dropdown on `mouseup`, which will prevent any `click` events from being triggered
      // So we need to block the propagation of the `mouseup` event
      evt.stopPropagation();
    });
    
    $preview.on('click', function (evt) {
      console.log('the link was clicked');
    });
    
    $option.text(data.text);
    $option.append($preview);
    
    return $option;
  }
});
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js"></script>

<select class="select2" style="width: 200px;">
  <option value="https://google.com">Google</option>
  <option value="https://mail.google.com">GMail</option>
</select>

在本例中,我们停止mouseup 事件的传播,因此浏览器将触发click 事件。如果您不使用实际链接,而只需要捕获 click 事件,则应该直接挂钩 mouseup 事件。

【讨论】:

    【解决方案4】:

    使用默认的 select2select 事件触发器而不是使用其他 jquery 事件

    $('#mySelect2').on('select2:select', function (e) {
        var data = e.params.data;
        console.log(data);
    });
    

    更多详情请参考以下链接 https://select2.org/programmatic-control/events

    【讨论】:

      【解决方案5】:

      对于 select2 4.0.0,以上答案均不适合我,所以这就是我最终要做的:

      $(document).on('mouseup', '.select2-container--open .select2-results__option', function (e) {
          // Act on the element
      }
      

      具体来说,我只想对之前选择的项目进行操作:

      $(document).on('mouseup', '.select2-container--open .select2-results__option[aria-selected=true]', function (e) {
          // Do something on the previously-selected item
      }
      

      【讨论】:

      • 如果可以请提供 JSfiddle 或其他东西来证明您的方法有效。这里的答案太多,不适用于新版本的 select2。
      【解决方案6】:

      根据文档的更简单的方法。

      $('#mySelect2').on('select2:select', function (e) {
          var data = e.params.data;
          console.log(data);
      });
      

      很惊讶没有看到任何答案。

      【讨论】:

      • 如果您出于任何原因选择了 2 次相同的选项,它将不起作用。
      【解决方案7】:

      我认为 Select2 对 mouseup 事件的处理阻止了 .info 元素获得点击事件。让.info 元素捕获 mouseup 事件并阻止它传播似乎可以解决这个问题。

      function format(state, container) {
          if (!state.id) return state.text; // optgroup
          container.append(state.text);
          $('<i class="info">link</i>')
              .appendTo(container)
              .mouseup(function(e) {
                  e.stopPropagation();            
              })
              .click(function(e) {
                  e.preventDefault();
                  alert('CLICK');
              });
      }
      

      这也可以支持所选项目中的链接,但需要捕获 mousedown 事件。

      jsfiddle

      【讨论】:

      • 对我来说,mousedown 事件有效(就像在你的小提琴的 formatSelection 函数中一样)而不是 mouseup
      • @yezahel - 谢谢。我的 jsfiddle 使用的是 v3.3.1,这是问题中使用的版本。最新版本是 3.5.2,不幸的是,我认为你是对的,使这项工作的代码需要与该版本有点不同。
      【解决方案8】:

      只需添加 'open' 监听器并为 '' 标签设置另一个 'mouseup' 监听器:

      $("#select").on('open', function() { 
          $('.select2-results i').on('mouseup', function() { 
             alert('aaa');
          }); 
      });
      

      这是我的解决方案的链接:http://jsfiddle.net/EW8t7/

      【讨论】:

      • 不幸的是这个答案,点击链接会导致项目被选中并关闭下拉菜单。没有阻止默认功能。
      【解决方案9】:

      问题似乎是 tgas 将在盒子关闭后立即被删除。因此无法触发 click 事件。

      我已经更改了一些内容 + 将被监听的事件。现在是鼠标按下...

      function format(state) {
          if (!state.id) return state.text; // optgroup
          return state.text + " <a class='info'>link</a>";
      }
      
      $("select").select2({
          formatResult: format,
          formatSelection: format,
          escapeMarkup: function(m) { return m; }
      }).on('select2-open',function(){
          console.log($('.info'))
          $('.info').on('mousedown', function(event){
              console.log("click")
              $('#log').text( "clicked" );
              event.preventDefault();
          });
      });
      <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2.css" rel="stylesheet" />
      <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2.js"></script>
      
      <select>
        <option>red</option>
        <option>green</option>
        <option>blue</option>
      </select>
      
      <div id="log"></div>

      【讨论】:

      • 好主意,但在您的情况下,您将无法通过单击 .info 来阻止关闭列表
      【解决方案10】:

      刚刚在 select2 v4.0.3 中遇到了这个问题,最终使用了“select2:selecting”事件。这基本上是我的做法:

      var $select2 = $savedReportsList.select2({ [stuff] });
      
      $select2.on('select2:selecting', function(e) {
        var args = e.params.args;
        if ($(args.originalEvent.target).hasClass('[something]')) {
          if (confirm('Are you sure?')) {
             window.location = '[somewhere]' + '/' + args.data.id;
          }
          return false; // stops propogation (so select2:select never fires)
        });
      });

      【讨论】:

        【解决方案11】:

        您需要从 .select2-results__options 元素中取消绑定 mouseup 事件。我在我的 templateResult 函数中这样做:

        function templateResult(location) {
        
            var $location = $([html with links]);
        
            $('.select2-results__options').unbind('mouseup');
        
            return $location;
        }
        

        如果您想保持 select2 选择选项并关闭下拉菜单的默认行为,您需要手动触发这些事件:

        $('.select2-results__options').unbind('mouseup');
        
        $('a', $location).on('click', function (e) {
            $('#locations_dropdown').select2('val', location.id);
            $('#locations_dropdown').select2('close');
        });
        
        return $location;
        

        【讨论】:

        • 这仅适用于标准选择,其中&lt;option&gt; 已经提前存在。当您使用 4.0.0 时,您应该使用 .val(location.id).trigger('change') 而不是旧的 select2('val') 方法。
        【解决方案12】:

        像这样的简单 onchange 事件也有助于解决问题

        <select id="GetClientAccounts" class="default-select2 form-control col-md-4" onchange="GetClientAccounts();">
            <option disabled selected value="-1">Select a customer from here</option>
            @{
                if (ViewBag.customers != null)
                {
                    foreach (CustomerTBL customer in ((List<CustomerTBL>)ViewBag.customers).OrderBy(c => c.cusCustomerName))
                    {
                        <option value="@customer.cusCustomerID">@customer.cusCustomerName</option>
                    }
                }
            }
        </select>
        

        【讨论】:

        • 嗨 PraBel,当您使用代码样式时,我认为您的代码示例会更容易阅读
        猜你喜欢
        • 1970-01-01
        • 2013-04-30
        • 1970-01-01
        • 2017-03-18
        • 1970-01-01
        • 1970-01-01
        • 2012-06-28
        • 2016-10-31
        • 1970-01-01
        相关资源
        最近更新 更多