| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- <template>
- <div class="sticky" :class="{ stickyed: data.stickyed }" :style="{ top: props.top }">
- <slot />
- </div>
- </template>
- <script lang="ts" setup>
- type stickyResult = UniApp.ObserveResult & { stickyed?: boolean }
- const props = withDefaults(
- defineProps<{
- top?: string
- relativeTo?: string
- targetSelector?: string
- targetComponent?: any
- }>(),
- {
- top: '',
- },
- )
- const emit = defineEmits<{ (e: 'stickChange', sr: stickyResult): void }>()
- const data = reactive({
- stickyed: false,
- })
- onMounted(() => {
- // #ifdef MP
- if (props.relativeTo && props.targetSelector) {
- const iob = uni.createIntersectionObserver(
- props.targetComponent || getCurrentInstance().parent.parent,
- )
- iob.relativeTo(props.relativeTo).observe(props.targetSelector, (res) => {
- const sr: stickyResult = res
- console.log(res.intersectionRatio)
- sr.stickyed = res.intersectionRatio > 0
- data.stickyed = sr.stickyed
- emit('stickChange', sr)
- })
- }
- // #endif
- })
- </script>
- <style lang="scss" scoped>
- .sticky {
- // 防止顶部镂空
- top: -1rpx;
- z-index: 1;
- // 防止部分真机误判相交状态
- margin-bottom: 1px;
- background-color: $bg-color;
- }
- .stickyed {
- border-bottom: 1rpx solid $border-color;
- @extend %box-shadow;
- &::before,
- &::after {
- position: absolute;
- top: 0;
- z-index: -1;
- width: $p-spac;
- height: 100%;
- content: '';
- background-color: #fff;
- border-bottom: 1rpx solid $border-color;
- }
- &::before {
- left: -$p-spac;
- }
- &::after {
- right: -$p-spac;
- }
- }
- </style>
|