当前位置: 首页 > wzjs >正文

宁波网站建设主页苏州seo推广公司

宁波网站建设主页,苏州seo推广公司,新世纪建设集团网站,高端医院网站建设实现 1.实现2.inline-table和table-cell实现2.1 表格布局的特性2.2 示例 3.clear清除事件未生效3.1 原因3.2 解决 4. 增加type为text和textarea4.1 rows,autosize的实现 5.拓展-composition事件 1.实现 <template><div class"my-input":class"{is-dis…

实现

  • 1.实现
  • 2.inline-table和table-cell实现
    • 2.1 表格布局的特性
    • 2.2 示例
  • 3.clear清除事件未生效
    • 3.1 原因
    • 3.2 解决
  • 4. 增加type为text和textarea
    • 4.1 rows,autosize的实现
  • 5.拓展-composition事件

1.实现

<template><div class="my-input":class="{'is-disabled': disabled,'is-focus': focused,'my-input--suffix': showSuffix,'my-input--prefix': showPrefix,'my-input-group': $slots.prepend || $slots.append,'my-input-group--prepend': $slots.prepend,'my-input-group--append': $slots.append}"><!-- 前置元素 --><span class="my-input-group__prepend" v-if="$slots.prepend"><slot name="prepend"></slot></span><!-- 前缀图标--><span class="my-input__prefix" v-if="showPrefix"><i :class="prefixIcon" v-if="prefixIcon"></i><slot name="prefix"></slot></span><!-- 输入框 --><inputref="input"class="my-input__inner":type="type":placeholder="placeholder":disabled="disabled":readonly="readonly":value="value"@input="handleInput"@focus="handleFocus"@blur="handleBlur"@change="handleChange"><!-- 后缀图标,包括清空按钮 --><span class="my-input__suffix" v-if="showSuffix"><span class="my-input__suffix-inner"><iclass="my-input__clear my-icon-circle-close"v-if="clearable && value && !disabled && !readonly"@click="clear"></i><i :class="suffixIcon" v-if="suffixIcon"></i><slot name="suffix"></slot></span></span><!-- 后置元素 --><span class="my-input-group__append" v-if="$slots.append"><slot name="append"></slot></span></div>
</template><script>
export default {name: 'MyInput',props: {// v-model 绑定值value: {type: [String, Number],default: ''},// 输入框类型type: {type: String,default: 'text'},// 占位文本placeholder: String,// 是否禁用disabled: Boolean,// 是否只读readonly: Boolean,// 是否可清空clearable: Boolean,// 前缀图标prefixIcon: String,// 后缀图标suffixIcon: String},data() {return {focused: false,// 用于存储内部值,支持可控和非可控模式currentValue: this.value};},computed: {// 是否显示前缀showPrefix() {return this.prefixIcon || this.$slots.prefix;},// 是否显示后缀showSuffix() {return this.suffixIcon || this.clearable || this.$slots.suffix;}},watch: {value(val) {this.currentValue = val;}},methods: {/*** 处理输入事件*/handleInput(event) {const value = event.target.value;this.$emit('input', value);this.currentValue = value;},/*** 处理聚焦事件*/handleFocus(event) {this.focused = true;this.$emit('focus', event);},/*** 处理失焦事件*/handleBlur(event) {this.focused = false;this.$emit('blur', event);},/*** 处理变更事件*/handleChange(event) {this.$emit('change', event.target.value);},/*** 清空输入框*/clear() {this.$emit('input', '');this.$emit('change', '');this.$emit('clear');this.currentValue = '';},/*** 聚焦输入框*/focus() {this.$refs.input.focus();},/*** 失焦输入框*/blur() {this.$refs.input.blur();}}
};
</script>

2.inline-table和table-cell实现

使用prefix和suffix插槽会有问题:
在这里插入图片描述
能看到在定宽的组件中重叠错位了。
Element UI的input组件中使用的display:inline-table和display:table-cell布局技术确实很巧妙。这种布局方式允许父元素有一个固定宽度,而子元素却可以根据内容自适应并且可以超出父元素的宽度限制。

2.1 表格布局的特性

CSS表格布局有一个独特的特性:表格单元格(table cells)会根据其内容自动调整大小,并且可以超出表格本身的设定宽度。这与普通的块级元素完全不同,块级元素默认会受到父元素宽度的限制。
display: inline-table:使元素像内联元素一样在行内显示,但内部使用表格布局规则
display: table-cell:使元素表现为表格单元格

为什么可以超出父元素宽度?
表格布局有一个特殊的宽度计算算法:
先考虑内容的实际宽度
然后根据可用空间和其他单元格调整。

2.2 示例

关键点是:表格单元格会优先满足内容需求,即使这意味着需要超出表格的指定宽度

<style>
.input-wrapper {/* 普通块级元素布局 */width: 300px;border: 1px solid #ccc;
}.table-input-wrapper {/* 表格布局 */display: inline-table;width: 300px;border: 1px solid #ccc;
}.addon {display: table-cell;background: #f5f7fa;padding: 0 10px;white-space: nowrap;
}.input {display: table-cell;width: 100%;border: none;padding: 8px;
}
</style><!-- 普通布局 - 会被截断或换行 -->
<div class="input-wrapper"><span>这是一个非常长的前置文本内容可能会超出父容器</span><input type="text" placeholder="输入内容">
</div><!-- 表格布局 - 会完整显示 -->
<div class="table-input-wrapper"><span class="addon">这是一个非常长的前置文本内容可能会超出父容器</span><input class="input" type="text" placeholder="输入内容">
</div>

结果:
在这里插入图片描述

3.clear清除事件未生效

在这里插入图片描述在这里插入图片描述

点击清除,clear没执行。

3.1 原因

点击清空按钮时,事件顺序如下:
mousedown 事件首先触发
由于清空按钮在输入框内部,输入框会失去焦点(blur)
输入框触发 blur 事件
如果值有变化,输入框还会触发 change 事件
然后才是清空按钮的 click 事件,此时才执行 clear 方法
问题在于:change事件在clear方法之前触发了,而且由于输入框已经失去焦点,您的清空操作可能不会生效。

3.2 解决

事件处加上 @mousedown.prevent,

1.阻止了mousedown的默认行为
2.阻止了输入框失去焦点
3.因此不会触发blur和change事件
4.让清空按钮的click事件和clear方法能够正常执行

4. 增加type为text和textarea

4.1 rows,autosize的实现

直接将input标签换成一个textarea标签是可以进行双向绑定的。但是还是差了点味。
思路(学习借鉴的elementui源码):创建一个隐藏的 textarea,放到 body 标签下,将 Textarea 组件的 value 值赋值给隐藏的 textarea,通过获取这个隐藏的 textarea 的 scrollHeight(scrollHeight 会返回该元素在不使用滚动条时的高度),来设置组件上面的 textarea 的高度。主要通过calcTextareaHeight 方法用于计算 textarea 的动态高度。

/*** 用于动态计算文本域(textarea)高度的模块* 通过创建隐藏的textarea元素复制样式和内容,计算理想高度*/// 全局隐藏textarea引用,避免重复创建
let hiddenTextarea/*** 应用于隐藏textarea的CSS样式* 确保元素完全不可见且不影响页面布局*/
const HIDDEN_STYLE = `height:0 !important;visibility:hidden !important;overflow:hidden !important;position:absolute !important;z-index:-1000 !important;top:0 !important;right:0 !important
`/*** 需要从目标textarea复制的CSS属性列表* 这些属性会影响文本渲染和尺寸计算*/
const CONTEXT_STYLE = ['letter-spacing', // 字符间距'line-height', // 行高'padding-top', // 上内边距'padding-bottom', // 下内边距'font-family', // 字体族'font-weight', // 字体粗细'font-size', // 字体大小'text-rendering', // 文本渲染方式'text-transform', // 文本转换'width', // 宽度'text-indent', // 文本缩进'padding-left', // 左内边距'padding-right', // 右内边距'border-width', // 边框宽度'box-sizing', // 盒模型类型
]/*** 计算目标元素的样式参数* @param {HTMLElement} targetElement - 目标textarea元素* @returns {Object} 包含上下文样式和关键尺寸参数的对象*/
function calculateNodeStyling(targetElement) {// 获取目标元素的计算样式const style = window.getComputedStyle(targetElement)// 获取盒模型类型(border-box或content-box)const boxSizing = style.getPropertyValue('box-sizing')// 计算上下padding总和const paddingSize =parseFloat(style.getPropertyValue('padding-bottom')) +parseFloat(style.getPropertyValue('padding-top'))// 计算上下border总和const borderSize =parseFloat(style.getPropertyValue('border-bottom-width')) +parseFloat(style.getPropertyValue('border-top-width'))// 构建CSS样式字符串,包含所有CONTEXT_STYLE中定义的属性const contextStyle = CONTEXT_STYLE.map(name => `${name}:${style.getPropertyValue(name)}`).join(';')console.log({ contextStyle, paddingSize, borderSize, boxSizing })return { contextStyle, paddingSize, borderSize, boxSizing }
}/*** 计算textarea的理想高度* @param {HTMLElement} targetElement - 目标textarea元素* @param {number} minRows - 最小行数,默认为1* @param {number|null} maxRows - 最大行数,默认为null(无限制)* @returns {Object} 包含计算得到的高度信息,格式为{height: 'XXpx', minHeight: 'XXpx'}*/
export default function calcTextareaHeight(targetElement, minRows = 1, maxRows = null) {// 创建隐藏文本域(如果尚未创建)if (!hiddenTextarea) {hiddenTextarea = document.createElement('textarea')document.body.appendChild(hiddenTextarea)}// 从目标元素获取样式参数let { paddingSize, borderSize, boxSizing, contextStyle } = calculateNodeStyling(targetElement)// 设置隐藏文本域的样式,确保渲染特性与目标元素一致hiddenTextarea.setAttribute('style', `${contextStyle};${HIDDEN_STYLE}`)// 复制目标元素的内容或占位符到隐藏文本域hiddenTextarea.value = targetElement.value || targetElement.placeholder || ''// 获取隐藏文本域的内容滚动高度let height = hiddenTextarea.scrollHeightconst result = {}// 根据盒模型调整高度计算if (boxSizing === 'border-box') {// border-box模型:滚动高度不包含border,需要加上height = height + borderSize} else if (boxSizing === 'content-box') {// content-box模型:滚动高度包含padding,需要减去height = height - paddingSize}// 计算单行高度(用于行数限制计算)hiddenTextarea.value = '' // 清空内容let singleRowHeight = hiddenTextarea.scrollHeight - paddingSize // 空文本域的高度减去padding// 应用最小行数限制if (minRows !== null) {let minHeight = singleRowHeight * minRows // 计算最小高度if (boxSizing === 'border-box') {// border-box模型下需加上padding和borderminHeight = minHeight + paddingSize + borderSize}// 取计算高度和最小高度的较大值height = Math.max(minHeight, height)result.minHeight = `${minHeight}px`}// 应用最大行数限制if (maxRows !== null) {let maxHeight = singleRowHeight * maxRows // 计算最大高度if (boxSizing === 'border-box') {// border-box模型下需加上padding和bordermaxHeight = maxHeight + paddingSize + borderSize}// 取计算高度和最大高度的较小值height = Math.min(maxHeight, height)}// 设置最终计算结果result.height = `${height}px`// 清理:移除隐藏文本域以释放资源hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea)hiddenTextarea = nullreturn result
}

实现效果:
在这里插入图片描述

5.拓展-composition事件

现在的input搭配输入法有个问题还
在这里插入图片描述

我输入一个“啊”字,事件分发出去了两次。

composition相关事件是HTML
DOM的标准事件,专门用于处理输入法编辑器(IME)输入过程。在使用中文、日文、韩文等需要组合多个按键输入的语言时特别重要。
这三个事件的作用是: compositionstart: 当用户开始使用输入法输入时触发 代码中将isComposing标记为true
防止在组合输入过程中触发正常的input事件处理 compositionupdate: 当输入法正在组合字符时触发
代码中检查最后输入的字符是否是韩文(isKorean函数) 根据检测结果更新isComposing标志 compositionend:
当输入法完成组合输入,确认文字时触发 代码中重置isComposing为false 然后手动触发handleInput事件
这种设计解决了一个重要问题:避免在使用输入法时,未完成的组合文字过早触发input事件导致的问题。

完善后,结果:
在这里插入图片描述


文章转载自:

http://EnC9m6Zc.fgqbx.cn
http://kogoS3QB.fgqbx.cn
http://7hOikiLU.fgqbx.cn
http://UWdVwfSK.fgqbx.cn
http://MgcbamwB.fgqbx.cn
http://mLWIgyeb.fgqbx.cn
http://MsKLkA6s.fgqbx.cn
http://r05NVyOY.fgqbx.cn
http://P15qsHdm.fgqbx.cn
http://Sr2yrsMX.fgqbx.cn
http://FDUPPFvk.fgqbx.cn
http://rKEuThIh.fgqbx.cn
http://XJ92jExM.fgqbx.cn
http://TC1megEi.fgqbx.cn
http://dRTHKkim.fgqbx.cn
http://a1m5CNL0.fgqbx.cn
http://p94dL9Ks.fgqbx.cn
http://BaRCMrZP.fgqbx.cn
http://isWFzS8b.fgqbx.cn
http://6wtDxR37.fgqbx.cn
http://G8E9qYVt.fgqbx.cn
http://UAx1CFdR.fgqbx.cn
http://ztr9dIWi.fgqbx.cn
http://WyY6nNpA.fgqbx.cn
http://WEch3TFM.fgqbx.cn
http://rfxG2hnm.fgqbx.cn
http://Lak0HKED.fgqbx.cn
http://b7kXXrSy.fgqbx.cn
http://jK0C5eGg.fgqbx.cn
http://KfOAdR2e.fgqbx.cn
http://www.dtcms.com/wzjs/778382.html

相关文章:

  • 虚拟主机可以建设什么网站做高端网站
  • 校园社交网站开发的目的与意义惠州app开发公司
  • 优秀网站设计案例分析ppt怎么开一家网站开发公司
  • 网站建设报告心得体会企业文化培训心得体会
  • 深圳福田专业网站建设站长工具友链检测
  • 图片上传不了网站网站显示乱码怎么办
  • 中国建设银行官网站企业网银下载做思维导图的在线网站
  • 网站自动更新时间代码如何找网站
  • 怎样把网站建设在国外在线制作公司网站
  • dhl做运单的网站云南省保山建设网站
  • 南京网站制作招聘网企业做网站有用吗
  • 做网站应该会什么问题邵阳相亲网站
  • 网站建设费属于宣传费吗优惠网站如何做
  • jw网站设计做电影网站要买什么
  • 做美图 网站有哪些上海装修公司电话
  • 用flash做的ppt模板下载网站手机版网页设计
  • 湛江网站排名提升wordpress 七牛上传插件
  • 北京网站建设排行榜网站制作商城
  • 网站页面设计技术参数wordpress 单页案例
  • 网站换域名 百度收录阿里云如何查看已建设好的网站
  • 外贸网站域名被封怎么投诉网络平台
  • 网站的首页文案长春建站服务
  • 蓬莱网站建设价格网络服务有点问题
  • 成品网站源码78w78使用方法新网站先做外链还是内容
  • 软件园专业做网站手机上如何上传wordpress
  • 广州正规网站建设公司免费外链代发
  • 如何做视频网站流程图清博舆情监测系统
  • 通过模版做网站免费微信小程序开发官网
  • 简述电子商务网站开发的研究意义精美网页模板
  • 景点网站应该怎么做网站建设课程有哪些收获