|
@@ -1,7 +1,5 @@
|
|
|
-import {Component, Mixins, Ref} from "vue-property-decorator";
|
|
|
import {emitNames} from '../enum/emit';
|
|
|
import ScrollApi from '../api/scroll';
|
|
|
-import ScrollStatus from './status';
|
|
|
import {
|
|
|
Config,
|
|
|
EventTypes,
|
|
@@ -11,11 +9,20 @@ import {
|
|
|
ScrollYConfig
|
|
|
} from "../types/on";
|
|
|
|
|
|
-@Component({
|
|
|
+export default <LibMixins>{
|
|
|
|
|
|
- created(this:ScrollViewConfig){
|
|
|
- this._config = {};
|
|
|
- this._scrollConfig = {
|
|
|
+ computed:{
|
|
|
+ scrollEl:function (){
|
|
|
+ return this.$refs.scroll
|
|
|
+ },
|
|
|
+ scrollTakeEl:function (){
|
|
|
+ return this.$refs.scrollTake;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ created(){
|
|
|
+
|
|
|
+ let _scrollConfig:ScrollConfig = {
|
|
|
look:false,
|
|
|
stipitate:undefined,
|
|
|
x:{
|
|
@@ -31,219 +38,194 @@ import {
|
|
|
maxScroll:0
|
|
|
}
|
|
|
};
|
|
|
+ let _scrollApi:ScrollApi | undefined = undefined;
|
|
|
+ let _config:Config = {};
|
|
|
+ let _listeners = undefined;
|
|
|
+
|
|
|
+ this._config = _config;
|
|
|
+ this._scrollApi = _scrollApi;
|
|
|
+ this._listeners = _listeners;
|
|
|
+ this._scrollConfig = _scrollConfig;
|
|
|
+
|
|
|
},
|
|
|
|
|
|
- mounted(this:ScrollViewConfig){
|
|
|
+ mounted(){
|
|
|
// 执行安装
|
|
|
return this.installScroll();
|
|
|
},
|
|
|
|
|
|
// 释放组件的时候触发
|
|
|
- beforeDestroy(this:ScrollViewConfig){
|
|
|
+ beforeUnmount(){
|
|
|
this._scrollApi && this._scrollApi.destroy();
|
|
|
this._scrollConfig.stipitate&&clearTimeout(this._scrollConfig.stipitate);
|
|
|
this._scrollApi = undefined;
|
|
|
this.scrollEl && this._config.scrollUnique && this.removeEventListener(this.scrollEl,'scroll',this._config.scrollUnique);
|
|
|
- }
|
|
|
+ },
|
|
|
|
|
|
-})
|
|
|
-export default class ScrollViewConfig extends Mixins(ScrollStatus) {
|
|
|
-
|
|
|
- // 滚动标签实例
|
|
|
- @Ref('scroll') scrollEl:HTMLElement | undefined;
|
|
|
- // 滚动包容标签实例
|
|
|
- @Ref('scrollTake') scrollTakeEl:HTMLElement | undefined;
|
|
|
-
|
|
|
- // 运行时的 scrollApi
|
|
|
- _scrollApi:ScrollApi | undefined;
|
|
|
- // 运行时参数
|
|
|
- _config:Config={};
|
|
|
- // 滚动系列参数配置
|
|
|
- _scrollConfig:ScrollConfig={
|
|
|
- look:false,
|
|
|
- stipitate:undefined,
|
|
|
- x:{
|
|
|
- x:0,
|
|
|
- width:0,
|
|
|
- actualWidth:0,
|
|
|
- maxScroll:0
|
|
|
+ methods:{
|
|
|
+ // 配置滚动系列参数
|
|
|
+ setScrollConfig(){
|
|
|
+ if (this._scrollConfig.look) return;
|
|
|
+ // 设置锁
|
|
|
+ this._scrollConfig.look = true;
|
|
|
+ // 配置 x 轴
|
|
|
+ this.scrollX && this.setScrollAxisConfig('x');
|
|
|
+ // 配置 y 轴
|
|
|
+ this.scrollY && this.setScrollAxisConfig('y');
|
|
|
+ // 帧频率不允许重复
|
|
|
+ this._scrollConfig.stipitate = setTimeout(()=>{
|
|
|
+ this._scrollConfig.stipitate = undefined;
|
|
|
+ this._scrollConfig.look = false;
|
|
|
+ },16.66);
|
|
|
},
|
|
|
- y:{
|
|
|
- y:0,
|
|
|
- height:0,
|
|
|
- actualHeight:0,
|
|
|
- maxScroll:0
|
|
|
- }
|
|
|
- };
|
|
|
- // 配置滚动系列参数
|
|
|
- setScrollConfig(){
|
|
|
- if (this._scrollConfig.look) return;
|
|
|
- // 设置锁
|
|
|
- this._scrollConfig.look = true;
|
|
|
- // 配置 x 轴
|
|
|
- this.scrollX && this.setScrollAxisConfig('x');
|
|
|
- // 配置 y 轴
|
|
|
- this.scrollY && this.setScrollAxisConfig('y');
|
|
|
- // 帧频率不允许重复
|
|
|
- this._scrollConfig.stipitate = setTimeout(()=>{
|
|
|
- this._scrollConfig.stipitate = undefined;
|
|
|
- this._scrollConfig.look = false;
|
|
|
- },16.66);
|
|
|
- };
|
|
|
- // 配置单独轴系列参数
|
|
|
- setScrollAxisConfig(axis:'x' | 'y'){
|
|
|
-
|
|
|
- if (this.scrollEl === undefined || this.scrollTakeEl === undefined) return;
|
|
|
-
|
|
|
- let sizeKey: 'width' | 'height' = axis === 'x' ? 'width':'height';
|
|
|
- let actualKey : 'actualWidth' | 'actualHeight' = axis === 'x' ? 'actualWidth' :'actualHeight';
|
|
|
- let scrollAxis: 'scrollLeft' | 'scrollTop' = axis === 'x'? 'scrollLeft' :'scrollTop';
|
|
|
- let elSizeKey:'offsetWidth' | 'offsetHeight' = axis === 'x' ? 'offsetWidth' :'offsetHeight';
|
|
|
-
|
|
|
- // 设置配置文件
|
|
|
- // @ts-ignore
|
|
|
- this._scrollConfig[axis] = {
|
|
|
- [sizeKey]: this.scrollEl[elSizeKey] || 0,
|
|
|
- [axis]: this.scrollEl[scrollAxis] || 0,
|
|
|
- [actualKey]: this.scrollTakeEl[elSizeKey] || 0,
|
|
|
- maxScroll:0
|
|
|
- };
|
|
|
- //
|
|
|
- // // 设置最大滚动
|
|
|
- // @ts-ignore
|
|
|
- (this._scrollConfig[axis] as ScrollYConfig | ScrollXConfig).maxScroll = Math.max(0,this._scrollConfig[axis][actualKey] - this._scrollConfig[axis][sizeKey]);
|
|
|
|
|
|
- };
|
|
|
- // 安装
|
|
|
- installScroll(){
|
|
|
+ // 配置单独轴系列参数
|
|
|
+ setScrollAxisConfig(axis:'x' | 'y'){
|
|
|
|
|
|
- // 设置当前的配置文件
|
|
|
- this.setScrollConfig();
|
|
|
+ if (this.scrollEl === undefined || this.scrollTakeEl === undefined) return;
|
|
|
|
|
|
- // 创建滚动Api
|
|
|
- if (this.scrollEl !== undefined) {
|
|
|
- this._scrollApi = new ScrollApi(this._scrollConfig,this.scrollEl);
|
|
|
- }
|
|
|
+ let sizeKey: 'width' | 'height' = axis === 'x' ? 'width':'height';
|
|
|
+ let actualKey : 'actualWidth' | 'actualHeight' = axis === 'x' ? 'actualWidth' :'actualHeight';
|
|
|
+ let scrollAxis: 'scrollLeft' | 'scrollTop' = axis === 'x'? 'scrollLeft' :'scrollTop';
|
|
|
+ let elSizeKey:'offsetWidth' | 'offsetHeight' = axis === 'x' ? 'offsetWidth' :'offsetHeight';
|
|
|
|
|
|
- // 如果存在此三种的任何一种 事件开启监听
|
|
|
- if (
|
|
|
- (this.$listeners[emitNames.onScroll]
|
|
|
- ||
|
|
|
- this.$listeners[emitNames.onScrollLower]
|
|
|
- ||
|
|
|
- this.$listeners[emitNames.onScrollUpper]) && this.scrollEl !== undefined
|
|
|
- ) {
|
|
|
-
|
|
|
- // 获取存储的唯一标识
|
|
|
- this._config.scrollUnique = this.addEventListener(this.scrollEl,'scroll',()=> this.onScroll());
|
|
|
- }
|
|
|
+ // 设置配置文件
|
|
|
+ // @ts-ignore
|
|
|
+ this._scrollConfig[axis] = {
|
|
|
+ [sizeKey]: this.scrollEl[elSizeKey] || 0,
|
|
|
+ [axis]: this.scrollEl[scrollAxis] || 0,
|
|
|
+ [actualKey]: this.scrollTakeEl[elSizeKey] || 0,
|
|
|
+ maxScroll:0
|
|
|
+ };
|
|
|
+ //
|
|
|
+ // // 设置最大滚动
|
|
|
+ // @ts-ignore
|
|
|
+ (this._scrollConfig[axis] as ScrollYConfig | ScrollXConfig).maxScroll = Math.max(0,this._scrollConfig[axis][actualKey] - this._scrollConfig[axis][sizeKey]);
|
|
|
|
|
|
- }
|
|
|
- // 滚动时触发
|
|
|
- onScroll(){
|
|
|
- if (this.scrollEl) {
|
|
|
- // 设置配置
|
|
|
+ },
|
|
|
+ // 安装
|
|
|
+ installScroll(){
|
|
|
+
|
|
|
+ // 设置当前的配置文件
|
|
|
this.setScrollConfig();
|
|
|
|
|
|
- if (this.$listeners[emitNames.onScrollUpper] || this.$listeners[emitNames.onScrollLower]) {
|
|
|
+ // 创建滚动Api
|
|
|
+ if (this.scrollEl !== undefined) {
|
|
|
+ this._scrollApi = new ScrollApi(this._scrollConfig,this.scrollEl);
|
|
|
+ }
|
|
|
|
|
|
- if (this.scrollY) {
|
|
|
- if ( this.$listeners[emitNames.onScrollLower] && this.testScrollDistance('y','lowerThreshold','_lowerThresholdYStatus')) {
|
|
|
- this.emitScrollLower('y');
|
|
|
- } else if (this.$listeners[emitNames.onScrollUpper] && this.testScrollDistance('y','upperThreshold','_upperThresholdYStatus')) {
|
|
|
- this.emitScrollUpper('y');
|
|
|
+ // 如果存在此三种的任何一种 事件开启监听
|
|
|
+ if (
|
|
|
+ (this.$attrs[emitNames.onScroll]
|
|
|
+ ||
|
|
|
+ this.$attrs[emitNames.onScrollLower]
|
|
|
+ ||
|
|
|
+ this.$attrs[emitNames.onScrollUpper]) && this.scrollEl !== undefined
|
|
|
+ ) {
|
|
|
+
|
|
|
+ // 获取存储的唯一标识
|
|
|
+ this._config.scrollUnique = this.addEventListener(this.scrollEl,'scroll',()=> this.onScroll());
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ // 滚动时触发
|
|
|
+ onScroll(){
|
|
|
+ if (this.scrollEl) {
|
|
|
+ // 设置配置
|
|
|
+ this.setScrollConfig();
|
|
|
+
|
|
|
+ if (this.$listeners[emitNames.onScrollUpper] || this.$listeners[emitNames.onScrollLower]) {
|
|
|
+
|
|
|
+ if (this.scrollY) {
|
|
|
+ if ( this.$listeners[emitNames.onScrollLower] && this.testScrollDistance('y','lowerThreshold','_lowerThresholdYStatus')) {
|
|
|
+ this.emitScrollLower('y');
|
|
|
+ } else if (this.$listeners[emitNames.onScrollUpper] && this.testScrollDistance('y','upperThreshold','_upperThresholdYStatus')) {
|
|
|
+ this.emitScrollUpper('y');
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- if (this.scrollX) {
|
|
|
- if ( this.$listeners[emitNames.onScrollLower] && this.testScrollDistance('x','lowerThreshold','_lowerThresholdXStatus')) {
|
|
|
- this.emitScrollLower('x');
|
|
|
- } else if (this.$listeners[emitNames.onScrollUpper] && this.testScrollDistance('x','upperThreshold','_upperThresholdXStatus')) {
|
|
|
- this.emitScrollUpper('x');
|
|
|
+ if (this.scrollX) {
|
|
|
+ if ( this.$listeners[emitNames.onScrollLower] && this.testScrollDistance('x','lowerThreshold','_lowerThresholdXStatus')) {
|
|
|
+ this.emitScrollLower('x');
|
|
|
+ } else if (this.$listeners[emitNames.onScrollUpper] && this.testScrollDistance('x','upperThreshold','_upperThresholdXStatus')) {
|
|
|
+ this.emitScrollUpper('x');
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
- }
|
|
|
+ if(this.$listeners[emitNames.onScroll]) {
|
|
|
+ return this.emitScroll(this._scrollConfig);
|
|
|
+ }
|
|
|
|
|
|
- if(this.$listeners[emitNames.onScroll]) {
|
|
|
- return this.emitScroll(this._scrollConfig);
|
|
|
}
|
|
|
+ },
|
|
|
|
|
|
- }
|
|
|
- }
|
|
|
+ // 校验是否满足条件
|
|
|
+ testScrollDistance(axis:'x' | 'y',key:'lowerThreshold' | 'upperThreshold',testKey:'_lowerThresholdXStatus'|'_lowerThresholdYStatus'|'_upperThresholdXStatus'|'_upperThresholdYStatus'){
|
|
|
|
|
|
- // 校验是否满足条件
|
|
|
- testScrollDistance(axis:'x' | 'y',key:'lowerThreshold' | 'upperThreshold',testKey:'_lowerThresholdXStatus'|'_lowerThresholdYStatus'|'_upperThresholdXStatus'|'_upperThresholdYStatus'){
|
|
|
+ if (
|
|
|
+ this[key] !== undefined
|
|
|
+ &&
|
|
|
+ key === 'upperThreshold' ? this._scrollConfig[axis][axis] <= this[key] : this._scrollConfig[axis].maxScroll - this._scrollConfig[axis][axis] <= this[key]
|
|
|
+ ) {
|
|
|
|
|
|
- if (
|
|
|
- this[key] !== undefined
|
|
|
- &&
|
|
|
- // @ts-ignore
|
|
|
- key === 'upperThreshold' ? this._scrollConfig[axis][axis] <= this[key] : this._scrollConfig[axis].maxScroll - this._scrollConfig[axis][axis] <= this[key]
|
|
|
- ) {
|
|
|
+ if (!this[testKey]) {
|
|
|
+ this[testKey] = true;
|
|
|
|
|
|
- if (!this[testKey]) {
|
|
|
- this[testKey] = true;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
|
|
|
- return true;
|
|
|
+ } else {
|
|
|
+ this[testKey] = false;
|
|
|
}
|
|
|
+ return false;
|
|
|
|
|
|
- } else {
|
|
|
- this[testKey] = false;
|
|
|
- }
|
|
|
- return false;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // 监听器对象
|
|
|
- _listeners: { [key:string]:ListenerEventTarget } | undefined = undefined;
|
|
|
-
|
|
|
- // 添加监听
|
|
|
- addEventListener<T extends EventTypes>(el:HTMLElement,event:T,target:ListenerEventTarget){
|
|
|
- // 如果没有监听器对象创建
|
|
|
- if (this._listeners === undefined) {
|
|
|
- this._listeners = {};
|
|
|
- }
|
|
|
-
|
|
|
- let unique:string = this.getUnique(event);
|
|
|
+ },
|
|
|
|
|
|
- this._listeners[unique] = target;
|
|
|
+ // 添加监听
|
|
|
+ addEventListener<T extends EventTypes>(el:HTMLElement,event:T,target:ListenerEventTarget){
|
|
|
+ // 如果没有监听器对象创建
|
|
|
+ if (this._listeners === undefined) {
|
|
|
+ this._listeners = {};
|
|
|
+ }
|
|
|
|
|
|
- if (window.addEventListener !== undefined) {
|
|
|
- el.addEventListener(event,target,{
|
|
|
- passive:true
|
|
|
- });
|
|
|
- } else {
|
|
|
- // @ts-ignore 兼容策略
|
|
|
- el.attachEvent('on'+event,target,{
|
|
|
- passive:true
|
|
|
- });
|
|
|
- }
|
|
|
+ let unique:string = this.getUnique(event);
|
|
|
|
|
|
- return unique;
|
|
|
- }
|
|
|
+ this._listeners[unique] = target;
|
|
|
|
|
|
- // 移除兼容
|
|
|
- removeEventListener<K extends EventTypes>(el:HTMLElement,event:K,unique:string){
|
|
|
- if (this._listeners !== undefined && this._listeners[unique] !== undefined) {
|
|
|
- if (window.removeEventListener !== undefined) {
|
|
|
- el.removeEventListener(event, this._listeners[unique]);
|
|
|
+ if (window.addEventListener !== undefined) {
|
|
|
+ el.addEventListener(event,target,{
|
|
|
+ passive:true
|
|
|
+ });
|
|
|
} else {
|
|
|
// @ts-ignore 兼容策略
|
|
|
- el.detachEvent('on' + event, this._listeners[unique]);
|
|
|
+ el.attachEvent('on'+event,target,{
|
|
|
+ passive:true
|
|
|
+ });
|
|
|
}
|
|
|
- return true;
|
|
|
- } else {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
|
|
|
+ return unique;
|
|
|
+ },
|
|
|
|
|
|
- }
|
|
|
+ // 移除兼容
|
|
|
+ removeEventListener<K extends EventTypes>(el:HTMLElement,event:K,unique:string){
|
|
|
+ if (this._listeners !== undefined && this._listeners[unique] !== undefined) {
|
|
|
+ if (window.removeEventListener !== undefined) {
|
|
|
+ el.removeEventListener(event, this._listeners[unique]);
|
|
|
+ } else {
|
|
|
+ // @ts-ignore 兼容策略
|
|
|
+ el.detachEvent('on' + event, this._listeners[unique]);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ },
|
|
|
|
|
|
- // 获取唯一值
|
|
|
- getUnique(value:string=''):string{
|
|
|
- return new Date().getTime() + value + Math.floor(Math.random() * 10000) ;
|
|
|
+ // 获取唯一值
|
|
|
+ getUnique(value:string=''):string{
|
|
|
+ return new Date().getTime() + value + Math.floor(Math.random() * 10000) ;
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
}
|