如何避免jQuery slideToggle动画时文本随内边距移动?
如何阻止jQuery slideToggle执行时文本发生位移?
调用jQuery的slideToggle()时,带内边距(padding)的<div>在显示/隐藏的动画过程中,内部文本会跟着上下移动。比如下面的代码,点击按钮后文本会随着div高度变化偏移:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <p><a href="#">Show/Hide</a></p> <div id="outer">Some text<br/>Some text<br/>Some text<br/>Some text<br/>Some text</div>
#outer { padding:10px; border:1px solid #aaa; }
$("a").on("click", function(e) { e.preventDefault(); $("#outer").slideToggle(1000); });
目前有个嵌套div的解决办法:把带内边距的内容放进内层div,外层div执行滑动动画,这样内层padding不会随动画变化,文本位置稳定:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <p><a href="#">Show/Hide</a></p> <div id="outer"><div>Some text<br/>Some text<br/>Some text<br/>Some text<br/>Some text</div></div>
#outer { border:1px solid #aaa; } #outer > div { padding:10px; }
$("a").on("click", function(e) { e.preventDefault(); $("#outer").slideToggle(1000); });
如果不想额外嵌套div,有两种无需嵌套的方案:
方案一:用CSS伪元素模拟内边距
核心是让元素的内边距由伪元素承担,这样slideToggle改变元素高度时,不会影响文本的内边距:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <p><a href="#">Show/Hide</a></p> <div id="outer">Some text<br/>Some text<br/>Some text<br/>Some text<br/>Some text</div>
#outer { border:1px solid #aaa; overflow: hidden; /* 限制伪元素范围 */ } #outer::before { content: ""; display: block; margin: 10px; /* 用margin替代原padding */ height: 0; } #outer::after { content: ""; display: table; clear: both; /* 避免内部浮动影响布局 */ }
$("a").on("click", function(e) { e.preventDefault(); $("#outer").slideToggle(1000); });
方案二:用animate控制max-height替代slideToggle
通过手动控制元素的max-height实现滑动效果,同时固定padding:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <p><a href="#">Show/Hide</a></p> <div id="outer">Some text<br/>Some text<br/>Some text<br/>Some text<br/>Some text</div>
#outer { padding:10px; border:1px solid #aaa; max-height: 0; overflow: hidden; box-sizing: border-box; /* 让padding计入max-height */ }
$("a").on("click", function(e) { e.preventDefault(); const $outer = $("#outer"); if ($outer.hasClass("hidden")) { $outer.animate({ maxHeight: "200px" }, 1000).removeClass("hidden"); } else { $outer.animate({ maxHeight: "0" }, 1000).addClass("hidden"); } });
原理说明
jQuery的slideToggle()是靠逐步修改元素的height属性实现动画的,当元素有padding时,padding会被算进总高度里,动画过程中padding会跟着高度被压缩/拉伸,导致文本位移。而上面的两种方案,要么把内边距移出height计算范围,要么固定padding只控制内容高度,自然就不会让文本移动了。
内容的提问来源于stack exchange,提问作者freefaller
相关产品推荐
相关产品推荐

