项目中有时候会遇到这样一个需求:大屏通知或者某个数据展示过长时要滚动展示其所有数据。
原生JS 1 2 3 4 5 <div id ="wrapper" class ="wrapper" > <div class ="inner" > <p > 文字如果超出了宽度自动向左滚动文字如果超出了宽度自动向左滚动。我是一个粉刷匠,粉刷本领强,我要把那新房子刷的更漂亮</p > </div > </div >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 var wrapper = document .getElementById("wrapper" );var inner = wrapper.getElementsByTagName("div" )[0 ];var p = document .getElementsByTagName("p" )[0 ];var p_w = p.offsetWidth;var wrapper_w = wrapper.offsetWidth;window .onload = function fun ( ) { if (wrapper_w > p_w) { return false ; } inner.innerHTML += inner.innerHTML; setTimeout ("fun1()" , 2000 ); }; function fun1 ( ) { if (p_w > wrapper.scrollLeft) { wrapper.scrollLeft++; setTimeout ("fun1()" , 30 ); } else { setTimeout ("fun2()" , 2000 ); } } function fun2 ( ) { wrapper.scrollLeft = 0 ; fun1(); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 * { margin : 0 ; padding : 0 ; } body { font : 12px /1 "微软雅黑" ; } .wrapper { font-size : 0.85rem ; color : #333 ; padding-top : 0.75rem ; margin : 0 0.75rem ; white-space : nowrap; overflow : hidden; width : 300px ; } .inner { width : 1000px ; overflow : hidden; } .inner p { display : inline-block; }
Vue 封装组件 1 2 3 4 5 6 7 8 9 <template > <div class ="scrollText" ref ="outer" > <div class ="st-inner" :class ="{'st-scrolling': needToScroll}" > <span class ="st-section" ref ="inner" > {{text}}</span > <span class ="st-section" v-if ="needToScroll" > {{text}}</span > </div > </div > </template >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 <script> export default { data ( ) { return { needToScroll : false , text : "" }; }, mounted ( ) { this .startCheck(); }, beforeDestroy ( ) { this .stopCheck(); }, methods : { check ( ) { this .setText(); this .$nextTick(() => { let flag = this .isOverflow(); this .needToScroll = flag; }); }, isOverflow ( ) { let outer = this .$refs.outer; let inner = this .$refs.inner; let outerWidth = this .getWidth(outer); let innerWidth = this .getWidth(inner); return innerWidth > outerWidth; }, getWidth (el ) { let { width } = el.getBoundingClientRect(); return width; }, setText ( ) { this .text = (this .$slots.default && this .$slots.default.reduce((res, it ) => res + it.text, "" )) || "" ; }, startCheck ( ) { this ._checkTimer = setInterval (this .check, 1000 ); this .check(); }, stopCheck ( ) { clearInterval (this ._checkTimer); } } }; </script>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <style lang="scss" scoped> .scrollText { overflow : hidden; white-space : nowrap; } .st-inner { display : inline-block; } .st-scrolling .st-section { padding : 0 5px ; } // 向左匀速滚动动画 .st-scrolling { animation : scroll 10s linear infinite; } @keyframes scroll { 0% { transform : translate3d (0% , 0 , 0 ); } 100% { transform : translate3d (-50% , 0 , 0 ); } } </style>
父级使用组件 1 2 3 4 5 6 7 <template > <div class ="about" > <div class ="content" > <scrollText > 一二三四五六七八九十哈哈哈哈哈哈哈哈测试</scrollText > </div > </div > </template >
1 2 3 4 5 6 7 8 9 <script> import scrollText from "@/components/scrollText" ;export default { components : { scrollText }, data ( ) { return {}; } }; </script>
1 2 3 4 5 6 7 8 9 10 11 12 <style lang="scss" scoped> .content { overflow : hidden; text-overflow : ellipsis; white-space : nowrap; // 设置容器最大宽度为200 width : 200px ; font-size : 40px ; border : 1px solid lightblue; margin : 40px ; } </style>