mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
fix(NoticeBar): replay event only triggered once (#6293)
This commit is contained in:
parent
f2ec0c5a4d
commit
1dfa1af288
@ -1,4 +1,5 @@
|
|||||||
import { createNamespace } from '../utils';
|
import { createNamespace } from '../utils';
|
||||||
|
import { doubleRaf } from '../utils/dom/raf';
|
||||||
import Icon from '../icon';
|
import Icon from '../icon';
|
||||||
|
|
||||||
const [createComponent, bem] = createNamespace('notice-bar');
|
const [createComponent, bem] = createNamespace('notice-bar');
|
||||||
@ -27,12 +28,12 @@ export default createComponent({
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
show: true,
|
||||||
|
offset: 0,
|
||||||
|
duration: 0,
|
||||||
wrapWidth: 0,
|
wrapWidth: 0,
|
||||||
firstRound: true,
|
firstRound: true,
|
||||||
duration: 0,
|
contentWidth: 0,
|
||||||
offsetWidth: 0,
|
|
||||||
showNoticeBar: true,
|
|
||||||
animationClass: '',
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -47,25 +48,27 @@ export default createComponent({
|
|||||||
methods: {
|
methods: {
|
||||||
onClickIcon(event) {
|
onClickIcon(event) {
|
||||||
if (this.mode === 'closeable') {
|
if (this.mode === 'closeable') {
|
||||||
this.showNoticeBar = false;
|
this.show = false;
|
||||||
this.$emit('close', event);
|
this.$emit('close', event);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onAnimationEnd() {
|
onTransitionEnd() {
|
||||||
|
this.offset = this.wrapWidth;
|
||||||
|
this.duration = 0;
|
||||||
this.firstRound = false;
|
this.firstRound = false;
|
||||||
this.$nextTick(() => {
|
|
||||||
this.duration = (this.offsetWidth + this.wrapWidth) / this.speed;
|
doubleRaf(() => {
|
||||||
this.animationClass = bem('play--infinite');
|
this.offset = -this.contentWidth;
|
||||||
|
this.duration = (this.contentWidth + this.wrapWidth) / this.speed;
|
||||||
this.$emit('replay');
|
this.$emit('replay');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.wrapWidth = 0;
|
|
||||||
this.offsetWidth = 0;
|
|
||||||
this.animationClass = '';
|
|
||||||
this.duration = 0;
|
this.duration = 0;
|
||||||
|
this.wrapWidth = 0;
|
||||||
|
this.contentWidth = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
@ -76,12 +79,13 @@ export default createComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const wrapWidth = wrap.getBoundingClientRect().width;
|
const wrapWidth = wrap.getBoundingClientRect().width;
|
||||||
const offsetWidth = content.getBoundingClientRect().width;
|
const contentWidth = content.getBoundingClientRect().width;
|
||||||
if (this.scrollable && offsetWidth > wrapWidth) {
|
|
||||||
|
if (this.scrollable && contentWidth > wrapWidth) {
|
||||||
|
this.offset = -contentWidth;
|
||||||
|
this.duration = contentWidth / this.speed;
|
||||||
this.wrapWidth = wrapWidth;
|
this.wrapWidth = wrapWidth;
|
||||||
this.offsetWidth = offsetWidth;
|
this.contentWidth = contentWidth;
|
||||||
this.duration = offsetWidth / this.speed;
|
|
||||||
this.animationClass = bem('play');
|
|
||||||
} else {
|
} else {
|
||||||
this.reset();
|
this.reset();
|
||||||
}
|
}
|
||||||
@ -98,9 +102,9 @@ export default createComponent({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const contentStyle = {
|
const contentStyle = {
|
||||||
paddingLeft: this.firstRound ? 0 : this.wrapWidth + 'px',
|
transform: `translateX(${this.offset}px)`,
|
||||||
animationDelay: (this.firstRound ? this.delay : 0) + 's',
|
transitionDelay: (this.firstRound ? this.delay : 0) + 's',
|
||||||
animationDuration: this.duration + 's',
|
transitionDuration: this.duration + 's',
|
||||||
};
|
};
|
||||||
|
|
||||||
function LeftIcon() {
|
function LeftIcon() {
|
||||||
@ -143,7 +147,7 @@ export default createComponent({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
role="alert"
|
role="alert"
|
||||||
vShow={this.showNoticeBar}
|
vShow={this.show}
|
||||||
class={bem({ wrapable: this.wrapable })}
|
class={bem({ wrapable: this.wrapable })}
|
||||||
style={barStyle}
|
style={barStyle}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
@ -156,12 +160,10 @@ export default createComponent({
|
|||||||
ref="content"
|
ref="content"
|
||||||
class={[
|
class={[
|
||||||
bem('content'),
|
bem('content'),
|
||||||
this.animationClass,
|
|
||||||
{ 'van-ellipsis': !this.scrollable && !this.wrapable },
|
{ 'van-ellipsis': !this.scrollable && !this.wrapable },
|
||||||
]}
|
]}
|
||||||
style={contentStyle}
|
style={contentStyle}
|
||||||
onAnimationend={this.onAnimationEnd}
|
onTransitionend={this.onTransitionEnd}
|
||||||
onWebkitAnimationEnd={this.onAnimationEnd}
|
|
||||||
>
|
>
|
||||||
{this.slots() || this.text}
|
{this.slots() || this.text}
|
||||||
</div>
|
</div>
|
||||||
|
@ -34,20 +34,13 @@
|
|||||||
&__content {
|
&__content {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
transition-timing-function: linear;
|
||||||
|
|
||||||
&.van-ellipsis {
|
&.van-ellipsis {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__play {
|
|
||||||
animation: van-notice-bar-play linear both;
|
|
||||||
|
|
||||||
&--infinite {
|
|
||||||
animation: van-notice-bar-play-infinite linear infinite both;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--wrapable {
|
&--wrapable {
|
||||||
height: auto;
|
height: auto;
|
||||||
padding: @notice-bar-wrapable-padding;
|
padding: @notice-bar-wrapable-padding;
|
||||||
@ -65,19 +58,3 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Declare two same keyframes
|
|
||||||
* In case that some mobile browsers can continue animation when className changed
|
|
||||||
*/
|
|
||||||
@keyframes van-notice-bar-play {
|
|
||||||
to {
|
|
||||||
transform: translate3d(-100%, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes van-notice-bar-play-infinite {
|
|
||||||
to {
|
|
||||||
transform: translate3d(-100%, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -6,34 +6,34 @@ exports[`renders demo correctly 1`] = `
|
|||||||
<div role="alert" class="van-notice-bar"><i class="van-icon van-icon-volume-o van-notice-bar__left-icon">
|
<div role="alert" class="van-notice-bar"><i class="van-icon van-icon-volume-o van-notice-bar__left-icon">
|
||||||
<!----></i>
|
<!----></i>
|
||||||
<div role="marquee" class="van-notice-bar__wrap">
|
<div role="marquee" class="van-notice-bar__wrap">
|
||||||
<div class="van-notice-bar__content" style="padding-left: 0px; animation-delay: 1s; animation-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
<div class="van-notice-bar__content" style="transform: translateX(0px); transition-delay: 1s; transition-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div role="alert" class="van-notice-bar">
|
<div role="alert" class="van-notice-bar">
|
||||||
<div role="marquee" class="van-notice-bar__wrap">
|
<div role="marquee" class="van-notice-bar__wrap">
|
||||||
<div class="van-notice-bar__content van-ellipsis" style="padding-left: 0px; animation-delay: 1s; animation-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
<div class="van-notice-bar__content van-ellipsis" style="transform: translateX(0px); transition-delay: 1s; transition-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div role="alert" class="van-notice-bar van-notice-bar--wrapable">
|
<div role="alert" class="van-notice-bar van-notice-bar--wrapable">
|
||||||
<div role="marquee" class="van-notice-bar__wrap">
|
<div role="marquee" class="van-notice-bar__wrap">
|
||||||
<div class="van-notice-bar__content" style="padding-left: 0px; animation-delay: 1s; animation-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
<div class="van-notice-bar__content" style="transform: translateX(0px); transition-delay: 1s; transition-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div role="alert" class="van-notice-bar">
|
<div role="alert" class="van-notice-bar">
|
||||||
<div role="marquee" class="van-notice-bar__wrap">
|
<div role="marquee" class="van-notice-bar__wrap">
|
||||||
<div class="van-notice-bar__content" style="padding-left: 0px; animation-delay: 1s; animation-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
<div class="van-notice-bar__content" style="transform: translateX(0px); transition-delay: 1s; transition-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
||||||
</div><i class="van-icon van-icon-cross van-notice-bar__right-icon">
|
</div><i class="van-icon van-icon-cross van-notice-bar__right-icon">
|
||||||
<!----></i>
|
<!----></i>
|
||||||
</div>
|
</div>
|
||||||
<div role="alert" class="van-notice-bar">
|
<div role="alert" class="van-notice-bar">
|
||||||
<div role="marquee" class="van-notice-bar__wrap">
|
<div role="marquee" class="van-notice-bar__wrap">
|
||||||
<div class="van-notice-bar__content" style="padding-left: 0px; animation-delay: 1s; animation-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
<div class="van-notice-bar__content" style="transform: translateX(0px); transition-delay: 1s; transition-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
||||||
</div><i class="van-icon van-icon-arrow van-notice-bar__right-icon">
|
</div><i class="van-icon van-icon-arrow van-notice-bar__right-icon">
|
||||||
<!----></i>
|
<!----></i>
|
||||||
</div>
|
</div>
|
||||||
@ -42,7 +42,7 @@ exports[`renders demo correctly 1`] = `
|
|||||||
<div role="alert" class="van-notice-bar" style="color: rgb(25, 137, 250); background: rgb(236, 249, 255);"><i class="van-icon van-icon-info-o van-notice-bar__left-icon">
|
<div role="alert" class="van-notice-bar" style="color: rgb(25, 137, 250); background: rgb(236, 249, 255);"><i class="van-icon van-icon-info-o van-notice-bar__left-icon">
|
||||||
<!----></i>
|
<!----></i>
|
||||||
<div role="marquee" class="van-notice-bar__wrap">
|
<div role="marquee" class="van-notice-bar__wrap">
|
||||||
<div class="van-notice-bar__content" style="padding-left: 0px; animation-delay: 1s; animation-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
<div class="van-notice-bar__content" style="transform: translateX(0px); transition-delay: 1s; transition-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
exports[`icon slot 1`] = `
|
exports[`icon slot 1`] = `
|
||||||
<div role="alert" class="van-notice-bar">Custom Left Icon<div role="marquee" class="van-notice-bar__wrap">
|
<div role="alert" class="van-notice-bar">Custom Left Icon<div role="marquee" class="van-notice-bar__wrap">
|
||||||
<div class="van-notice-bar__content" style="padding-left: 0px; animation-delay: 1s; animation-duration: 0s;">
|
<div class="van-notice-bar__content" style="transform: translateX(0px); transition-delay: 1s; transition-duration: 0s;">
|
||||||
Content
|
Content
|
||||||
</div>
|
</div>
|
||||||
</div>Custom Right Icon</div>
|
</div>Custom Right Icon</div>
|
||||||
|
@ -44,7 +44,7 @@ test('replay event', async () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
wrapper.find('.van-notice-bar__content').trigger('animationend');
|
wrapper.find('.van-notice-bar__content').trigger('transitionend');
|
||||||
await later();
|
await later(50);
|
||||||
expect(wrapper.emitted('replay')).toBeTruthy();
|
expect(wrapper.emitted('replay')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user