我将一个 div 设置为 contentEditable
并设置了“white-space:pre
”样式,这样它就可以保留换行符之类的东西。在 Safari、FF 和 IE 中,div 的外观和工作方式几乎相同。一切都很好。我想要做的是从此 div 中提取文本,但不会丢失格式——特别是换行符。
我们正在使用 jQuery,它的 text()
函数基本上执行预排序 DFS,并将 DOM 分支中的所有内容粘合在一起成为一个 block 。这会丢失格式。
我查看了 html()
函数,但似乎所有三种浏览器对在我的 contentEditable
中在幕后生成的实际 HTML 做了不同的事情> 分区。假设我将其输入到我的 div 中:
1
2
3
结果如下:
Safari 4:
1
<div>2</div>
<div>3</div>
火狐 3.6:
1
<br _moz_dirty="">
2
<br _moz_dirty="">
3
<br _moz_dirty="">
<br _moz_dirty="" type="_moz">
IE 8:
<P>1</P><P>2</P><P>3</P>
呃。这里没有什么非常一致的。令人惊讶的是,MSIE 看起来最理智! (大写 P 标签和所有)
div 将动态设置样式(字体、颜色、大小和对齐方式),这是使用 CSS 完成的,所以我不确定我是否可以使用 pre
标签(已被提及)在我使用 Google 发现的某些页面上)。
有谁知道任何 JavaScript 代码和/或 jQuery 插件或其他东西可以从 contentEditable div 中提取文本以保留换行符?我不想重新发明一个解析如果不需要的话,我会用轮子。
更新:我抄袭了 jQuery 1.4.2 中的 getText
函数并对其进行了修改以提取它,其中的空白大部分完好无损(我只在添加换行符的地方更改了一行);
function extractTextWithWhitespace( elems ) {
var ret = "", elem;
for ( var i = 0; elems[i]; i++ ) {
elem = elems[i];
// Get the text from text nodes and CDATA nodes
if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
ret += elem.nodeValue + "\n";
// Traverse everything else, except comment nodes
} else if ( elem.nodeType !== 8 ) {
ret += extractTextWithWhitespace2( elem.childNodes );
}
}
return ret;
}
我调用这个函数并使用它的输出通过 jQuery 将它分配给一个 XML 节点,例如:
var extractedText = extractTextWithWhitespace($(this));
var $someXmlNode = $('<someXmlNode/>');
$someXmlNode.text(extractedText);
生成的 XML 最终通过 AJAX 调用发送到服务器。
这在 Safari 和 Firefox 中运行良好。
在 IE 上,似乎只有第一个 '\n' 以某种方式保留下来。仔细研究一下,jQuery 看起来像这样设置文本(jQuery-1.4.2.js 的第 4004 行):
return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
阅读 createTextNode
,IE 的实现似乎混搭了空白。这是真的还是我做错了什么?
最佳答案
不幸的是,您仍然需要为 pre
处理这个问题每个浏览器单独处理(在很多情况下我不允许浏览器检测,使用特征检测...但在这种情况下这是必要的),但幸运的是你可以采取像这样简洁地处理它们:
var ce = $("<pre />").html($("#edit").html());
if($.browser.webkit)
ce.find("div").replaceWith(function() { return "\n" + this.innerHTML; });
if($.browser.msie)
ce.find("p").replaceWith(function() { return this.innerHTML + "<br>"; });
if($.browser.mozilla || $.browser.opera ||$.browser.msie )
ce.find("br").replaceWith("\n");
var textWithWhiteSpaceIntact = ce.text();
You can test it out here . IE 尤其麻烦,因为它的方式是
和文本转换中的新行,这就是它获得 <br>
的原因上面的处理使其保持一致,因此需要 2 遍才能正确处理。
在上面#edit
是 contentEditable
的 ID组件,所以只要把它改掉,或者把它变成一个函数,例如:
function getContentEditableText(id) {
var ce = $("<pre />").html($("#" + id).html());
if ($.browser.webkit)
ce.find("div").replaceWith(function() { return "\n" + this.innerHTML; });
if ($.browser.msie)
ce.find("p").replaceWith(function() { return this.innerHTML + "<br>"; });
if ($.browser.mozilla || $.browser.opera || $.browser.msie)
ce.find("br").replaceWith("\n");
return ce.text();
}
You can test that here .或者,由于它无论如何都是基于 jQuery 方法构建的,因此将其作为一个插件,如下所示:
$.fn.getPreText = function () {
var ce = $("<pre />").html(this.html());
if ($.browser.webkit)
ce.find("div").replaceWith(function() { return "\n" + this.innerHTML; });
if ($.browser.msie)
ce.find("p").replaceWith(function() { return this.innerHTML + "<br>"; });
if ($.browser.mozilla || $.browser.opera || $.browser.msie)
ce.find("br").replaceWith("\n");
return ce.text();
};
然后你可以用$("#edit").getPreText()
调用它, you can test that version here .
关于javascript - 从 contentEditable div 中提取文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3455931/