|
|
|
@ -0,0 +1,103 @@ |
|
|
|
export default { |
|
|
|
install(Vue) { |
|
|
|
Vue.prototype.$scrollTo = function(el, behavior = 'smooth', retryCount = 0) { |
|
|
|
if (!el) { |
|
|
|
console.warn('scrollTo: 元素参数为空') |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
const maxRetries = 3 |
|
|
|
const retryDelay = 100 // 100ms
|
|
|
|
|
|
|
|
let targetEL = typeof el === 'string' ? this.$refs[el] : el |
|
|
|
|
|
|
|
console.log(`scrollTo called with: ${el} (尝试次数: ${retryCount + 1})`) |
|
|
|
console.log('原始targetEL:', targetEL) |
|
|
|
|
|
|
|
// 如果targetEL为undefined且还有重试次数,则延迟重试
|
|
|
|
if (!targetEL && retryCount < maxRetries) { |
|
|
|
console.log(`元素未找到,${retryDelay}ms后重试...`) |
|
|
|
setTimeout(() => { |
|
|
|
this.$scrollTo(el, behavior, retryCount + 1) |
|
|
|
}, retryDelay) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
// 如果重试次数用完仍未找到元素,输出详细信息
|
|
|
|
if (!targetEL) { |
|
|
|
console.error(`scrollTo: 经过${maxRetries + 1}次尝试仍未找到元素 "${el}"`) |
|
|
|
console.log('当前可用的refs:', Object.keys(this.$refs)) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
// 如果targetEL是数组,取第一个元素
|
|
|
|
if (Array.isArray(targetEL) && targetEL.length > 0) { |
|
|
|
targetEL = targetEL[0] |
|
|
|
console.log('检测到数组,取第一个元素:', targetEL) |
|
|
|
} else if (Array.isArray(targetEL) && targetEL.length === 0) { |
|
|
|
console.error('scrollTo: 找到的是空数组') |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
if (targetEL) { |
|
|
|
// #ifdef H5
|
|
|
|
console.log('进h5环境的滚动插件了'); |
|
|
|
console.log('targetEL类型:', typeof targetEL); |
|
|
|
console.log('targetEL是否有$el属性:', !!targetEL.$el); |
|
|
|
console.log('targetEL是否有scrollIntoView方法:', !!targetEL.scrollIntoView); |
|
|
|
|
|
|
|
try { |
|
|
|
// H5环境下使用原生的scrollIntoView方法
|
|
|
|
if (targetEL.$el) { |
|
|
|
// 如果是Vue组件(uni-app的view等组件),获取其DOM元素
|
|
|
|
console.log('检测到uni-app Vue组件,使用$el获取DOM元素'); |
|
|
|
console.log('DOM元素:', targetEL.$el); |
|
|
|
|
|
|
|
targetEL.$el.scrollIntoView({ |
|
|
|
behavior: behavior, |
|
|
|
block: 'start', |
|
|
|
inline: 'nearest' |
|
|
|
}) |
|
|
|
console.log('✅ 滚动成功') |
|
|
|
} else if (targetEL.scrollIntoView) { |
|
|
|
console.log('检测到原生DOM元素'); |
|
|
|
// 如果是原生DOM元素
|
|
|
|
targetEL.scrollIntoView({ |
|
|
|
behavior: behavior, |
|
|
|
block: 'start', |
|
|
|
inline: 'nearest' |
|
|
|
}) |
|
|
|
console.log('✅ 滚动成功') |
|
|
|
} else { |
|
|
|
console.log('无法识别的元素类型,尝试其他方法'); |
|
|
|
// 如果都不是,可能需要其他处理方式
|
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
console.error('scrollTo 执行失败:', error) |
|
|
|
} |
|
|
|
// #endif
|
|
|
|
|
|
|
|
// #ifndef H5
|
|
|
|
// 非H5环境(小程序等)使用uni.pageScrollTo
|
|
|
|
const query = uni.createSelectorQuery().in(this) |
|
|
|
query.select(`[ref="${el}"]`).boundingClientRect((data) => { |
|
|
|
console.log('element position:', data) |
|
|
|
if (data) { |
|
|
|
uni.pageScrollTo({ |
|
|
|
scrollTop: data.top, |
|
|
|
duration: behavior === 'smooth' ? 300 : 0 |
|
|
|
}) |
|
|
|
console.log('✅ 滚动成功') |
|
|
|
} else { |
|
|
|
console.error('scrollTo: 未找到元素位置信息') |
|
|
|
} |
|
|
|
}).exec() |
|
|
|
// #endif
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 使用方式
|
|
|
|
// 在 main.js 中引入:Vue.use(require('./plugins/scrollTo'))
|
|
|
|
// 然后在组件中:this.$scrollTo('targetRef')
|