ios input框只能输入一次的问题

本文介绍了一个在苹果手机上解决软键盘遮挡输入框的问题,通过使用setTimeout结合window.scrollTo方法,在input框失去焦点后延迟滚动页面,确保软键盘关闭时不会影响输入框的正常使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

苹果手机 固定定位的元素 在元素内 input 框聚焦的时候 弹出的软键盘占位 失去焦点的时候软键盘消失 但是还是占位的 导致input框不能再次输入 在失去焦点的时候给一个事件
blur() {
setTimeout(() => {
const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0
window.scrollTo(0, Math.max(scrollHeight - 1, 0))
}, 200)
}
即可解决

<think>我们正在处理一个微信小程序的需求:限制输入输入emoji图标。我们需要在输入的验证中实现这一点。 思路: 1. 微信小程序的输入可以使用`<input>`或`<textarea>`组件,我们可以通过绑定事件(如bindinput)来实时检查输入内容。 2. 在事件处理函数中,我们可以获取输入的值,然后检查是否包含emoji字符。 3. 如何检测emoji?我们可以使用正则表达式来匹配emoji字符。由于emoji的Unicode范围较广,我们可以使用一个较为通用的正则表达式来匹配大部分emoji。 4. 如果检测到emoji,我们可以选择阻止输入(例如,将输入值中的emoji字符过滤掉)或者给用户提示。 参考正则表达式: 我们可以使用如下正则表达式来匹配emoji: /[\uD83C-\uDBFF\uDC00-\uDFFF]+/g 这个正则表达式覆盖了大部分emoji字符(位于Unicode的补充多语言平面和多语言补充平面)。 但是,更全面的emoji正则表达式可以覆盖更广的范围,例如: /[\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]/gu 但是注意,在JavaScript中,我们需要使用Unicode转义序列,并且注意JavaScript的正则表达式对Unicode的支持。 由于微信小程序运行在JavaScript环境中,我们可以使用以下正则表达式(注意使用双反斜杠): var reg = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/gi; 但是,更简单的方式是使用一个范围更广的匹配,例如: var reg = /[\uD800-\uDBFF][\uDC00-\uDFFF]|[\u2600-\u27FF]|[\u1F000-\u1F9FF]/g; 不过,由于emoji的更新,正则表达式可能无法覆盖所有,但我们可以选择一种较为通用的。 实际处理中,我们可以这样: - 在bindinput事件中,获取输入值(event.detail.value) - 使用正则表达式替换掉emoji字符,然后设置输入。 但是,直接替换会导致光标位置问题,所以我们可以使用以下方法: 1. 在data中设置一个变量(如inputValue)来绑定输入的值。 2. 在bindinput事件中,获取新值,然后过滤掉emoji,再设置inputValue。 但是这样会导致光标跳到末尾,所以我们可以使用cursor对象来记录光标位置,并在设置值后恢复光标位置(微信小程序支持设置光标位置)。 另一种做法:如果检测到有emoji,则阻止本次输入(通过返回被过滤的字符串),但注意这样会重新渲染输入,导致光标位置问题,所以需要记录光标位置并恢复。 具体步骤: 1. 在wxml中,给input或textarea组件绑定bindinput事件: <input value="{{inputValue}}" bindinput="onInput" /> 2. 在js中,定义onInput函数: onInput: function(e) { var value = e.detail.value; // 过滤emoji var newValue = this.filterEmoji(value); // 如果过滤后的值和原来的值不同,则设置新值 if (newValue !== value) { // 需要更新数据,并手动设置输入的值(因为返回新值会替换输入内容) // 同时记录光标位置 var cursor = e.detail.cursor; // 注意:input事件中,detail.cursor可能不存在,但可以自己记录光标位置 // 但是,在微信小程序中,input事件中,对于<input>组件,可以通过e.detail.cursor获取光标位置,但只有输入导致光标变化时才有,且仅在安卓上有效?所以我们需要自己记录光标位置。 // 另一种做法:使用setData设置inputValue,然后使用wx.nextTick在下一个时间点设置光标位置 // 但是,微信小程序提供了在setData中设置光标位置的方法:通过设置selection-start和selection-end,但需要给input组件设置selection-start和selection-end属性,并在setData时同时设置这两个值。 // 因此,我们可以这样做: // 首先,在data中定义光标位置对象:cursorPos: {start:0, end:0} // 然后,在每次输入时,我们记录下当前的光标位置(在过滤前,通过e.detail.cursor获取,但注意:在输入事件中,detail.cursor表示的是输入发生前的位置,而且只有部分情况有效) // 实际上,我们可以通过自己维护光标位置来解决。在每次输入事件中,我们通过setData更新inputValue,然后通过this.setData同时设置selection-start和selection-end。 // 但是,由于每次输入都会触发bindinput,我们可以在过滤后,计算光标位置(因为过滤掉的是emoji,通常是一个字符,所以光标位置应该减去过滤掉的字符数?但这样很复杂) // 因此,我们采用一个简单的方法:如果检测到有emoji,我们直接过滤掉,然后更新整个输入的值,并将光标放在最后。这样可能会导致光标总是跳到末尾,但实现简单。 // 如果要求不高,可以这样: this.setData({ inputValue: newValue }); // 如果需要精确控制光标,我们可以自己计算光标位置。这里我们假设过滤掉的是整个字符串中的emoji,所以光标位置需要减去被过滤的字符数?但这样很困难。 // 所以,我们这里采用:当发现输入了emoji时,我们给出提示,并过滤掉,但光标位置放在最后(用户体验可能不好,但简单) // 或者,我们可以在输入下方显示提示信息,但允许输入,然后在提交表单时再验证,并提示用户不允许输入emoji。 // 根据需求,我们可能需要实时过滤,所以这里我们选择实时过滤并更新值,光标放在最后。 // 注意:这样会导致每次过滤后光标都跳到最后,所以如果用户是在中间输入输入一个emoji,过滤后光标会跳到最后,体验不好。 // 因此,我们需要记录光标位置,并在过滤后恢复光标位置(减去被过滤的字符数)。 // 由于我们无法精确知道用户输入的位置,我们可以这样: // 在每次输入事件中,我们获取到输入前的值、输入后的值以及光标位置。然后我们比较输入前后的值,找出用户输入(或删除)的位置,然后进行过滤,并计算新的光标位置。 // 这比较复杂,因此我们采用另一种思路:在过滤时,我们记录下当前的光标位置(通过e.detail.cursor获取,但注意:在input事件中,对于textarea和input组件,e.detail有cursor属性,表示输入前光标的位置,但只有在输入导致光标变化时才有,且当输入内容改变时,该字段只出现在安卓设备上,iOS上可能没有。所以我们需要自己维护光标位置)。 // 因此,我们可以给input组件添加bindfocus事件,记录下当前的光标位置(通过selection-change事件?)。但这样比较复杂。 // 考虑到需求是防止输入emoji,我们可以使用一个折中的方法:在输入时过滤,但只过滤当前输入的字符(如果当前输入的字符是emoji,则忽略这个字符)。这样我们就不需要改变整个字符串,只需要判断最后一次输入是否是emoji。 // 如何判断最后一次输入?我们可以通过比较新旧字符串的长度和差异。但是,在bindinput事件中,我们可以通过e.detail.value获取新字符串,通过之前存储的旧字符串(在data中)比较,找出新增的字符。 // 具体步骤: // 1. 在data中存储上一次的值(oldValue) // 2. 在onInput中,获取新值newValue,然后与oldValue比较,找出新增的字符(可能是多个,比如粘贴) // 3. 检查新增的字符中是否包含emoji,如果有,则把新增的字符中的emoji过滤掉,然后组合成新的字符串。 // 4. 设置这个新字符串,并更新oldValue。 // 同时,我们需要记录光标位置。但是,如果我们只过滤新增的字符,那么光标位置应该是:上一次光标位置(在输入前)加上新增的非emoji字符的长度。 // 由于实现起来较为复杂,这里我们提供一个简单版本(整个字符串过滤)和一个增强版本(仅过滤新增部分)。 // 简单版本(整个字符串过滤): // 直接过滤整个字符串,然后设置,光标跳到最后。 // 增强版本(仅过滤新增部分): // 在data中存储:inputValue和oldInputValue,以及cursorPos(用于记录输入前光标位置) // 在bindinput事件中,我们获取到新值newValue,然后与oldInputValue比较,找出差异(从0开始比较,直到遇到不同的位置,然后从末尾比较,找到变化的区间?) // 实际上,我们可以认为用户是在光标位置处进行了输入(或删除),但我们不知道具体是插入还是删除,所以我们可以通过长度变化判断:如果newValue比oldInputValue长,则说明是插入,反之是删除。 // 但是,我们这里只处理插入的情况(输入新字符),如果用户输入了emoji,我们就将其过滤掉,然后组合成新的字符串。 // 具体步骤(增强版): // 1. 获取oldValue(上一次设置的值,注意:不是data中的oldInputValue,而是上一次事件处理后的值)和newValue(当前输入事件的值) // 2. 比较oldValue和newValue,找出新增的文本(假设是用户在光标位置插入的) // 3. 过滤新增文本中的emoji,得到cleanText // 4. 将oldValue中光标位置(输入前光标位置)之前的部分 + cleanText + oldValue中光标位置之后的部分,得到最终文本 // 5. 设置最终文本,并更新光标位置:原光标位置 + cleanText的长度 // 但是,如何获取输入前光标位置?在input事件中,e.detail.cursor可以获取到输入前的光标位置(在安卓上有效,iOS上可能没有)。在iOS上,我们可以通过自己记录:在bindfocus和bindblur时记录光标位置,并在每次输入事件中更新?这样比较复杂。 // 考虑到跨平台,我们可以使用微信小程序的输入组件的selection-change事件(从基础库2.7.0开始支持)来实时记录光标位置。 // 因此,我们可以这样设计: // 在wxml中: // <input value="{{inputValue}}" bindinput="onInput" bindselectionchange="onSelectionChange" /> // 在js中: // data: { // inputValue: '', // start: 0, // 当前光标开始位置 // end: 0 // 当前光标结束位置 // }, // onSelectionChange: function(e) { // this.setData({ // start: e.detail.start, // end: e.detail.end // }); // }, // onInput: function(e) { // var newValue = e.detail.value; // var oldValue = this.data.inputValue; // var start = this.data.start; // 输入前光标开始位置 // var end = this.data.end; // 输入前光标结束位置 // // 如果输入前后值没有变化,则不处理(可能不会发生) // if (newValue === oldValue) { // return; // } // // 情况1:用户输入(插入) // if (newValue.length > oldValue.length) { // // 插入文本 // // 假设用户是在光标位置插入的,那么插入的文本长度 = newValue.length - oldValue.length // // 但实际上,可能是替换选中的文本?如果有选中文本(即start!=end),那么插入的文本长度 = newValue.length - (oldValue.length - (end - start)) // // 所以,插入的文本 = newValue.substring(start, start + (newValue.length - oldValue.length + (end - start))) // // 这个计算比较复杂。 // // 另一种思路:直接比较两个字符串,从start位置开始,找到插入的文本。 // // 因为用户是在start位置插入的,所以oldValue在start位置之前和newValue相同,oldValue从start位置开始被替换成了插入的文本(长度为新增长度)和后面部分(但后面部分可能被覆盖?) // // 更简单:我们直接截取newValue中从0到start,然后加上插入的文本(我们不知道具体插入了什么,但我们可以通过oldValue和newValue的差异来获取插入的文本?) // // 实际上,我们可以通过以下方式得到插入的文本: // // 插入的文本 = newValue.substring(start, start + (newValue.length - oldValue.length + (end - start))) // // 但是这样不可靠。 // // 因此,我们采用整个字符串过滤的方式,但只过滤新增的部分(即从oldValue到newValue变化的部分)是不可行的。 // // 所以,我们回到整个字符串过滤,然后通过之前记录的光标位置,计算出新的光标位置。 // // 过滤整个字符串 // var filteredValue = this.filterEmoji(newValue); // // 计算新光标位置:因为过滤了部分字符,所以光标位置会变化。我们需要计算在过滤前光标位置(即输入后光标位置,但注意输入后光标位置应该是start + (新插入的字符数))在过滤后对应的位置。 // // 但是,由于我们不知道过滤了多少个emoji,以及它们的位置,所以很难精确计算。 // // 因此,我们采用简单方法:将光标放在最后(用户体验不好,但实现简单)。 // this.setData({ // inputValue: filteredValue // }); // } else { // // 删除操作,不需要过滤 // this.setData({ // inputValue: newValue // }); // } // } // 由于精确控制光标的复杂性,如果需求不是很严格,我们可以只过滤整个字符串,并将光标放在最后。或者,只过滤整个字符串,不处理光标(这样光标可能会错乱)。 // 因此,我们这里提供一个折中方案:在输入失去焦点时过滤,或者在提交时验证。但用户要求是实时限制。 // 我们也可以使用简单过滤,并接受光标跳到最后的问题。 // 所以,我们选择简单版本:整个字符串过滤,然后设置整个字符串,光标位置由微信小程序自己控制(会跳到最后)。同时,我们可以给用户一个提示。 // 简单版本实现: var filteredValue = value.replace(/[\uD83C-\uDBFF\uDC00-\uDFFF]/g, ''); this.setData({ inputValue: filteredValue }); // 提示 if (filteredValue !== value) { wx.showToast({ title: '不能输入表情符号', icon: 'none' }); } } else { // 没有emoji,直接设置 this.setData({ inputValue: newValue }); } } 但是,上面的简单版本在用户输入多个字符(比如粘贴)时,会过滤掉所有emoji,但光标会跳到最后。 考虑到实际需求,我们也可以采用在提交表单时验证,这样就不会影响输入体验,只是在提交时提示用户。 两种方式: 方式一:实时过滤(如上) 方式二:提交时验证 这里我们按照用户要求,实现实时限制。 因此,我们选择实时过滤并提示。 但是,我们也可以选择不实时过滤整个输入,而是只过滤当前输入的字符(如果当前输入的字符是emoji,则忽略这个字符)。这样就不会影响光标位置。 如何只过滤当前输入的字符? - 在bindinput事件中,我们可以通过e.detail.value获取新值,通过e.detail.keyCode(但keyCode在输入中文时可能无效)和e.detail.data(输入的新字符,如果是多个字符比如粘贴,则e.detail.data为整个粘贴的字符串)来获取新增的字符。 注意:在微信小程序的input事件中,e.detail有一个data属性,表示输入的内容(如果是删除,则为空)。所以我们可以这样: onInput: function(e) { var value = e.detail.value; var inputData = e.detail.data; // 本次输入的内容(如果是删除,则inputData为null或空字符串) if (inputData) { // 检查输入的内容中是否包含emoji var reg = /[\uD83C-\uDBFF\uDC00-\uDFFF]/g; if (reg.test(inputData)) { // 如果输入了emoji,则我们使用上一次的值(即过滤后的值)作为输入的值 // 注意:这里我们无法直接获取上一次的值,因为我们的输入是受控的(由inputValue控制),所以我们可以用data中存储的inputValue(但注意,data中的inputValue可能不是实时的,因为setData是异步的) // 因此,我们需要在每次输入事件后立即更新data中的inputValue,这样在下一个事件中,data.inputValue就是上一次过滤后的值。 // 但是,在本次事件中,data.inputValue还是上一次的值(即未包含本次输入的值) // 所以,我们可以这样:将输入的值设置为data.inputValue(即上一次的值),这样本次输入就被忽略。 var lastValue = this.data.inputValue; this.setData({ inputValue: lastValue }); // 提示 wx.showToast({ title: '不能输入表情符号', icon: 'none' }); return; } } // 如果没有输入emoji,则更新inputValue this.setData({ inputValue: value }); } 这种方法的好处是:只过滤当前输入的字符,不会影响整个字符串,光标位置不会变化(因为如果输入了emoji,我们直接使用上一次的值,输入内容不变,所以光标位置也不会变)。 但是,这种方法只能过滤单个字符的输入(或粘贴的多个字符中的emoji,但注意:如果粘贴的文本中包含emoji,那么整个粘贴操作都会被取消,因为inputData包含非emoji和emoji,我们检测到emoji就整个放弃粘贴)。 所以,我们需要将粘贴的文本中的emoji过滤掉,只保留非emoji字符,然后插入到光标位置。但是,这样就需要处理光标位置,因为我们只过滤了部分字符。 因此,我们采用以下策略: - 如果输入事件是输入文本(非删除),我们获取到输入的文本(inputData),然后过滤掉其中的emoji,得到cleanData。 - 然后,我们将输入的值设置为:原值(data.inputValue)在光标位置(start到end)处替换为cleanData后的字符串。 - 然后,设置新的光标位置:start + cleanData.length 具体步骤: onInput: function(e) { var value = e.detail.value; var inputData = e.detail.data; var cursor = e.detail.cursor; // 注意:这个cursor在安卓上表示输入前的位置,iOS上可能没有 var start = e.detail.cursor; // 这里我们假设e.detail.cursor是输入前光标的位置(安卓上有效) var end = e.detail.cursor; // 如果是选择了一段文本,那么end就是选区的结束位置,但这里我们暂时不考虑选区,只考虑光标位置(即start=end) // 实际上,在input事件中,e.detail有selectionStart和selectionEnd(基础库2.7.1开始支持)?但文档中没有明确。 // 由于微信小程序文档中,input事件的detail对象包含cursor(在安卓上,输入的光标位置),在iOS上没有。所以我们可以用自己记录的光标位置(通过selection-change事件)。 // 因此,我们这里使用自己记录的光标位置(通过bindselectionchange事件)。 var start = this.data.start; var end = this.data.end; if (inputData) { // 过滤输入文本中的emoji var cleanData = inputData.replace(/[\uD83C-\uDBFF\uDC00-\uDFFF]/g, ''); if (cleanData !== inputData) { // 有emoji被过滤掉 wx.showToast({ title: '不能输入表情符号', icon: 'none' }); } // 构造新的字符串:将原字符串中start到end的部分替换为cleanData var oldValue = this.data.inputValue; var newValue = oldValue.substring(0, start) + cleanData + oldValue.substring(end); // 计算新光标位置 var newCursorPos = start + cleanData.length; // 设置新值 this.setData({ inputValue: newValue, start: newCursorPos, end: newCursorPos }); // 注意:设置后,我们需要在下一个事件循环中设置输入的光标位置 // 但是,微信小程序提供了wx.nextTick,我们可以在这里设置光标位置 // 然而,微信小程序的input组件的光标位置可以通过setData设置selection-start和selection-end来实现,所以我们在setData中同时设置了start和end(绑定到selection-start和selection-end)就可以了。 // 在wxml中,我们需要将start和end绑定到selection-start和selection-end: // <input value="{{inputValue}}" selection-start="{{start}}" selection-end="{{end}}" bindinput="onInput" bindselectionchange="onSelectionChange" /> return; } // 如果没有输入数据(比如删除),或者输入数据为空,我们直接设置 this.setData({ inputValue: value }); } 但是,这种方法需要维护光标位置,并且需要绑定selection-start和selection-end,以及bindselectionchange事件。 综合以上,我们给出一个较为完整的实现: 步骤: 1. WXML: <input value="{{inputValue}}" selection-start="{{start}}" selection-end="{{end}}" bindinput="onInput" bindselectionchange="onSelectionChange" /> 2. JS: Page({ data: { inputValue: '', start: 0, // 光标开始位置 end: 0 // 光标结束位置 }, onSelectionChange: function(e) { // 记录光标位置 this.setData({ start: e.detail.start, end: e.detail.end }); }, onInput: function(e) { var value = e.detail.value; var inputData = e.detail.data; // 本次输入的内容,如果是删除则为空 var oldValue = this.data.inputValue; var start = this.data.start; var end = this.data.end; // 如果是删除操作(inputData为空),则我们直接更新inputValue if (inputData === null || inputData === undefined || inputData === '') { this.setData({ inputValue: value }); return; } // 过滤输入的内容 var cleanData = inputData.replace(/[\uD83C-\uDBFF\uDC00-\uDFFF]/g, ''); // 如果cleanData为空,说明输入的全是emoji,则不需要更新,直接返回 if (cleanData === '') { // 但是,我们需要保持输入的值不变,所以设置回oldValue // 同时,光标位置也不变(因为输入被过滤了,所以光标位置应该保持在原处) this.setData({ inputValue: oldValue }); wx.showToast({ title: '不能输入表情符号', icon: 'none' }); return; } // 如果有部分被过滤,则提示 if (cleanData.length < inputData.length) { wx.showToast({ title: '已过滤表情符号', icon: 'none' }); } // 构造新的字符串 var newValue = oldValue.substring(0, start) + cleanData + oldValue.substring(end); var newCursorPos = start + cleanData.length; this.setData({ inputValue: newValue, start: newCursorPos, end: newCursorPos }); } }); 注意:这种方法在粘贴时也能生效,因为inputData是本次输入的整个字符串(包括粘贴的多个字符),我们过滤掉其中的emoji,然后插入到光标位置。 但是,这种方法在性能上可能有问题,如果输入内容很大,每次都要截取字符串再拼接。但一般输入内容不会太长。 另外,正则表达式可能无法覆盖所有emoji,但可以覆盖大部分。 最后,我们也可以考虑使用更全面的emoji正则表达式,例如: var reg = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|[\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|[\ud83c[\ude32-\ude3a]|[\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55]|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g; 但这个正则表达式很长,我们可以根据需求选择。 我们这里选择使用一个简单的:/[\uD800-\uDBFF][\uDC00-\uDFFF]/g 可以匹配大部分四字节的emoji,但注意,有些两字节的符号(如©)不在这个范围内,所以我们可以加上\u2600-\u27BF等。 这里我们使用:/[\uD83C-\uDBFF\uDC00-\uDFFF\u2600-\u27BF]/g 但注意,这个正则表达式可能会匹配到一些非emoji的字符,所以需要测试。 考虑到时间,我们使用一个较为通用的:/[\uD83C-\uDBFF\uDC00-\uDFFF]/g 和 \u200D(零宽连接符)等,但为了简单,我们先用这个。 综上所述,我们给出一个实现方案,并注意在代码中注释。 由于emoji的复杂性,可能无法完全覆盖,但可以满足大部分需求。 最后,我们给出完整的代码示例。</think>在微信小程序中实现输入限制,防止用户输入 emoji 图标,可以通过以下两种方法实现: --- ### 方法一:通过正则表达式实时过滤(推荐) 在输入的 `bindinput` 事件中,使用正则表达式检测并过滤 emoji 字符: ```javascript Page({ data: { inputValue: '' }, // 输入内容变化时触发 onInput(e) { let value = e.detail.value; // 匹配 emoji 的正则表达式(覆盖常见 Unicode 范围) const emojiReg = /[\uD83C-\uDBFF\uDC00-\uDFFF\u2600-\u27BF\u1F000-\u1FAFF]/g; // 过滤 emoji 字符 const filteredValue = value.replace(emojiReg, ''); if (value !== filteredValue) { // 如果过滤后内容变化,更新输入值 this.setData({ inputValue: filteredValue }); // 提示用户(可选) wx.showToast({ title: '不支持输入表情符号', icon: 'none' }); } else { // 无 emoji 时正常更新 this.setData({ inputValue: value }); } } }); ``` **WXML 文件**: ```html <input value="{{inputValue}}" bindinput="onInput" placeholder="请输入文本(不支持表情)" /> ``` --- ### 方法二:表单提交时验证 在提交表单时检查内容,若包含 emoji 则阻止提交: ```javascript Page({ data: { inputValue: '' }, // 提交表单时触发 onSubmit() { const value = this.data.inputValue; const emojiReg = /[\uD83C-\uDBFF\uDC00-\uDFFF]/g; if (emojiReg.test(value)) { wx.showToast({ title: '内容包含表情符号!', icon: 'error' }); return; // 阻止提交 } // 通过验证,执行提交操作 // ... } }); ``` --- ### 关键说明 1. **正则表达式原理**: - `\uD83C-\uDBFF\uDC00-\uDFFF`:匹配 Unicode 的补充多语言平面(含大部分 emoji) - `\u2600-\u27BF`:匹配基础符号(如 ☀️⭐) - `\u1F000-\u1FAFF`:匹配扩展符号(如 🎯🏀) - 可通过 [Unicode Emoji 列表](https://unicode.org/emoji/charts/) 调整范围 2. **光标位置处理**: - 实时过滤时,若直接替换整个字符串,可能导致光标跳至末尾。可通过 `wx.nextTick` 和 `selection-start` 重置光标位置(需额外逻辑)。 3. **兼容性建议**: - 在真机上测试,部分安卓机型可能需调整正则范围 - 考虑使用第三方库(如 [emoji-regex](https://www.npmjs.com/package/emoji-regex)),通过小程序 npm 支持引入 --- ### 相关问题 1. 如何在小程序中实现输入的字数限制? 2. 微信小程序如何阻止用户输入特殊字符(如 #、@)? 3. 小程序中如何实现输入的自动格式化(如手机号分隔)? 4. 表单提交时如何实现多字段联合验证? > 提示:小程序原生组件 `input` 和 `textarea` 的详细参数可参考 [微信官方文档](https://developers.weixin.qq.com/miniprogram/dev/component/input.html)[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值