From d1448cb0ef10f358bb7bddb4e1ec268515e0b787 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 15 七月 2025 11:46:57 +0800
Subject: [PATCH] 项目初始化

---
 uni_modules/uview-ui/components/u-sticky/u-sticky.vue |  212 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 212 insertions(+), 0 deletions(-)

diff --git a/uni_modules/uview-ui/components/u-sticky/u-sticky.vue b/uni_modules/uview-ui/components/u-sticky/u-sticky.vue
new file mode 100644
index 0000000..ff74688
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-sticky/u-sticky.vue
@@ -0,0 +1,212 @@
+<template>
+	<view
+		class="u-sticky"
+		:id="elId"
+		:style="[style]"
+	>
+		<view
+			:style="[stickyContent]"
+			class="u-sticky__content"
+		>
+			<slot />
+		</view>
+	</view>
+</template>
+
+<script>
+	import props from './props.js';;
+	/**
+	 * sticky 鍚搁《
+	 * @description 璇ョ粍浠朵笌CSS涓璸osition: sticky灞炴�у疄鐜扮殑鏁堟灉涓�鑷达紝褰撶粍浠惰揪鍒伴璁剧殑鍒伴《閮ㄨ窛绂绘椂锛� 灏变細鍥哄畾鍦ㄦ寚瀹氫綅缃紝缁勪欢浣嶇疆澶т簬棰勮鐨勯《閮ㄨ窛绂绘椂锛屼細閲嶆柊鎸夌収姝e父鐨勫竷灞�鎺掑垪銆�
+	 * @tutorial https://www.uviewui.com/components/sticky.html
+	 * @property {String 锝� Number}	offsetTop		鍚搁《鏃朵笌椤堕儴鐨勮窛绂伙紝鍗曚綅px锛堥粯璁� 0 锛�
+	 * @property {String 锝� Number}	customNavHeight	鑷畾涔夊鑸爮鐨勯珮搴� 锛坔5 榛樿44  鍏朵粬榛樿 0 锛�
+	 * @property {Boolean}			disabled		鏄惁寮�鍚惛椤跺姛鑳� 锛堥粯璁� false 锛�
+	 * @property {String}			bgColor			缁勪欢鑳屾櫙棰滆壊锛堥粯璁� '#ffffff' 锛�
+	 * @property {String 锝� Number}	zIndex			鍚搁《鏃剁殑z-index鍊�
+	 * @property {String 锝� Number}	index			鑷畾涔夋爣璇嗭紝鐢ㄤ簬鍖哄垎鏄摢涓�涓粍浠�
+	 * @property {Object}			customStyle		缁勪欢鐨勬牱寮忥紝瀵硅薄褰㈠紡
+	 * @event {Function} fixed		缁勪欢鍚搁《鏃惰Е鍙�
+	 * @event {Function} unfixed	缁勪欢鍙栨秷鍚搁《鏃惰Е鍙�
+	 * @example <u-sticky offsetTop="200"><view>濉炰笅绉嬫潵椋庢櫙寮傦紝琛¢槼闆佸幓鏃犵暀鎰�</view></u-sticky>
+	 */
+	export default {
+		name: 'u-sticky',
+		mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+		data() {
+			return {
+				cssSticky: false, // 鏄惁浣跨敤css鐨剆ticky瀹炵幇
+				stickyTop: 0, // 鍚搁《鐨則op鍊硷紝鍥犱负鍙兘鍙楄嚜瀹氫箟瀵艰埅鏍忓奖鍝嶏紝鏈�缁堢殑鍚搁《鍊奸潪offsetTop鍊�
+				elId: uni.$u.guid(),
+				left: 0, // js妯″紡鏃讹紝鍚搁《鐨勫唴瀹瑰洜涓哄浜巔ostition: fixed妯″紡锛屼负浜嗗拰鍘熸潵淇濇寔涓�鑷寸殑鏍峰紡锛岄渶瑕佽褰曞苟閲嶆柊璁剧疆瀹冪殑left锛宧eight锛寃idth灞炴��
+				width: 'auto',
+				height: 'auto',
+				fixed: false, // js妯″紡鏃讹紝鏄惁澶勪簬鍚搁《妯″紡
+			}
+		},
+		computed: {
+			style() {
+				const style = {}
+				if(!this.disabled) {
+					if (this.cssSticky) {
+						style.position = 'sticky'
+						style.zIndex = this.uZindex
+						style.top = uni.$u.addUnit(this.stickyTop)
+					} else {
+						style.height = this.fixed ? this.height + 'px' : 'auto'
+					}
+				} else {
+					// 鏃犻渶鍚搁《鏃讹紝璁剧疆浼氶粯璁ょ殑relative(nvue)鍜岄潪nvue鐨剆tatic闈欐�佹ā寮忓嵆鍙�
+					// #ifdef APP-NVUE
+					style.position = 'relative'
+					// #endif
+					// #ifndef APP-NVUE
+					style.position = 'static'
+					// #endif
+				}
+				style.backgroundColor = this.bgColor
+				return uni.$u.deepMerge(uni.$u.addStyle(this.customStyle), style)
+			},
+			// 鍚搁《鍐呭鐨勬牱寮�
+			stickyContent() {
+				const style = {}
+				if (!this.cssSticky) {
+					style.position = this.fixed ? 'fixed' : 'static'
+					style.top = this.stickyTop + 'px'
+					style.left = this.left + 'px'
+					style.width = this.width == 'auto' ? 'auto' : this.width + 'px'
+					style.zIndex = this.uZindex
+				}
+				return style
+			},
+			uZindex() {
+				return this.zIndex ? this.zIndex : uni.$u.zIndex.sticky
+			}
+		},
+		mounted() {
+			this.init()
+		},
+		methods: {
+			init() {
+				this.getStickyTop()
+				// 鍒ゆ柇浣跨敤鐨勬ā寮�
+				this.checkSupportCssSticky()
+				// 濡傛灉涓嶆敮鎸乧ss sticky锛屽垯浣跨敤js鏂规锛屾鏂规鎬ц兘姣斾笉涓奵ss鏂规
+				if (!this.cssSticky) {
+					!this.disabled && this.initObserveContent()
+				}
+			},
+			initObserveContent() {
+				// 鑾峰彇鍚搁《鍐呭鐨勯珮搴︼紝鐢ㄤ簬鍦╦s鍚搁《妯″紡鏃讹紝缁欑埗鍏冪礌涓�涓~鍏呴珮搴︼紝闃叉"濉岄櫡"
+				this.$uGetRect('#' + this.elId).then((res) => {
+					this.height = res.height
+					this.left = res.left
+					this.width = res.width
+					this.$nextTick(() => {
+						this.observeContent()
+					})
+				})
+			},
+			observeContent() {
+				// 鍏堟柇鎺変箣鍓嶇殑瑙傚療
+				this.disconnectObserver('contentObserver')
+				const contentObserver = uni.createIntersectionObserver({
+					// 妫�娴嬬殑鍖洪棿鑼冨洿
+					thresholds: [0.95, 0.98, 1]
+				})
+				// 鍒板睆骞曢《閮ㄧ殑楂樺害鏃惰Е鍙�
+				contentObserver.relativeToViewport({
+					top: -this.stickyTop
+				})
+				// 缁戝畾瑙傚療鐨勫厓绱�
+				contentObserver.observe(`#${this.elId}`, res => {
+					this.setFixed(res.boundingClientRect.top)
+				})
+				this.contentObserver = contentObserver
+			},
+			setFixed(top) {
+				// 鍒ゆ柇鏄惁鍑轰簬鍚搁《鏉′欢鑼冨洿
+				const fixed = top <= this.stickyTop
+				this.fixed = fixed
+			},
+			disconnectObserver(observerName) {
+				// 鏂帀瑙傚療锛岄噴鏀捐祫婧�
+				const observer = this[observerName]
+				observer && observer.disconnect()
+			},
+			getStickyTop() {
+				this.stickyTop = uni.$u.getPx(this.offsetTop) + uni.$u.getPx(this.customNavHeight)
+			},
+			async checkSupportCssSticky() {
+				// #ifdef H5
+				// H5锛屼竴鑸兘鏄幇浠f祻瑙堝櫒锛屾槸鏀寔css sticky鐨勶紝杩欓噷浣跨敤鍒涘缓鍏冪礌鍡呮帰鐨勫舰寮忓垽鏂�
+				if (this.checkCssStickyForH5()) {
+					this.cssSticky = true
+				}
+				// #endif
+
+				// 濡傛灉瀹夊崜鐗堟湰楂樹簬8.0锛屼緷鐒惰涓烘槸鏀寔css sticky鐨�(鍥犱负瀹夊崜7鍦ㄦ煇浜涙満鍨嬶紝鍙兘涓嶆敮鎸乻ticky)
+				if (uni.$u.os() === 'android' && Number(uni.$u.sys().system) > 8) {
+					this.cssSticky = true
+				}
+
+				// APP-Vue鍜屽井淇″钩鍙帮紝閫氳繃computedStyle鍒ゆ柇鏄惁鏀寔css sticky
+				// #ifdef APP-VUE || MP-WEIXIN
+				this.cssSticky = await this.checkComputedStyle()
+				// #endif
+
+				// ios涓婏紝浠巌os6寮�濮嬶紝閮芥槸鏀寔css sticky鐨�
+				if (uni.$u.os() === 'ios') {
+					this.cssSticky = true
+				}
+
+				// nvue锛屾槸鏀寔css sticky鐨�
+				// #ifdef APP-NVUE
+				this.cssSticky = true
+				// #endif
+			},
+			// 鍦ˋPP鍜屽井淇″皬绋嬪簭涓婏紝閫氳繃uni.createSelectorQuery鍙互鍒ゆ柇鏄惁鏀寔css sticky
+			checkComputedStyle() {
+				// 鏂规硶鍐呰繘琛屽垽鏂紝閬垮厤鍦ㄥ叾浠栧钩鍙扮敓鎴愭棤鐢ㄤ唬鐮�
+				// #ifdef APP-VUE || MP-WEIXIN
+				return new Promise(resolve => {
+					uni.createSelectorQuery().in(this).select('.u-sticky').fields({
+						computedStyle: ["position"]
+					}).exec(e => {
+						resolve('sticky' === e[0].position)
+					})
+				})
+				// #endif
+			},
+			// H5閫氳繃鍒涘缓鍏冪礌鐨勫舰寮忓梾鎺㈡槸鍚︽敮鎸乧ss sticky
+			// 鍒ゆ柇娴忚鍣ㄦ槸鍚︽敮鎸乻ticky灞炴��
+			checkCssStickyForH5() {
+				// 鏂规硶鍐呰繘琛屽垽鏂紝閬垮厤鍦ㄥ叾浠栧钩鍙扮敓鎴愭棤鐢ㄤ唬鐮�
+				// #ifdef H5
+				const vendorList = ['', '-webkit-', '-ms-', '-moz-', '-o-'],
+					vendorListLength = vendorList.length,
+					stickyElement = document.createElement('div')
+				for (let i = 0; i < vendorListLength; i++) {
+					stickyElement.style.position = vendorList[i] + 'sticky'
+					if (stickyElement.style.position !== '') {
+						return true
+					}
+				}
+				return false;
+				// #endif
+			}
+		},
+		beforeDestroy() {
+			this.disconnectObserver('contentObserver')
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.u-sticky {
+		/* #ifdef APP-VUE || MP-WEIXIN */
+		// 姝ゅ榛樿鍐檚ticky灞炴�э紝鏄负浜嗙粰寰俊鍜孉PP閫氳繃uni.createSelectorQuery鏌ヨ鏄惁鏀寔css sticky浣跨敤
+		position: sticky;
+		/* #endif */
+	}
+</style>

--
Gitblit v1.9.3