为何给SnapAppointments的bootstrap-select设置title会清空元素值?
问题:bootstrap-select设置title后选中值延迟丢失
使用SnapAppointments的bootstrap-select组件时,遇到异常行为:页面加载后动态更新option并设置了预期选中值,但延迟一段时间后获取该值发现丢失。经测试,问题与设置title属性(原生title、data-title或脚本设置均触发)直接相关——只要设置了title,选中值就会在延迟后消失,但业务场景又必须保留title属性。
复现代码
JavaScript
var jData = {"data":[ {"label":"Option 1","value":"1"}, {"label":"Option 2","value":"2"}, {"label":"Option 3","value":"3"}, {"label":"Option 4","value":"4"}, {"label":"Option 5","value":"5"}] }; // 注释/取消注释这行可复现问题 $('#test').attr('title', 'test title'); // 模拟动态加载数据 $('#test').find('optgroup').remove(); $('#test').find('option').remove(); jData.data.forEach(function (o) { o.option = $('<option/>').attr('value', o.value).text(o.label).appendTo($('#test'))[0]; }); $('#test').selectpicker('destroy').selectpicker().selectpicker('val', '2'); console.log('value after selectpicker(\'val\', \'2\') : ' + $('#test').val()); $('#test').find('option[value=2]').attr('selected','selected'); console.log('value after attr(\'selected\',\'selected\') : ' + $('#test').val()); window.setTimeout(function() { console.log('value after delay : ' + $('#test').val()); }, 1000);
HTML
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.18/css/bootstrap-select.min.css" rel="stylesheet"/> <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.18/js/bootstrap-select.min.js"></script> <select id="test" name="test" data-live-search="true" > <button id="load" >Load data</button>
解决方案
这个问题源于bootstrap-select内部对title属性的处理逻辑:提前设置title会干扰组件的选中状态同步,导致延迟后选中值被重置。可以通过以下三种方式规避:
方法1:初始化时通过配置项设置title
不要提前给原生select设置title,而是在初始化selectpicker时将title作为配置参数传入:
// 移除提前设置title的代码:$('#test').attr('title', 'test title'); // 保留原有数据加载逻辑... // 初始化组件时传入title配置 $('#test').selectpicker('destroy').selectpicker({ title: 'test title' }).selectpicker('val', '2');
方法2:初始化完成后设置生成按钮的title
bootstrap-select会将原生select转换为按钮元素,直接找到该按钮设置title即可:
// 保留原有数据加载和组件初始化逻辑 $('#test').selectpicker('destroy').selectpicker().selectpicker('val', '2'); // 初始化完成后给生成的按钮设置title $('.bootstrap-select[data-id="test"] .btn').attr('title', 'test title');
方法3:初始化后设置data-title并刷新组件
如果需要使用data-title属性,需在组件初始化完成后设置,再调用refresh同步状态:
// 移除提前设置title的代码 // 保留数据加载和初始化逻辑 $('#test').selectpicker('destroy').selectpicker().selectpicker('val', '2'); // 设置data-title并刷新组件 $('#test').attr('data-title', 'test title'); $('#test').selectpicker('refresh');
原理说明
bootstrap-select初始化时会读取原生select的title属性作为按钮提示,但提前设置title会触发组件内部的状态重置逻辑,导致选中值在延迟后丢失。将title设置时机放在组件初始化之后,或通过配置项传入,能避开这个冲突点,保证选中状态稳定。
内容的提问来源于stack exchange,提问作者stefanu
相关产品推荐
相关产品推荐

