WbsPool
WbsPool
  • 发布:2020-05-19 10:46
  • 更新:2020-09-09 11:58
  • 阅读:2491

【报Bug】在IOS下,textarea的字数限制maxlength属性有问题,某些情况下不能准确限制字数

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: window10

HBuilderX类型: Alpha

HBuilderX版本号: 2.7.4

手机系统: iOS

手机系统版本号: iOS 13.4

手机厂商: 苹果

手机机型: iphonexr

页面类型: vue

打包方式: 云端

项目创建方式: HBuilderX

示例代码:

<template>  
    <view>  
        <textarea :value="content" maxlength="2000"  @input="handleContentChange" placeholder="请在这里输入内容">

操作步骤:

见演示视频

预期结果:

见演示视频

实际结果:

见演示视频

bug描述:

textarea的字数限制maxlength属性有问题,比如我限制2000个字符,在复制长文本的时候,有时文本长度还不够2000就输入不了了。

可以使用下面这段文字测试:

【管理咨询正式实习内推】
【职位名称】埃森哲咨询实习生
【地点】北京
【主要工作内容】

  1. 协助完成多行业的管理和咨询、规划、可研及相应的咨询分析工作,协助项目经理收集整理项目资料,在项目经理指导下编写管理改善方案;
  2. 协助编写交付物 (如Proposal、Report、培训材料等),外部信息调研,并根据要求撰写PPT版本的调研报告;
  3. 在项目经理的指导下完成访谈提纲撰写、参与项目访谈,并完成访谈信息整理工作;列席客户沟通会议,撰写会议纪要;
  4. 搜索资料、分析数据并独立分析和研究问题,独立负责项目中的某块交付成果,主动与客户沟通,主动与项目组成员和项目负责人汇报,确保成果质量和客户满意度;
  5. 主动思考所承接的工作任务,在提出问题的同时明确解决思路,给出推荐方案并说明理由;
    【申请要求】
    1.拥有较好的逻辑分析和沟通理解能力,责任心强,踏实靠谱
    2.学历要求本科,研究生最佳
    3.熟练操作office软件,特别是PowerPoint、Excel
    4.英文水平较好
    5.能够尽快入职最佳

【管理咨询正式实习内推】
【职位名称】埃森哲咨询实习生
【地点】北京
【主要工作内容】

  1. 协助完成多行业的管理和咨询、规划、可研及相应的咨询分析工作,协助项目经理收集整理项目资料,在项目经理指导下编写管理改善方案;
  2. 协助编写交付物 (如Proposal、Report、培训材料等),外部信息调研,并根据要求撰写PPT版本的调研报告;
  3. 在项目经理的指导下完成访谈提纲撰写、参与项目访谈,并完成访谈信息整理工作;列席客户沟通会议,撰写会议纪要;
  4. 搜索资料、分析数据并独立分析和研究问题,独立负责项目中的某块交付成果,主动与客户沟通,主动与项目组成员和项目负责人汇报,确保成果质量和客户满意度;
  5. 主动思考所承接的工作任务,在提出问题的同时明确解决思路,给出推荐方案并说明理由;
    【申请要求】
    1.拥有较好的逻辑分析和沟通理解能力,责任心强,踏实靠谱
    2.学历要求本科,研究生最佳
    3.熟练操作office软件,特别是PowerPoint、Excel
    4.英文水平较好
    5.能够尽快入职最佳
    时间段可以进行预约号码是你的朋友可以加我们微信咨询微信公众号里有需要的朋友可以联系我
2020-05-19 10:46 负责人:DCloud_UNI_GSQ 分享
已邀请:
你的城主大人

你的城主大人

我采用的方式是计算的时候就当做两位计算,不过在粘贴的时候空格会被多粘贴出来几个字符出现201/200的情况,所以用一下代码对textarea的粘贴行为进行了覆盖,如果有更好的方式,还请发在下面,共同进步

        mui("body").on("paste" , "textarea", function(e){  
            var val = this.value;  
            var selectionStart = this.selectionStart;  
            var selectionEnd = this.selectionEnd;  
            // 删除选中部分  
            if(selectionStart != selectionEnd){  
                val = val.substr(0, selectionStart) + val.substr(selectionEnd);  
            }  
            // 处理粘贴内容  
            var clipboard = (e.clipboardData || window.clipboardData);  
            var oldText = clipboard.getData('text');  
            var textMaxLen = this.maxLength - val.length;  
            var tempText = oldText.replace(/(?<!\r)\n/g,"\r\n");  
            tempText = tempText.substr(0, textMaxLen);  
            tempText = tempText.replace(/\r\n/g, "\n");  
            val = val.substr(0, selectionStart) + tempText + val.substr(selectionStart);  
            this.value = val;  
            // 恢复光标位置  
            this.setSelectionRange(selectionStart, selectionStart);  

            e.preventDefault();  
        });
你的城主大人

你的城主大人

貌似粘贴方法只支持ctrl+v在移动端无效,哎,感觉需要用input事件改善一下

你的城主大人

你的城主大人

这样写貌似能保持安卓向苹果靠齐,
仅ios执行的话可以保证粘贴的时候内容中有空格不会超位,
如果安卓也执行感觉能和苹果一样,输入粘贴的时候不会超过苹果能输入的上限,如果在差一位满位的情况下,允许输入一个回车。
虽然两端一致了,但是总感觉有些怪异,不过一般应该没啥,最起码不会字数计算错误

var updateSum = function (obj, numID){  
    var temp = obj.value;  
    var maxlength = $(obj).attr("maxlength");  
    var length;  
    // if(plus.os.name == "iOS"){  
        length = temp.replace(/\n/g,"11").length;  
        if(length > maxlength){  
            console.log(1);  
            var selectionStart = obj.selectionStart;  
            var delCount = length - maxlength;  
            var _delCount = 0;  
            while(delCount > 0){  
                var chr = temp[selectionStart - _delCount - 1];  
                if(chr == "\n"){  
                    delCount -= 2;  
                }else{  
                    delCount -= 1;  
                }  
                _delCount++;  
            }  
            if(delCount == -1){  
                _delCount--;  
            }  
            var delAfter = selectionStart - _delCount;  
            obj.value = temp.substr(0, delAfter) + temp.substr(selectionStart);  
            obj.setSelectionRange(delAfter, delAfter);  
            length = maxlength;  
        }  
    // }else{  
    //  length = temp.length;  
    // }  

    $("#"+numID).text(length + "/" + maxlength);  
}
  • 你的城主大人

    有需求的可以用着试试,之前那个解决方案移动端不能用,如果出了什么漏掉的分支,不会改提出来,看能不能解决,如果会改,就拜托大神改完了再补发一个。

    2020-09-04 18:56

DCloud_UNI_GSQ

DCloud_UNI_GSQ

实际测试确实存在此问题

在iOS(或者Mac Safari)的App、H5端测试均可以复现。

不使用uni-app框架直接使用html进行测试仍然可以复现。

确认到:当存在换行时,Safari浏览器(WebView)内核对文字的计数出现不一致的行为,曾经Chrome内核也有类似问题,后被修复。

结论:Safari 浏览器(WebView)的Bug或者特性,框架暂时不整体进行特殊处理或者绕过(以避免导致的其他不确定行为),可在用户层自行绕过(maxlength设置为-1,并检测长度)。

相关资料:

  • https://bugs.webkit.org/show_bug.cgi?id=74686
  • https://bugs.chromium.org/p/chromium/issues/detail?id=252613
1***@qq.com

1***@qq.com

66666

你的城主大人

你的城主大人

解决中文输入法下的可以无限输入的问题,两个项目,这是apicloud那边的代码,如果需要可以自己修改下写法

$global.fireEvent = function(el, evtName){  
    if(typeof el == "string"){  
        el = $api.dom(el);  
    }  
    el.dispatchEvent(new Event(evtName));  
}  

$global.addUpdateSum = function(el, numID){  
    if(typeof el == "string"){  
        el = $api.dom(el);  
    }  
    var isInputEnd = true;  
    $api.addEvt(el, 'compositionstart', function(){  
        isInputEnd = false;  
    });  
    $api.addEvt(el, 'compositionend', function(){  
        isInputEnd = true;  
        $global.fireEvent(this, "input");  
    });  
    $api.addEvt(el, 'input', function(){  
        if(isInputEnd){  
            $global.updateSum(this, numID);  
        }  
    });  
}  
$global.updateSum = function (obj, numID){  
    var temp = obj.value;  
    var maxlength = obj.maxLength;  
    var length;  
    if(api.systemType == "ios"){  
        length = temp.replace(/\n/g,"11").length;  
        if(length > maxlength){  
            var selectionStart = obj.selectionStart;  
            var delCount = length - maxlength;  
            var _delCount = 0;  
            while(delCount > 0){  
                var chr = temp[selectionStart - _delCount - 1];  
                if(chr == "\n"){  
                    delCount -= 2;  
                }else{  
                    delCount -= 1;  
                }  
                _delCount++;  
            }  
            if(delCount == -1){  
                _delCount--;  
            }  
            var delAfter = selectionStart - _delCount;  
            obj.value = temp.substr(0, delAfter) + temp.substr(selectionStart);  
            obj.setSelectionRange(delAfter, delAfter);  
            length = maxlength;  
        }  
    }else{  
        length = temp.length;  
    }  
    var numEL = $api.byId(numID);  
    $api.text(numEL, length + "/" + maxlength);  
}

该问题目前已经被锁定, 无法添加新回复