Materialize CSS Autocomplete加载数据后无法显示下拉列表求助
解决Materialize CSS Autocomplete输入开头下拉不显示且instance.open()失效的问题
嘿,我之前也踩过Materialize这个Autocomplete组件的坑,咱们一步步来把它搞定!
先聊聊问题的根源:你用keypress事件触发搜索,但这个事件在输入第一个字符时,输入框的value其实还没完成更新,导致后续逻辑拿到的是旧值;另外,updateData之后直接调用open(),组件内部可能还没完成数据的更新渲染,所以调用会失效。
下面是具体的修复方案:
1. 替换触发事件:onkeypress → oninput
oninput事件会在输入框的value真正变化后才触发,比keypress更适配自动补全的场景,能避免拿到旧值的问题。修改你的input标签:
<input type="text" id="autocomplete-input" class="autocomplete" oninput="valueChange(this);">
2. 延迟调用instance.open()
updateData之后,组件需要一点时间处理数据并更新内部状态,直接调用open()可能赶不上节奏。用setTimeout把open()放到下一个事件循环,确保数据更新完成:
.then(function (response) { var map = {}; // 简化数据处理逻辑 response.data.forEach(item => { map[item.town] = null; }); if (response.data.length > 0) { console.log(map); instance.updateData(map); // 延迟0毫秒,让组件完成数据更新 setTimeout(() => { instance.open(); }, 0); } else { // 没有数据时关闭下拉列表 instance.close(); } })
3. 优化初始化配置
初始化Autocomplete时,设置minLength为1(或者0,根据你的需求调整),确保输入第一个字符时就能触发自动补全逻辑:
document.addEventListener('DOMContentLoaded', function() { var elems = document.querySelectorAll('.autocomplete'); var instances = M.Autocomplete.init(elems, { minLength: 1 // 输入1个字符就触发自动补全 }); });
4. 增加实例存在性检查
为了避免意外报错,在函数开头加个判断,确保实例已经正确初始化:
function valueChange(elem) { var instance = M.Autocomplete.getInstance(elem); if (!instance) { console.warn('Autocomplete instance not found'); return; } // ... 后续的axios请求逻辑 }
完整修改后的代码
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/css/materialize.min.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/js/materialize.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script> <div class="row"> <div class="col s12"> <div class="row"> <div class="input-field col s12"> <i class="material-icons prefix">textsms</i> <input type="text" id="autocomplete-input" class="autocomplete" oninput="valueChange(this);"> <label for="autocomplete-input">Autocomplete</label> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { var elems = document.querySelectorAll('.autocomplete'); var instances = M.Autocomplete.init(elems, { minLength: 1 }); }); function valueChange(elem) { var instance = M.Autocomplete.getInstance(elem); if (!instance) { console.warn('Autocomplete instance not found'); return; } console.log("search for " + elem.value); axios.post("<%= test_autocomplete_search_path %>", { search: elem.value, authenticity_token: '<%= form_authenticity_token %>', }) .then(function (response) { var map = {}; response.data.forEach(item => { map[item.town] = null; }); if (response.data.length > 0) { console.log(map); instance.updateData(map); setTimeout(() => { instance.open(); }, 0); } else { instance.close(); } }) .catch(function (error) { alert(error); }); }; </script>
这些修改应该能解决你输入开头下拉不显示、instance.open()失效的问题啦!
内容的提问来源于stack exchange,提问作者Gregoire Mulliez
相关产品推荐
相关产品推荐

