You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:50:36