update
This commit is contained in:
@@ -9,18 +9,17 @@
|
||||
</div>
|
||||
<Teleport to="#dropdowns">
|
||||
<div
|
||||
v-if="visible"
|
||||
ref="dropdown"
|
||||
class="dropdown"
|
||||
:class="{ visible }"
|
||||
@onmouseleave="visible = false">
|
||||
@mouseleave="visible = false">
|
||||
<slot name="content" />
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
const trigger = ref<HTMLDivElement>();
|
||||
const dropdown = ref<HTMLDivElement>();
|
||||
@@ -28,13 +27,17 @@
|
||||
const visible = ref(false);
|
||||
const top = ref('0px');
|
||||
const left = ref('0px');
|
||||
const effectiveTop = computed(() => visible.value ? top.value : 0);
|
||||
const effectiveLeft = computed(() => visible.value ? left.value : 0);
|
||||
|
||||
function onMouseEnter(e: MouseEvent | TouchEvent) {
|
||||
visible.value = true;
|
||||
if (trigger.value) {
|
||||
const rect = trigger.value.getBoundingClientRect();
|
||||
top.value = rect.top + 'px';
|
||||
left.value = rect.width + rect.left + 'px';
|
||||
if (trigger.value && dropdown.value) {
|
||||
const rectTrigger = trigger.value.getBoundingClientRect();
|
||||
const rectDropdown = dropdown.value.getBoundingClientRect();
|
||||
console.log(rectDropdown);
|
||||
top.value = Math.min(window.innerHeight - rectDropdown.height, rectTrigger.top) + 'px';
|
||||
left.value = rectTrigger.width + rectTrigger.left + 'px';
|
||||
}
|
||||
window.addEventListener('touchstart', onWindowClick);
|
||||
window.addEventListener('click', onWindowClick);
|
||||
@@ -57,7 +60,7 @@
|
||||
}
|
||||
|
||||
function onMouseLeave(e: MouseEvent) {
|
||||
if (trigger.value && outside(e, trigger.value)) {
|
||||
if (trigger.value && outside(e, trigger.value) && dropdown.value && outside(e, dropdown.value)) {
|
||||
visible.value = false;
|
||||
}
|
||||
}
|
||||
@@ -66,8 +69,8 @@
|
||||
<style scoped lang="scss">
|
||||
.dropdown {
|
||||
position: absolute;
|
||||
top: v-bind(top);
|
||||
left: v-bind(left);
|
||||
top: v-bind(effectiveTop);
|
||||
left: v-bind(effectiveLeft);
|
||||
visibility: hidden;
|
||||
|
||||
&.visible {
|
||||
|
||||
Reference in New Issue
Block a user