Firefox中Twitter加载失败报twttr未定义问题求助
嘿,这个问题我之前帮人排查过,Firefox对异步脚本的加载时序处理确实和Chrome、Safari有差异,咱们一步步来解决它:
核心原因
你目前用了async加载Twitter的widget.js,同时用defer加载自定义脚本custom.js,再在window.load事件里调用twttr对象。但Firefox中,async脚本的加载完成时机可能晚于window.load触发的时间,导致代码执行时twttr还未初始化,就抛出了“twttr is not defined”的错误。
解决方案
方案1:改用Twitter官方推荐的异步加载回调(最稳妥)
Twitter的widget.js本身支持加载完成后的回调机制,能确保在所有浏览器中都能等到twttr对象就绪后再执行代码,完全规避时序问题:
<!-- 替换原来的Twitter脚本引入 --> <script id="twitter-wjs"></script> <script type="text/javascript" defer src="custom.js"></script> <!-- 添加Twitter的官方异步加载逻辑 --> <script type="text/javascript"> window.twttr = (function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0], t = window.twttr || {}; if (d.getElementById(id)) return t; js = d.createElement(s); js.id = id; js.src = "https://platform.twitter.com/widgets.js"; fjs.parentNode.insertBefore(js, fjs); // 注册就绪回调 t._e = []; t.ready = function(f) { t._e.push(f); }; return t; }(document, "script", "twitter-wjs")); // 在这里编写你的Twitter相关逻辑 twttr.ready(function(twttr) { // 例:创建分享按钮 // twttr.widgets.createShareButton( // 'https://your-url.com', // document.getElementById('twitter-share'), // {size: 'large'} // ); }); </script>
这种方式是Twitter官方给出的最佳实践,能完美适配所有现代浏览器。
方案2:在自定义脚本中添加轮询检查
如果不想修改HTML结构,可以在custom.js的window.load回调里,添加轮询逻辑,直到twttr对象可用再执行代码:
$(window).on('load', function() { // 初始化Twitter组件 function initTwitter() { if (typeof twttr !== 'undefined' && twttr.widgets) { // 这里放你的Twitter相关代码 return; } // 如果未就绪,100ms后重试 setTimeout(initTwitter, 100); } // 初始化Facebook组件(同理处理FB对象) function initFacebook() { if (typeof FB !== 'undefined') { // 这里放你的Facebook相关代码 return; } setTimeout(initFacebook, 100); } // 启动检查 initTwitter(); initFacebook(); });
这种方式灵活度高,适合已有大量现有代码、不想大幅改动的场景。
方案3:调整脚本加载属性与顺序
把Twitter脚本的async改为defer,并确保它在custom.js之前引入。defer脚本会按顺序加载,且在DOM解析完成后执行,能保证custom.js执行时twttr已初始化:
<script id="twitter-wjs" defer type="text/javascript" src="https://platform.twitter.com/widgets.js"></script> <script type="text/javascript" defer src="custom.js"></script>
注意:如果custom.js里的代码是直接执行而非在window.load中,要确保代码在DOMContentLoaded事件触发后执行(比如用$(document).ready()包裹)。
内容的提问来源于stack exchange,提问作者M4l2c3l0
相关产品推荐
相关产品推荐

