Rails 5.1.2中Searchkick+Typeahead报错:$(…).typeahead不是函数
哎呀,这种卡了两天的问题真的太磨人了!我来帮你捋捋这个TypeError: $(...).typeahead is not a function的常见坑,尤其是在Rails 5.1.2结合Searchkick+Typeahead的场景里:
1. 先揪出最容易踩的Turbolinks坑
Rails 5.x默认启用Turbolinks,它会让页面切换时不重新加载整个文档,这就导致你写的$(document).ready()里的typeahead初始化代码,在页面跳转后不会重新执行。
解决办法:把你的typeahead初始化代码包裹在Turbolinks的加载事件里:
$(document).on('turbolinks:load', function() { // 这里写你的typeahead初始化逻辑 $('#your-search-input').typeahead({ // 配置项... }); });
2. 严格检查JS文件的加载顺序
Typeahead完全依赖jQuery,所以加载顺序绝对不能乱,你的application.js里的require顺序必须是这样的:
//= require jquery //= require jquery_ujs //= require turbolinks //= require typeahead.bundle // 必须在jQuery之后 //= require searchkick // Searchkick依赖Typeahead,所以放后面 //= require articles // 你的自定义脚本最后加载 //= require_tree .
另外要确认typeahead.bundle.js确实在app/assets/javascripts或者vendor/assets/javascripts目录下,浏览器Network面板里能看到它成功加载(没有404错误)。
3. 排查jQuery冲突问题
有些情况下,Rails里的jQuery可能被设置了noConflict模式,导致$别名失效。你可以试试两种解决方式:
- 把代码里的
$换成jQuery,比如jQuery('#search-input').typeahead(...) - 用自执行函数重新映射
$:
(function($) { $(document).on('turbolinks:load', function() { $('#search-input').typeahead({/*配置*/}); }); })(jQuery);
4. 结合Searchkick的额外注意点
Searchkick自带的typeahead辅助方法需要正确的数据源配置,比如你要确保后端的autocomplete接口正常返回数据,并且前端用Bloodhound正确对接:
$(document).on('turbolinks:load', function() { var articleSuggestions = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title'), queryTokenizer: Bloodhound.tokenizers.whitespace, remote: { url: '/articles/autocomplete?query=%QUERY', wildcard: '%QUERY' } }); $('#article-search').typeahead(null, { name: 'articles', display: 'title', source: articleSuggestions.ttAdapter() }); });
先从这几个方向排查,尤其是Turbolinks和加载顺序的问题,这在Rails 5.x里是最常见的诱因。如果还是不行,打开浏览器控制台看看有没有其他加载错误,比如Typeahead文件没加载成功之类的细节。
内容的提问来源于stack exchange,提问作者user1844147

