文档章节

innerText 操作 textarea 的 “坑”

zTree
 zTree
发布于 2017/03/27 18:29
字数 1003
阅读 481
收藏 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

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

评论(1)

巢鹏
巢鹏
CodeMirror对滚动条的hack真心恶心。
如何在html页面显示标签内容

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

唐佳
2016/09/01
101
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
12
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
jquery、js调用iframe父窗口与子窗口元素的方法

$("iframe").contents().find("body").append("I'm in an iframe!"); $(window.frames["iframe1"].document).find("input[@type='text']").attr("size","30px"); $("#iframe1").contents().f......

zh119893
2014/05/18
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

Confluence 6 自定义你的空间

通过对你的空间进行界面的自定义能够让你的空间更加出类拔萃。 如果你具有空间管理员权限,你可以修改你空间的颜色配色,添加你自己的空间标识,选择是否在你空间中显示边栏。或者你可以进入...

honeymose
今天
1
0
Ubuntu18.04 安装MySQL

1.安装MySQL sudo apt-get install mysql-server 2.配置MySQL sudo mysql_secure_installation 3.设置MySQL非root用户 设置原因:配置过程为系统root权限,在构建MySQL连接时出现错误:ERROR...

AI_SKI
今天
3
0
3.6 rc脚本(start方法) 3.7 rc脚本(stop和status方法) 3.8 rc脚本(以daemon方式启动)

3.6-3.7 rc脚本(start、stop和status方法) #!/usr/bin/env python# -*- coding: utf-8 -*-# [@Version](https://my.oschina.net/u/931210) : python 2.7# [@Time](https://my.oschina.......

隐匿的蚂蚁
今天
3
0
Cnn学习相关博客

CNN卷积神经网络原理讲解+图片识别应用(附源码) 笨方法学习CNN图像识别系列 深度学习图像识别项目(中):Keras和卷积神经网络(CNN) 卷积神经网络模型部署到移动设备 使用CNN神经网络进行...

-九天-
昨天
5
0
flutter 底部输入框 聊天输入框 Flexible

想在页面底部放个输入框,结果键盘一直遮住了,原来是布局问题 Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("评论"), ...

大灰狼wow
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部