index.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. exports.__esModule = true;
  4. exports.default = void 0;
  5. var _utils = require("../utils");
  6. var _raf = require("../utils/dom/raf");
  7. var _bindEvent = require("../mixins/bind-event");
  8. var _icon = _interopRequireDefault(require("../icon"));
  9. var _createNamespace = (0, _utils.createNamespace)('notice-bar'),
  10. createComponent = _createNamespace[0],
  11. bem = _createNamespace[1];
  12. var _default = createComponent({
  13. mixins: [(0, _bindEvent.BindEventMixin)(function (bind) {
  14. // fix cache issues with forwards and back history in safari
  15. // see: https://guwii.com/cache-issues-with-forwards-and-back-history-in-safari/
  16. bind(window, 'pageshow', this.start);
  17. })],
  18. inject: {
  19. vanPopup: {
  20. default: null
  21. }
  22. },
  23. props: {
  24. text: String,
  25. mode: String,
  26. color: String,
  27. leftIcon: String,
  28. wrapable: Boolean,
  29. background: String,
  30. scrollable: {
  31. type: Boolean,
  32. default: null
  33. },
  34. delay: {
  35. type: [Number, String],
  36. default: 1
  37. },
  38. speed: {
  39. type: [Number, String],
  40. default: 60
  41. }
  42. },
  43. data: function data() {
  44. return {
  45. show: true,
  46. offset: 0,
  47. duration: 0,
  48. wrapWidth: 0,
  49. contentWidth: 0
  50. };
  51. },
  52. watch: {
  53. scrollable: 'start',
  54. text: {
  55. handler: 'start',
  56. immediate: true
  57. }
  58. },
  59. created: function created() {
  60. var _this = this;
  61. // https://github.com/youzan/vant/issues/8634
  62. if (this.vanPopup) {
  63. this.vanPopup.onReopen(function () {
  64. _this.start();
  65. });
  66. }
  67. },
  68. activated: function activated() {
  69. this.start();
  70. },
  71. methods: {
  72. onClickIcon: function onClickIcon(event) {
  73. if (this.mode === 'closeable') {
  74. this.show = false;
  75. this.$emit('close', event);
  76. }
  77. },
  78. onTransitionEnd: function onTransitionEnd() {
  79. var _this2 = this;
  80. this.offset = this.wrapWidth;
  81. this.duration = 0; // wait for Vue to render offset
  82. // using nextTick won't work in iOS14
  83. (0, _raf.raf)(function () {
  84. // use double raf to ensure animation can start
  85. (0, _raf.doubleRaf)(function () {
  86. _this2.offset = -_this2.contentWidth;
  87. _this2.duration = (_this2.contentWidth + _this2.wrapWidth) / _this2.speed;
  88. _this2.$emit('replay');
  89. });
  90. });
  91. },
  92. reset: function reset() {
  93. this.offset = 0;
  94. this.duration = 0;
  95. this.wrapWidth = 0;
  96. this.contentWidth = 0;
  97. },
  98. start: function start() {
  99. var _this3 = this;
  100. var delay = (0, _utils.isDef)(this.delay) ? this.delay * 1000 : 0;
  101. this.reset();
  102. clearTimeout(this.startTimer);
  103. this.startTimer = setTimeout(function () {
  104. var _this3$$refs = _this3.$refs,
  105. wrap = _this3$$refs.wrap,
  106. content = _this3$$refs.content;
  107. if (!wrap || !content || _this3.scrollable === false) {
  108. return;
  109. }
  110. var wrapWidth = wrap.getBoundingClientRect().width;
  111. var contentWidth = content.getBoundingClientRect().width;
  112. if (_this3.scrollable || contentWidth > wrapWidth) {
  113. (0, _raf.doubleRaf)(function () {
  114. _this3.offset = -contentWidth;
  115. _this3.duration = contentWidth / _this3.speed;
  116. _this3.wrapWidth = wrapWidth;
  117. _this3.contentWidth = contentWidth;
  118. });
  119. }
  120. }, delay);
  121. }
  122. },
  123. render: function render() {
  124. var _this4 = this;
  125. var h = arguments[0];
  126. var slots = this.slots,
  127. mode = this.mode,
  128. leftIcon = this.leftIcon,
  129. onClickIcon = this.onClickIcon;
  130. var barStyle = {
  131. color: this.color,
  132. background: this.background
  133. };
  134. var contentStyle = {
  135. transform: this.offset ? "translateX(" + this.offset + "px)" : '',
  136. transitionDuration: this.duration + 's'
  137. };
  138. function LeftIcon() {
  139. var slot = slots('left-icon');
  140. if (slot) {
  141. return slot;
  142. }
  143. if (leftIcon) {
  144. return h(_icon.default, {
  145. "class": bem('left-icon'),
  146. "attrs": {
  147. "name": leftIcon
  148. }
  149. });
  150. }
  151. }
  152. function RightIcon() {
  153. var slot = slots('right-icon');
  154. if (slot) {
  155. return slot;
  156. }
  157. var iconName;
  158. if (mode === 'closeable') {
  159. iconName = 'cross';
  160. } else if (mode === 'link') {
  161. iconName = 'arrow';
  162. }
  163. if (iconName) {
  164. return h(_icon.default, {
  165. "class": bem('right-icon'),
  166. "attrs": {
  167. "name": iconName
  168. },
  169. "on": {
  170. "click": onClickIcon
  171. }
  172. });
  173. }
  174. }
  175. return h("div", {
  176. "attrs": {
  177. "role": "alert"
  178. },
  179. "directives": [{
  180. name: "show",
  181. value: this.show
  182. }],
  183. "class": bem({
  184. wrapable: this.wrapable
  185. }),
  186. "style": barStyle,
  187. "on": {
  188. "click": function click(event) {
  189. _this4.$emit('click', event);
  190. }
  191. }
  192. }, [LeftIcon(), h("div", {
  193. "ref": "wrap",
  194. "class": bem('wrap'),
  195. "attrs": {
  196. "role": "marquee"
  197. }
  198. }, [h("div", {
  199. "ref": "content",
  200. "class": [bem('content'), {
  201. 'van-ellipsis': this.scrollable === false && !this.wrapable
  202. }],
  203. "style": contentStyle,
  204. "on": {
  205. "transitionend": this.onTransitionEnd
  206. }
  207. }, [this.slots() || this.text])]), RightIcon()]);
  208. }
  209. });
  210. exports.default = _default;