diff --git a/src/image-preview/ImagePreview.js b/src/image-preview/ImagePreview.js index 628540fe3..f90c3226e 100644 --- a/src/image-preview/ImagePreview.js +++ b/src/image-preview/ImagePreview.js @@ -1,8 +1,9 @@ -import { createNamespace, isServer } from '../utils'; +import { createNamespace } from '../utils'; import { range } from '../utils/format/number'; import { preventDefault } from '../utils/dom/event'; import { PopupMixin } from '../mixins/popup'; import { TouchMixin } from '../mixins/touch'; +import { CloseOnPopstateMixin } from '../mixins/close-on-popstate'; import Swipe from '../swipe'; import SwipeItem from '../swipe-item'; @@ -18,7 +19,11 @@ function getDistance(touches) { } export default createComponent({ - mixins: [PopupMixin, TouchMixin], + mixins: [ + PopupMixin, + TouchMixin, + CloseOnPopstateMixin + ], props: { images: Array, @@ -27,7 +32,6 @@ export default createComponent({ asyncClose: Boolean, startPosition: Number, showIndicators: Boolean, - closeOnPopstate: Boolean, loop: { type: Boolean, default: true @@ -94,30 +98,10 @@ export default createComponent({ startPosition(active) { this.active = active; - }, - - closeOnPopstate: { - handler(val) { - this.handlePopstate(val); - }, - immediate: true } }, methods: { - handlePopstate(bind) { - /* istanbul ignore if */ - if (isServer) { - return; - } - - if (this.bindStatus !== bind) { - this.bindStatus = bind; - const action = bind ? 'add' : 'remove'; - window[`${action}EventListener`]('popstate', this.close); - } - }, - onWrapperTouchStart() { this.touchStartTime = new Date(); }, diff --git a/src/mixins/bind-event.ts b/src/mixins/bind-event.ts index a970d543c..f7dae60ec 100644 --- a/src/mixins/bind-event.ts +++ b/src/mixins/bind-event.ts @@ -7,7 +7,9 @@ type BindEventMixinThis = { binded: boolean; }; -export function BindEventMixin(handler: Function) { +type BindEventHandler = (bind: Function, isBind: boolean) => void; + +export function BindEventMixin(handler: BindEventHandler) { function bind(this: BindEventMixinThis) { if (!this.binded) { handler.call(this, on, true); diff --git a/src/mixins/close-on-popstate.ts b/src/mixins/close-on-popstate.ts new file mode 100644 index 000000000..2ede0f115 --- /dev/null +++ b/src/mixins/close-on-popstate.ts @@ -0,0 +1,40 @@ +import Vue from 'vue'; +import { on, off } from '../utils/dom/event'; +import { BindEventMixin } from './bind-event'; + +export const CloseOnPopstateMixin = Vue.extend({ + mixins: [BindEventMixin(function (this: any, bind, isBind) { + this.onPopstate(isBind); + })], + + props: { + closeOnPopstate: Boolean + }, + + data() { + return { + bindStatus: false + }; + }, + + watch: { + closeOnPopstate(val: boolean) { + this.onPopstate(val); + } + }, + + methods: { + onPopstate(bind: boolean) { + /* istanbul ignore if */ + if (this.$isServer) { + return; + } + + if (this.bindStatus !== bind) { + this.bindStatus = bind; + const action = bind ? on : off; + action(window, 'popstate', (this as any).close); + } + } + } +}); diff --git a/src/utils/dom/event.ts b/src/utils/dom/event.ts index 67ed5eb95..add54873d 100644 --- a/src/utils/dom/event.ts +++ b/src/utils/dom/event.ts @@ -20,7 +20,7 @@ if (!isServer) { } export function on( - target: HTMLElement | Document, + target: HTMLElement | Document | Window, event: string, handler: EventHandler, passive = false @@ -35,7 +35,7 @@ export function on( } export function off( - target: HTMLElement | Document, + target: HTMLElement | Document | Window, event: string, handler: EventHandler ) {