mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-05-11 13:17:29 +08:00
fix: 搜索focus
This commit is contained in:
@@ -168,9 +168,19 @@ export default {
|
|||||||
const mobileMenuRef = ref(null)
|
const mobileMenuRef = ref(null)
|
||||||
const isMobile = useIsMobile()
|
const isMobile = useIsMobile()
|
||||||
|
|
||||||
|
const openMenu = () => {
|
||||||
|
if (!open.value) {
|
||||||
|
open.value = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const toggle = () => {
|
const toggle = () => {
|
||||||
open.value = !open.value
|
if (open.value) {
|
||||||
if (!open.value) emit('close')
|
open.value = false
|
||||||
|
emit('close')
|
||||||
|
} else {
|
||||||
|
open.value = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const close = () => {
|
const close = () => {
|
||||||
@@ -275,7 +285,7 @@ export default {
|
|||||||
return /^https?:\/\//.test(icon) || icon.startsWith('/')
|
return /^https?:\/\//.test(icon) || icon.startsWith('/')
|
||||||
}
|
}
|
||||||
|
|
||||||
expose({ toggle, close, reload, scrollToBottom })
|
expose({ toggle, close, reload, scrollToBottom, openMenu })
|
||||||
|
|
||||||
return {
|
return {
|
||||||
open,
|
open,
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
class="text-input"
|
class="text-input"
|
||||||
v-model="keyword"
|
v-model="keyword"
|
||||||
placeholder="键盘点击「/」以触发搜索"
|
placeholder="键盘点击「/」以触发搜索"
|
||||||
|
ref="searchInput"
|
||||||
@input="setSearch(keyword)"
|
@input="setSearch(keyword)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -48,7 +49,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch } from 'vue'
|
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||||
import Dropdown from '~/components/Dropdown.vue'
|
import Dropdown from '~/components/Dropdown.vue'
|
||||||
import { stripMarkdown } from '~/utils/markdown'
|
import { stripMarkdown } from '~/utils/markdown'
|
||||||
import { useIsMobile } from '~/utils/screen'
|
import { useIsMobile } from '~/utils/screen'
|
||||||
@@ -61,8 +62,48 @@ const keyword = ref('')
|
|||||||
const selected = ref(null)
|
const selected = ref(null)
|
||||||
const results = ref([])
|
const results = ref([])
|
||||||
const dropdown = ref(null)
|
const dropdown = ref(null)
|
||||||
|
const searchInput = ref(null)
|
||||||
const isMobile = useIsMobile()
|
const isMobile = useIsMobile()
|
||||||
|
|
||||||
|
const isEditableElement = (el) => {
|
||||||
|
if (!el) return false
|
||||||
|
if (el.isContentEditable) return true
|
||||||
|
const tagName = el.tagName ? el.tagName.toLowerCase() : ''
|
||||||
|
if (tagName === 'input' || tagName === 'textarea' || tagName === 'select') {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
const role = el.getAttribute ? el.getAttribute('role') : null
|
||||||
|
return role === 'textbox'
|
||||||
|
}
|
||||||
|
|
||||||
|
const focusSearchInput = () => {
|
||||||
|
if (!searchInput.value) return
|
||||||
|
dropdown.value?.openMenu?.()
|
||||||
|
if (typeof searchInput.value.focus === 'function') {
|
||||||
|
try {
|
||||||
|
searchInput.value.focus({ preventScroll: true })
|
||||||
|
} catch (e) {
|
||||||
|
searchInput.value.focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleGlobalSlash = (event) => {
|
||||||
|
if (event.defaultPrevented) return
|
||||||
|
if (event.key !== '/' || event.ctrlKey || event.metaKey || event.altKey) return
|
||||||
|
if (isEditableElement(document.activeElement)) return
|
||||||
|
event.preventDefault()
|
||||||
|
focusSearchInput()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
window.addEventListener('keydown', handleGlobalSlash)
|
||||||
|
})
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
window.removeEventListener('keydown', handleGlobalSlash)
|
||||||
|
})
|
||||||
|
|
||||||
const toggle = () => {
|
const toggle = () => {
|
||||||
dropdown.value.toggle()
|
dropdown.value.toggle()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user