点击li显示隐藏div层

第一种方法
$(document).ready(function(e) {
$(“li的id或class”).click(function(e) {
$(“div层的id或class”).toggle();
});
});

第二种方法
$(document).ready(function(e) {
$(".li的id或class").click(function(e) {
if( $(div层的id或class").hasClass(“show”) ){
// 执行隐藏
$(“div层的id或class”).hide().removeClass(“show”);
// 其他
}else{
// 显示
$(“div层的id或class”).show().addClass(“show”);
}
});
});

注意:不能将div层放在li的内部

<think>我们创建一个自定义组件,该组件包含一个输入框,当点击输入框时,显示一个div(例如下拉菜单或弹出)。同时,我们还要实现点击组件外部关闭该div的功能。 组件名:CustomInputWithDiv 实现步骤: 1. 使用Vue3的Composition API(setup语法糖) 2. 创建状态showDiv来控制div显示隐藏 3. 在输入框上绑定点击事件,点击时将showDiv设为true 4. 使用Teleport或者绝对定位来避免父组件的overflow:hidden影响弹出 5. 添加点击外部关闭的功能(使用document事件监听) 注意:为了避免事件冒泡导致的问题,我们在输入框的点击事件上使用stop修饰符。 代码实现:</think>### Vue3 自定义组件:点击输入框显示 div 在 Vue3 中创建自定义组件实现点击输入框显示 div 的功能,需要封装组件状态、事件处理和样式。以下是完整实现: ```vue <!-- CustomInput.vue --> <template> <div class="custom-input-container"> <!-- 输入框部分 --> <input ref="inputRef" v-model="inputValue" type="text" class="custom-input" :placeholder="placeholder" @focus="showContent" @blur="handleBlur" /> <!-- 显示的内容区域 --> <div v-show="isContentVisible" ref="contentRef" class="content-box" :style="contentStyle" > <slot name="content"> <div v-if="!$slots.content" class="default-content"> {{ defaultContent }} <button @click="closeContent">关闭</button> </div> </slot> </div> </div> </template> <script setup> import { ref, computed, onMounted, onUnmounted } from 'vue'; const props = defineProps({ placeholder: { type: String, default: '点击输入...' }, defaultContent: { type: String, default: '这是默认显示内容' }, position: { type: String, default: 'below', // 'below' 或 'above' validator: (value) => ['below', 'above'].includes(value) }, closeOnClickOutside: { type: Boolean, default: true } }); const emit = defineEmits(['open', 'close', 'update:modelValue']); const inputValue = ref(''); const isContentVisible = ref(false); const inputRef = ref(null); const contentRef = ref(null); // 计算内容区域的位置样式 const contentStyle = computed(() => { if (!inputRef.value || !isContentVisible.value) return {}; const inputRect = inputRef.value.getBoundingClientRect(); return props.position === 'above' ? { bottom: `${window.innerHeight - inputRect.top + 5}px` } : { top: `${inputRect.bottom + window.scrollY + 5}px`, left: `${inputRect.left}px` }; }); // 显示内容区域 const showContent = () => { isContentVisible.value = true; emit('open'); }; // 关闭内容区域 const closeContent = () => { isContentVisible.value = false; emit('close'); }; // 处理点击外部关闭 const handleClickOutside = (event) => { if (!props.closeOnClickOutside) return; const isClickInside = inputRef.value.contains(event.target) || (contentRef.value && contentRef.value.contains(event.target)); if (!isClickInside) { closeContent(); } }; // 处理 blur 事件(延迟关闭避免按钮无法点击) const handleBlur = () => { setTimeout(() => { if (!document.activeElement || (contentRef.value && !contentRef.value.contains(document.activeElement))) { closeContent(); } }, 100); }; // 添加全局点击监听 onMounted(() => { document.addEventListener('click', handleClickOutside); }); // 清理事件监听 onUnmounted(() => { document.removeEventListener('click', handleClickOutside); }); </script> <style scoped> .custom-input-container { position: relative; display: inline-block; width: 100%; } .custom-input { width: 100%; padding: 8px 12px; border: 1px solid #dcdfe6; border-radius: 4px; font-size: 14px; transition: border-color 0.2s; } .custom-input:focus { outline: none; border-color: #409eff; box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2); } .content-box { position: absolute; width: 100%; min-height: 100px; padding: 15px; background: white; border: 1px solid #ebeef5; border-radius: 4px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); z-index: 2000; box-sizing: border-box; } .default-content { padding: 10px; text-align: center; } button { margin-top: 10px; padding: 5px 10px; background: #f56c6c; color: white; border: none; border-radius: 3px; cursor: pointer; } button:hover { background: #e05e5e; } </style> ``` ### 使用示例 ```vue <template> <div class="container"> <h2>自定义输入框组件示例</h2> <!-- 基本用法 --> <CustomInput placeholder="点击显示默认内容" /> <!-- 自定义内容 --> <CustomInput placeholder="点击显示自定义内容" default-content="这是通过 prop 传入的内容" > <template #content> <div class="custom-content"> <h3>自定义内容区域</h3> <p>这里可以放置任何自定义内容:</p> <ul> <li>选项 1</li> <li>选项 2</li> <li>选项 3</li> </ul> </div> </template> </CustomInput> <!-- 上方显示 --> <CustomInput placeholder="内容在上方显示" position="above" /> <!-- 禁用点击外部关闭 --> <CustomInput placeholder="需手动关闭" :close-on-click-outside="false" /> </div> </template> <script setup> import CustomInput from './CustomInput.vue'; </script> <style> .container { max-width: 500px; margin: 0 auto; padding: 20px; } .custom-content { padding: 15px; } .custom-content ul { padding-left: 20px; } </style> ``` ### 实现原理详解 1. **组件封装结构**: - 使用 `defineProps` 定义可配置属性:`placeholder`、`defaultContent`、`position` 等 - 通过 `defineEmits` 声明事件:`open`、`close` 等 - 使用插槽 (`slot`) 支持内容自定义 2. **显示/隐藏控制**: - 使用 `ref` 创建响应式状态 `isContentVisible` 控制显示 - 通过 `@focus` 事件触发显示 - 通过 `@blur` 和外部点击检测触发隐藏 3. **智能定位**: - 使用 `getBoundingClientRect()` 获取输入框位置 - 根据 `position` prop 动态计算内容区域位置 - 添加 `scrollY` 补偿确保滚动时位置正确 4. **点击外部关闭**: - 通过 `document.addEventListener` 添加全局点击监听 - 使用 `contains()` 方法检测点击目标 - 通过 `closeOnClickOutside` prop 控制是否启用此功能 5. **边缘情况处理**: - 使用 `setTimeout` 延迟处理 blur 事件,避免按钮无法点击 - 添加 `z-index` 确保内容显示在最上 - 使用 `box-sizing: border-box` 确保尺寸计算准确 ### 组件功能亮点 1. **高度可定制**: - 支持通过插槽自定义内容 - 可配置显示位置(上方/下方) - 可控制是否点击外部关闭 2. **完善的用户体验**: - 输入框聚焦样式反馈 - 平滑的显示/隐藏过渡 - 精准的内容区域定位 3. **健壮的事件处理**: - 正确处理焦点切换 - 避免事件冲突 - 组件卸载时清理事件监听
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值