文档章节

innerText 操作 textarea 的 “坑”

zTree
 zTree
发布于 2017/03/27 18:29
字数 1003
阅读 854
收藏 0

这两天正在把 CodeMirror 融入 编辑器。。。结果发现了奇怪的现象: textarea 内正常的换行居然变成了<br>

以前从未出现过这种事情,难道是 Chrome 57(最新版)出现了 bug?

 

找了一下 FireFox 居然是这样, 再看 Chrome 49 还是这样。。。

看来不是最新版的问题,还是在自己的代码中找原因吧....

首先要了解 textarea 操作的几个特性:

  • 对于现在最新版的浏览器中  innerHTML / innerText / textContent 这几个方法都可以操作 textarea 内容
  • 对于旧版的浏览器中 FireFox 是不能使用 innerText 方法的(现在就不管这个了)
  • 一旦针对 textarea 使用了 value 方法 或 用户在 textarea 内输入内容后, innerHTML / innerText / textContent 这几个方法都不会影响 textarea 看到的值,当然也不会影响 value 的数据了

之前操作 textarea 部分的代码如下:

// 这是在保存编辑内容时,为了把 textarea 的内容正确保存时,必须要把 value 赋值给 html 内

// 为了处理 旧版 Firefox 兼容
textType = (obj.innerText === undefined ? 'textContent' : 'innerText');
if (obj.value !== obj[textType]) {
    obj[textType] = obj.value;
}

于是立刻找到问题所在:innerText

在编辑器内对于 textarea 只要使用 innerText 设置的值,'\n' 全部都会变成 '<br>'

不可思议的情况:

为什么以前从来没有发现过这个问题?? 为了谨慎着手,制作一个干干净净的 html 页面,只有一个 textarea,使用 innerText 设置数据,居然全都正常了。。OMG,难道是 CodeMirror 的 bug??赶紧打开 CodeMirror 提供的 Demo,直接操作对应的 textarea 全都出现 <br>!!看看源码吧, CodeMirror 内没有什么 innerText 相关的代码。。。太奇怪了吧??沉思中。。。

剧情反转:

最后只有终极法宝了,把出现问题的页面删除 script、删除 style,删除多余的,只留下 textarea,问题依然存在,然后创建一个新的 textarea,innerText 操作正常。这时恍然大悟,两个 textarea 唯一的区别就是 'display:none'

<textarea id="t01" style="display:none"></textarea>
<textarea id="t02" style="visibility:hidden"></textarea>
<textarea id="t03" ></textarea>

针对这 3 个 textarea 做如下测试:

document.querySelector('#t01').innerText = '555\n666';
document.querySelector('#t02').innerText = '555\n666';
document.querySelector('#t03').innerText = '555\n666';

可以看到 只有 display 为 none 的时候,数据出现了异常:

这样导致的直接错误是,获取整个 body 的 html时, textarea 内的数据异常了:“<textarea id="t01" style="display:none">555<br>666</textarea>”,这个 <br> 会直接导致编辑内容重新展示时出现异常。

不过对于 innerHTML 、textContent 操作均未发现异常。

问题解决:

找到了病根儿就好办了,针对这种情况调整一下代码即可:

textType = (obj.textContent === undefined ? 'innerText' : 'textContent');
if (obj.value !== obj[textType]) {
    obj[textType] = obj.value;
}

反思:

绝大部分界面操作都是直接让用户直接在 textarea 内输入,保存时从 textarea 的 value 内获取数据,像我们这种把编辑器内再融入 CodeMirror 的情况是很少见的,我可以尝试去 chrome 上提交一下 bug,看看是否能得到什么回复。。。拭目以待

https://bugs.chromium.org/p/chromium/issues/detail?id=705478

大结局再次反转:

Chrome 的技术人员答复了我提交的 bug

原文如下:

Safari and Firefox has the same behavior.

This behavior is defined by the HTML standard. The behavior without display:none is a bug according to it.

https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute:dom-innertext-3

Please use textContent or defaultValue or value setter instead of innerText setter.

说白了,早先 innerText 是 IE 自己搞的,现在已经进入到 HTML 标准中,而且定义了是会把 \n 变成 <br> 的,反倒是 没有 display:none 时,我们之前认为正确的结果是个 bug(我估计可能是为了不影响长久以来已经约定俗成的结果)。

备注:测试了一下 <pre> 效果与 <textarea> 完全一样。 

综上所述,面对未来的浏览器,更加严谨规范的操作 DOM,innerText 要根据你的场景来使用了,对于  <pre> 和 <textarea> 来说尽量使用 textContent / value 方法去操作吧。

© 著作权归作者所有

zTree

zTree

粉丝 859
博文 21
码字总数 21754
作品 1
朝阳
技术主管
私信 提问
加载中

评论(1)

巢鹏
巢鹏
CodeMirror对滚动条的hack真心恶心。
实现高度“听话”的多行文本输入框

一、前言   通过创建 textarea 标签,并且指定其 rows 和 cols 属性,就可以创建一个多行文本输入框。   但是当输入的内容超过指定的 rows 之后,就会出现滚动条,如果用户想要查看全部内...

descire
2019/03/26
0
0
如何在html页面显示标签内容

通常情况下,我们希望网页能被正确的解析,页面上不要出现多余的html标签。而有些时候我们又希望能够显示诸如“<body>”这样的内容在段落中。 为了避免html标签被解析掉,找了如下几种方法:...

唐佳
2016/09/01
1.3K
0
Stylus——富有表现力、动态的、健壮的css

其实跟css很想,语法不一样,万变不离其宗 坑1:选择器>父级引用: 惯性思维,我以为是等同于textarea input{color:#000} textarea input:hover{..}(仔细想,哪里不对劲) 坑2:发现跟less什么...

南蓝NL
2017/12/03
0
0
web产品浏览器兼容性问题你有考虑到吗?

  通常,动态网页除了Server端的代码撰写Client端代码也必须下不少工夫。例如:表单提交前的数据验证、图片的轮播、菜单的收合等等。   因此,对于Client端是否能正常执行指令码也必须适...

程序员客栈
2016/07/05
18
0
iframe 父窗口和子窗口相互的调用方法集锦

http://www.jb51.net/article/25629.htm 一、父窗口调用iframe子窗口方法 1、HTML语法: 2、父窗口调用子窗口:myFrame.window.functionName(); 3、子窗品调用父窗口:parent.functionName()...

lionkas
2017/09/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

laravel 多条件查询 闭包写法

laravel 多条件查询 闭包写法 直接上代码 1: 比如我要查询 符合条件的 部门和 用户 DB::table('user')->where('user_id',20)->whereIn('d_id',[82,83])->get(); 可以使用下面这种方法替换 ......

李佳顺
4分钟前
9
0
springboot实现热部署

一、前言 在实际开发过程中,每次修改代码就得将项目重启,重新部署,对于一些大型应用来说,重启时间需要花费大量的时间成本。对于一个后端开发者来说,重启过程确实很难受。在java开发领域...

素小暖OSC
5分钟前
38
0
为什么要选择开源的直播源码开发直播系统?

相信大家在购买直播源码的过程中,肯定都会咨询过是否开源这个问题。对于懂技术的人来说,开源的意思非常好理解,而对于不懂技术的人来说,开源可能是个非常难以理解的词汇。在这里跟大家简单...

图玩智能科技
7分钟前
18
0
真的在Windows中杀死一个进程

偶尔,Windows机器上的程序会发疯,只是挂起。 所以我将调用任务管理器并点击“结束进程”按钮。 但是,这并不总是有效; 如果我尝试了足够多次,那么它通常会最终死亡,但我真的希望能够立即...

技术盛宴
11分钟前
39
0
使用低代码平台 - 危险的赌注

低代码应用平台(LCAP - low code application platforms)在多样、复杂的现代软件开发情势下应运而生。依据Gartner(高德纳,全球最具权威的IT研究与顾问咨询公司)的数据,Mendix 是这方面...

CUBAChinaTeam
12分钟前
31
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部