用纯jQuery替换contenteditable中的动态文本
Replacing text on-the-fly in contenteditable with pure jQuery
我在StackOverflow上看到了一些关于这方面的问题,但似乎很难找到基于jQuery的解决方案。因此,我想提出这个问题。
我想用属性contenteditable="true"
替换div
中的动态文本。
我正在寻找一个基于jQuery的解决方案,它将执行以下操作:
- 动态自动替换书面文本(键入时)
- 能够继续写作(在替换过程中)
我看了SC Editor(http://www.sceditor.com/),它似乎正是这样做的(例如,如果你尝试键入:)
,它会被一个表情符号所取代。
我认为一个好的开始应该是一个包含所有元素的数组:
$.settings = {
path: 'https://example.com/images/',
emoticons: {
':(' : 'stupid.jpg',
':)' : 'smart.jpg',
}
}
我一直找不到这样的好例子。如果有人能分享他们的想法和任何关于这方面的代码,我会很高兴。
使用上述代码,如何以最佳方式进行更换?
我发现了这个。如果你调整一下,它可能会适合你的需要。它将{替换为{}和(替换为(),光标最终位于在中间。
<script type="text/javascript">
$(document).ready(function () {
$("#d").keypress(function (e) {
var charTyped = String.fromCharCode(e.which);
if (charTyped == "{" || charTyped == "(") {
// Handle this case ourselves
e.preventDefault();
var sel = window.getSelection();
if (sel.rangeCount > 0) {
// First, delete the existing selection
var range = sel.getRangeAt(0);
range.deleteContents();
// Insert a text node with the braces/parens
var text = (charTyped == "{") ? "{}" : "()";
var textNode = document.createTextNode(text);
range.insertNode(textNode);
// Move the selection to the middle of the text node
range.setStart(textNode, 1);
range.setEnd(textNode, 1);
sel.removeAllRanges();
sel.addRange(range);
}
}
});
});
</script>
</head>
<body>
<div id="d" contentEditable="true">....</div>
</body>
</html>
$('div').keyup(function(){
//make here for loop which replace all emoticons
$(this).text().replace(':(', 'stupid.jpg');
});
发布我在找不到这个问题的答案后最终写的内容。我希望这将有助于其他人谁来到这个问题寻求答案(:
我将发布一个更通用的查找和替换解决方案(包含在一个类中)。这适用于内容可编辑的div,在用户键入时有效,此外,它不会影响插入符号的位置。这个实现使用了不区分大小写的搜索(尽管在代码中禁用它是微不足道的)。它的另一个优点是,即使您在段落的中间(而不仅仅是在行的末尾)打字,它也可以工作,并且可以处理粘贴的文本。试试看!
class FindAndReplace {
constructor($contentEditable, findAndReplaceData) {
var self = this;
$contentEditable.on('input blur', function () {
var textNodes = self.getTextNodes($contentEditable);
textNodes.each(function (i) {
// Perform all replacements on text
findAndReplaceData.forEach(function (findAndReplaceDatum) {
var find = findAndReplaceDatum.find;
var replace = findAndReplaceDatum.replace;
var regexEscapedFind = self.escapeRegExp(find);
var regexEscapedReplace = self.escapeRegExp(replace);
var regexEscapedCaseInsensitiveFind = self.makeRegexCaseInsensitive(regexEscapedFind);
// Case insensitive search for the find with a negative lookahead to check its not a case sensitive match of the replacement (aka to check its actually going to make a difference)
var regexString = `(?!${regexEscapedReplace})${regexEscapedCaseInsensitiveFind}`;
do {
// Get the latest version of the text node
textNode = self.getTextNodes($contentEditable)[i];
var text = textNode.data;
var regex = new RegExp(regexString);
var matchIndex = text.search(regex);
var matchFound = (matchIndex !== -1);
if (matchFound) {
// Select the match
var range = document.createRange();
range.setStart(textNode, matchIndex);
range.setEnd(textNode, matchIndex + find.length);
// Delete it
range.deleteContents();
// Create the replacement node
var textNode = document.createTextNode(replace);
// Insert it
range.insertNode(textNode);
// Set the range to the end of the selected node
range.collapse(false);
// Set the user selection the range
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
// Make sure there a no adjacent or empty text nodes
$contentEditable[0].normalize();
}
} while (matchFound)
});
});
});
}
escapeRegExp(string) {
// https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
return string.replace(/[.*+?^${}()|[']'']/g, '''$&'); // $& means the whole matched string
}
getTextNodes($contentEditable) {
return $contentEditable.contents().filter(function () {
return this.nodeType == 3; // Text node
});
}
makeRegexCaseInsensitive(string) {
var stringArray = string.split('');
stringArray = stringArray.map(function (char) {
if (char.toLowerCase() !== char.toUpperCase())
return '[' + char.toLowerCase() + char.toUpperCase() + ']';
else
return char;
});
return stringArray.join('');
}
}
div {
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(function(){
var findAndReplaceData = [
{
'find': 'find me',
'replace': 'and replace with me!'
},
{
'find': 'foo',
'replace': 'bar'
},
{
'find': 'no',
'replace': 'yes'
}
];
$contentEditable = $('div');
new FindAndReplace($contentEditable,findAndReplaceData);
});
</script>
<div contenteditable="true"></div>
相关文章:
- createjs动态文本重叠
- 在 JavaScript 中添加动态文本
- 动态文本大小JavaScript在IE中不起作用
- 使用Date.parse();从动态文本中删除(或允许)序数字符;
- 用动态文本和动态大小填充多边形
- Javascript/jQuery链接/href补充的动态文本
- 通过javascript的动态文本框
- 动态文本的 SVG 线条动画
- 动态文本区域的Javascript验证
- 通过jquery验证动态文本
- 将单击按钮时的动态文本区域值传递给javascriptphp
- 如何将动态文本框值分配给相应的模型
- 如何创建动态文本并使用 KineticJS 对其进行编辑.任何可以说明的例子都会很棒
- 使用颜色选取器更改所选动态文本框的文本颜色
- 发布多个动态文本框值
- 从选定的对象获取动态文本 - (通过 ID 和“活动”类) - jQuery
- 动态文本区域高度
- 为动态文本框创建新的会话变量
- PHP 邮件中的动态文本框
- 钛应用器动态文本区域高度增加