Skip to content

Commit

Permalink
fix:全局搜索代码优化,修复1280屏幕下搜索框focus位置错误问题
Browse files Browse the repository at this point in the history
# Reviewed, transaction id: 11855
  • Loading branch information
leafage-collb committed Jul 11, 2024
1 parent f06d66d commit 9176387
Show file tree
Hide file tree
Showing 6 changed files with 978 additions and 911 deletions.
2 changes: 1 addition & 1 deletion webfe/package_vue/src/assets/css/ps-style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ span.ellipsis {
z-index: 9999;

.drop-content {
box-shadow: 0 2px 6px 0 #0000001a;
box-shadow: 0px 0px 5px #e5e5e5;
}
}

Expand Down
282 changes: 282 additions & 0 deletions webfe/package_vue/src/components/global-search/search-input.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
<template>
<div class="mr20 global-search-modal">
<!-- 查看态 -->
<div
ref="outFocusRef"
class="out-focus-tool"
@click="handleSearchFocus"
>
<span>{{ filterKey ? filterKey : $t('搜索') }}</span>
<i
class="input-right-icon bk-icon bk-icon icon-search"
@click="handleEnter"
/>
</div>
<!-- focus -->
<div
v-show="isFocus"
class="global-search-focus"
:style="{ left: leftPosition + 'px' }"
>
<div
:class="['ps-search', 'clearfix', { focus: isFocus }]"
v-bk-clickoutside="handleClickOutSide"
>
<input
ref="searchInputRef"
v-model="filterKey"
type="text"
:placeholder="$t('搜索')"
@keypress.enter="handleEnter"
@focus="handleFocus"
/>
<i
v-if="filterKey && isFocus"
class="bk-icon icon-close-circle-shape clear-icon"
@click="clearInputValue"
/>
<i
class="input-right-icon bk-icon bk-icon icon-search"
@click="handleEnter"
/>
</div>
<div class="search-result-content">
<search-result
ref="searchRef"
:search-history="searchHistory"
:search-value="filterKey"
@close-search-mode="handleSearchClose"
@load-history="loadSearchHistory"
@change="handleChange"
/>
</div>
</div>
</div>
</template>

<script>
import searchResult from './search-result.vue';
import { parentClsContains } from '@/common/tools';
const SEARCHWIDTH = 720; // 固定元素的宽度
export default {
name: 'GlobalSearch',
components: {
searchResult,
},
data() {
return {
isFocus: false,
leftPosition: 0,
filterKey: '',
searchHistory: [],
toolEl: null,
};
},
mounted() {
this.toolEl = this.$refs.outFocusRef;
window.addEventListener('resize', this.updateFixedElementPosition);
},
beforeDestroy() {
window.removeEventListener('resize', this.updateFixedElementPosition);
},
methods: {
// 更新 focus 状态下全局搜索框的位置
updateFixedElementPosition() {
const toolRect = this.toolEl.getBoundingClientRect();
this.leftPosition = toolRect.right - SEARCHWIDTH;
},
// 点击默认显示的输入框
handleSearchFocus() {
this.toolEl = this.$refs.outFocusRef;
this.updateFixedElementPosition();
this.isFocus = true;
this.$nextTick(() => {
this.$refs.searchInputRef.focus();
this.$refs.searchInputRef.click();
});
},
// enter键 选择事件回调
handleEnter() {
if (!this.filterKey) {
this.$refs.searchRef.clearData();
}
if (this.filterKey !== '') {
this.saveSearchHistory(this.filterKey);
this.$refs.searchRef.handleSearch();
}
},
handleClickOutSide(e) {
const result = parentClsContains('search-result-content', e.target);
if (!result) {
this.isFocus = false;
}
},
// 聚焦事件
handleFocus() {
this.loadSearchHistory();
this.isFocus = true;
},
handleSearchClose() {
this.isFocus = false;
},
handleChange(text) {
this.filterKey = text;
},
// 清空搜索框
clearInputValue() {
this.filterKey = '';
this.$refs.searchRef.clearData();
},
// 加载搜索历史
loadSearchHistory() {
const history = localStorage.getItem('searchHistory');
if (history) {
this.searchHistory = JSON.parse(history);
}
},
// 存储搜索历史
saveSearchHistory(query) {
this.searchHistory = [query, ...this.searchHistory.filter(item => item !== query)];
localStorage.setItem('searchHistory', JSON.stringify(this.searchHistory));
},
},
};
</script>

<style lang="scss" scoped>
@mixin search-input-styles {
cursor: text;
height: 32px;
padding: 0 48px 0 14px;
line-height: 30px;
background: none;
float: left;
color: #d3d9e4;
border: none;
z-index: 1;
border-radius: 2px;
}
.global-search-modal {
.global-search-focus {
position: fixed;
top: 9px;
right: 0;
z-index: 999;
}
.out-focus-tool {
@include search-input-styles;
display: flex;
align-items: center;
position: relative;
width: 240px;
background: #303d55;
font-size: 12px;
.icon-search {
position: absolute;
right: 12px;
top: 9px;
font-size: 14px;
color: #979ba5;
cursor: pointer;
}
}
.header-search-result,
.search-result-content {
width: 720px;
height: 440px;
margin-top: 5px;
background: #ffffff;
border: 1px solid #dcdee5;
box-shadow: 0 2px 6px 0 #0000001a;
border-radius: 2px;
transition: all 0.1s;
overflow-y: auto;
.search-result-panel {
box-shadow: 0px 1px 5px #e5e5e5;
border: 1px solid #eee;
border-radius: 2px;
}
h3 {
padding: 10px 15px;
}
.paas-search-trigger {
position: relative;
top: 5px;
width: calc(100% - 10px);
margin: 0 auto;
line-height: 24px;
border-radius: 2px;
background: #f0f1f5;
font-size: 12px;
color: #979ba5;
text-align: center;
cursor: pointer;
&:hover {
color: #3a84ff;
}
}
}
.search-result-content {
position: absolute;
top: 35px;
left: 0;
z-index: 999;
}
}
.ps-search {
background: #303d55;
overflow: hidden;
border-radius: 2px;
position: relative;
width: 720px;
&.focus {
input[type='text'] {
outline: none;
width: 720px;
background: #303d55;
}
}
input[type='text'] {
@include search-input-styles;
width: 720px;
&:focus {
outline: none;
background: #303d55;
}
&::-webkit-input-placeholder {
color: #d3d9e4;
}
}
.clear-icon,
.icon-search {
cursor: pointer;
position: absolute;
top: 9px;
}
i.clear-icon {
right: 30px;
font-size: 14px;
&:hover {
color: #979ba5;
}
}
i.icon-search {
right: 12px;
&:hover {
color: #3a84ff;
}
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ export default {
// 概览
toAppSummary(appItem) {
this.$router.push({
name: 'appSummary',
name: appItem.type === 'cloud_native' ? 'cloudAppSummary' : 'appSummary',
params: {
id: appItem.code,
moduleId: appItem.modules.find(item => item.is_default).name,
Expand All @@ -292,7 +292,7 @@ export default {
toAppDetail(appItem) {
this.$emit('close-search-mode');
this.clearData();
if (appItem.config_info.engine_enabled) {
if (appItem.type === 'engineless_app' || appItem.config_info.engine_enabled) {
this.toAppSummary(appItem);
return;
}
Expand Down
Loading

0 comments on commit 9176387

Please sign in to comment.