使用jQuery .fadeOut()时文本先显示再淡出的问题排查
问题
希望实现从JSON文件加载网站文本,当JSON文件中的数据变更时,文本先淡出、更新为新值后再淡入。但当前代码运行时,数据会先显示,再执行淡出淡入操作,过渡效果不流畅,请问问题出在哪里?
原代码
<html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> </head> <body style="background:#000000;"> <script> var currentText; setInterval(function checkUpdate() { $.ajaxSetup({ cache: false }); $.ajax({ type:"get", cache: false, url: 'temp.json', success:function(data) { var textSource = data.currentText[0].text; if(currentText !== textSource) { $("#dataDiv").fadeOut(2000); $("#dataDiv").html('<h1><font color=#ffffff>' + textSource + '</font></h1>') //.fadeOut(2000) .fadeIn(2000); } currentText = textSource; } }); return checkUpdate; }(), 5000);//time in milliseconds </script> <div style="background:#000000"><div id="dataDiv"></div></div> </body> </html>
JSON文件内容
{ "currentText": { "0": { "id": "1", "text": "This is a test again." } } }
问题原因与解决方案
问题核心是jQuery动画是异步执行的,你调用fadeOut()后没等它结束,就直接执行了.html()更新文本和.fadeIn(),导致新文本先直接显示出来,之后才完成淡出再淡入,视觉上就出现了混乱的过渡效果。
解决办法很简单,利用fadeOut()的回调函数——把更新内容和淡入的逻辑放到fadeOut()的第二个参数里,这样就能保证动画按「淡出→更新内容→淡入」的顺序执行:
另外补充一点:初始加载时currentText是undefined,第一次加载会直接显示文本,可以给容器初始状态设为隐藏,让首次加载也有淡入效果,体验更统一。
修改后的完整代码
<html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> </head> <body style="background:#000000;"> <script> var currentText; // 初始隐藏容器,让首次加载也有淡入过渡 $("#dataDiv").hide(); setInterval(function checkUpdate() { $.ajaxSetup({ cache: false }); $.ajax({ type:"get", cache: false, url: 'temp.json', success:function(data) { var textSource = data.currentText[0].text; if(currentText !== textSource) { $("#dataDiv").fadeOut(2000, function() { // 淡出完成后才更新内容并淡入 $(this).html('<h1><font color=#ffffff>' + textSource + '</font></h1>') .fadeIn(2000); }); } currentText = textSource; } }); return checkUpdate; }(), 5000);//time in milliseconds </script> <div style="background:#000000"><div id="dataDiv"></div></div> </body> </html>
额外优化建议
你的JSON里currentText是对象类型,用data.currentText[0].text虽然能生效(因为键是"0"),但更规范的写法是把currentText改成数组,这样索引访问更合理,也避免后续扩展出问题:
{ "currentText": [ { "id": "1", "text": "This is a test again." } ] }
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

