繁体   English   中英

幻灯片隐藏和显示文本

[英]slide hide & show text

我想创建一个动画,其中active类每 X 秒更改为profession-wrapper span内的下一个spandeveloper span将以显示字母的方式滑动到active span之上新的active span ,在它上面滑动,同时隐藏每个字母,当它覆盖整个单词时, active类将进入下一个跨度。

我让developer span滑动,并且active class可以正常工作,但是developer span不涵盖它滑动的active span ,并且由于每个跨度的文本长度不同,滑动不会在单词的末尾完成,但在一个固定的地方,在|之间留下了很多空白空间| active span

我怎样才能实现幻灯片覆盖它滑动的文本,并确保幻灯片将在新的active词的末尾完成?

 const firstProfession = document.querySelector('.profession-wrapper').firstElementChild; let professionActive = document.querySelector('.active'); setInterval(() => { professionActive.classList.remove('active'); professionActive.classList.add('inactive'); if (professionActive.nextElementSibling) { professionActive = professionActive.nextElementSibling; } else { professionActive = firstProfession; } professionActive.classList.remove('inactive'); professionActive.classList.add('active'); }, 6000);
 .profession-header { display: flex; width: 100%; position: relative; } .profession-wrapper { position: relative; display: flex; padding-right: 7px; } .inactive { opacity: 0; position: absolute; overflow: hidden; display: inline-block; } .active { opacity: 1; display: inline-block; position: relative; overflow: hidden; width: max-content; padding-right: 5px; } .developer::before { content: ''; border-left: 2px solid white; display: block; margin-right: 5px; height: 1.5rem; position: absolute; left: -7px; } .developer { position: absolute; animation: slide-text-in-out 6s ease-in-out infinite; } @keyframes slide-text-in-out { 0% { left: 8px; } 45%, 55% { left: 50%; } 100% { left: 8px; } }
 <h5 class="profession-header"> <span class="profession-wrapper"> <span class="profession active">Web</span> <span class="profession inactive">Full Stack</span> <span class="profession inactive">Front End</span> <span class="profession inactive">Back End</span> </span> <span class="developer">Developer</span> </h5>

更新后的版本

为了回应下面 OP 的评论,这里是动画脚本/css 的更新版本,它在为.developer元素设置动画时尊重专业的宽度。

它的工作原理基本相同,但使用 CSS transitiontransform而不是animationleft移动.developer div。

 setupProfessionAnim(document.querySelector('.profession-header')); function setupProfessionAnim(containerEl) { let professions = Array.from(containerEl.querySelectorAll('.profession')), sliding = containerEl.querySelector('.developer'), covered = true; // <-- state tracking variable sliding.addEventListener('transitionend', runNextAnimation); // <-- changed event runNextAnimation(); // <-- starts the first transition function runNextAnimation() { let active, next; covered = !covered; // <-- inverse the state if (covered) { // <-- are we in covering mode? sliding.style.transform = 'translateX(0)'; // <-- then cover return; // <-- and stop further processing } // otherwise active = getWithClass(professions, 'active'); next = active.nextElementSibling ? active.nextElementSibling : professions[0]; next.classList.add('active'); // <-- switch the .active class active.classList.remove('active'); // <-- here, too sliding.style.transform = 'translateX(' + getWidth(next) + 'px)'; // <-- and let the .developer div uncover } } function getWithClass(elList, className) { return elList.find ? elList.find(el => el.classList.contains(className)) : elList.filter(el => el.classList.contains(className))[0]; } function getWidth(el) { return el.getBoundingClientRect().width; }
 .profession-header { display: flex; width: 100%; position: relative; } .profession-wrapper { position: relative; display: flex; padding-right: 7px; } .profession { display: none; width: max-content; padding-right: 1ex; } .profession.active { display: block; } .developer { position: absolute; width: 160px; /* adjust if necessary */ background-color: #fff; /* remove if you like, just for demonstation purposes */ transform: translateX(0); transition: transform 2s ease-in-out 0s; }
 <h5 class="profession-header"> <span class="profession-wrapper"> <span class="profession active">Web</span> <span class="profession inactive">Full Stack</span> <span class="profession inactive">Front End</span> <span class="profession inactive">Back End</span> </span> <span class="developer">Developer</span> </h5>

以前的版本

你应该避免在setInterval和 CSS 动画时间之间有一个隐含的要求。 相反,使用 CSS 动画触发的事件来切换类。 这可以确保你的动画“时间表”不能得到同步(另一种方式来查看它是它确保有只是一个单一的时间表,而不是多个)出来。

下面是一个解决您的问题的工作示例。 请注意我留下的评论!

 setupProfessionAnim(document.querySelector('.profession-header')); function setupProfessionAnim(containerEl) { let professions = Array.from(containerEl.querySelectorAll('.profession')), // get an array of all professions sliding = containerEl.querySelector('.developer'); // get the 'developer' element sliding.addEventListener('animationiteration', runNextAnimation); // re-execute runNextAnimation whenever an animation iteration finishes function runNextAnimation() { // this actually switches the classes from 'active' to 'inactive' and vice-versa let active = getWithClass(professions, 'active'), // get the current 'active' profession next = active.nextElementSibling ? active.nextElementSibling : professions[0]; // find next profession active.classList.replace('active', 'inactive'); // switch! next.classList.replace('inactive', 'active'); // here, too! } } function getWithClass(elList, className) { // convenience helper, uses Array.prototype.find if available and falls back to Array.prototype.filter return elList.find ? elList.find(el => el.classList.contains(className)) : elList.filter(el => el.classList.contains(className))[0]; }
 .profession-header { display: flex; width: 100%; position: relative; } .profession-wrapper { position: relative; display: flex; padding-right: 7px; } .inactive { opacity: 0; position: absolute; overflow: hidden; display: inline-block; animation: slide-text-out 2s ease-in-out; } .active { opacity: 1; display: inline-block; position: relative; overflow: hidden; width: max-content; padding-right: 5px; animation: slide-text-in 2s ease-in-out; } /* --- removed --- .developer::before { content: ''; border-left: 2px solid white; display: block; margin-right: 5px; height: 1.5rem; position: absolute; left: -7px; } --- removed --- */ .developer { position: absolute; /* --- new additions --- */ width: 160px; /* adjust if necessary */ border-left: 2px solid white; padding-left: 5px; background-color: #fff; /* remove if you like, just for demonstation purposes */ /* --- end new additions --- */ animation: slide-text-in-out 6s ease-in-out infinite; } @keyframes slide-text-in-out { 0% { left: 0; } 45%, 55% { left: 50%; } 100% { left: 0; } }
 <h5 class="profession-header"> <span class="profession-wrapper"> <span class="profession active">Web</span> <span class="profession inactive">Full Stack</span> <span class="profession inactive">Front End</span> <span class="profession inactive">Back End</span> </span> <span class="developer">Developer</span> </h5>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM