我试图替换一个可信的div中的某个字符串。 Replace()函数对我不起作用,不确定我哪里出错。
我的代码:
<div contenteditable="true" id="contenteditableDiv"></div>
$(document).ready(function(){
$('#contenteditableDiv').on('keyup', function() {
var content = $('#contenteditableDiv').html();
var watcher = (content.match(/cat/gi)||[]).length;
if (watcher === 1) {
$('#contenteditableDiv').html().replace(/cat/g, "dog");
};
});
});
这是一个有点简化的例子(用“&#39; dog&#39;”代替“&#39; cat&#39;”这个词。最后,我计划在键入一系列字符串时触发此操作(即四个连续的换行符)。
答案 0 :(得分:2)
从我从问题中收集到的是:
正在使用contenteditable
<div>
。
当用户输入时,如果输入关键字(“cat”),它将被新关键字(“dog”)替换。
keyup
事件无法促成此行为。
keyup
之类的键盘事件过于气馁:
“可聚焦元素可能因浏览器而异,但表单元素始终可以获得焦点,因此这种事件类型是合理的候选者。”
因此,接收键盘事件等事件的关键是能够获得focus
。可以100%获得focus
时间的元素是表单元素(例如<input>
,<textarea>
等)。虽然键盘事件在表单元素上是可以的,但change
和input
事件专门用于表单事件。
由于OP代码需要contenteditable
<div>
而不是<textarea>
,因此Demo有:
div#view
contenteditable
textarea#edit
下的一个div#view
,只有光标可见。
当用户输入div#view
时,textarea#edit
实际上正在侦听input
事件,div#view
正在侦听keyup
事件。< / p>
当input
事件发生时,#edit
会立即将#view
的文本设置为其自身值的文本。在每个keyup
事件#view
上将focus
设置回#edit
。
基本上,div#view
和textarea#edit
占据相同的空间,#view
位于前方#edit
位于#view
之后。用户输入是#edit
上的透明文字,但其光标是可见的(因为在focus
事件期间它始终从#view
获得keyup
。 #view
从#edit
获取其文字。
作为奖励,用户输入要更改的任何字符串(如“cat”)并输入要更改的字符串(如“dog”)。
注意:我之所以选择这样一个错综复杂的解决方案,是因为游标的focus
。在没有人的情况下打字会感觉很人为,并且使用弹出回到开头的光标进行打字会令人迷惑。
在演示中评论的详细信息
如果要呈现HTML,请参阅jQuery部分中的注释
$(document).ready(function() {
// textarea listens for input event...
$('#edit').on('input', function() {
// Collect values from inputs and textarea
var from = $('#from').val();
var to = $('#to').val();
var value = $(this).val();
/* if the value of input#from is in the value of textarea...
|| indexOf() will return its index number...
|| so if indexOf() doesn't find it then it returns -1
*/
if (value.indexOf(from) !== -1) {
// Using RegExp Object for variable string
var rgx = new RegExp(from, 'g');
// New value of textarea#edit replaced 'from' with 'to'
value = value.replace(rgx, to);
}
// The text of div#view is the new value of #edit
/* Change .text to .html is you want to render HTML but it
|| be disorienting as what is actually typed is not seen.
|| A more feasible solution is to move #edit below view and
|| change #edit color to a visible color.
*/
$('#view').text(value);
// The value of #edit is the new value
$(this).val(value);
});
// #view listens for keydown event...
$('#view').on('keydown', function() {
// Move focus to #edit
$('#edit')[0].focus();
});
});
html,
body {
font: 400 16px/1.3 Consolas;
}
/* Wrap fieldset.main around both textarea and div
|| div will be on top of textarea because they are absolute
*/
.main {
position: relative;
width: 90vw;
border: 0
}
input {
font: inherit;
width: 20ch;
}
/* Only textarea#edit's cursor is visible */
#edit {
border: 0;
outline: 0;
color: transparent;
caret-color: red;
position: absolute;
width: 100%;
font: inherit;
left: 2px;
}
/* Editable div#view is over textarea#edit */
/* textarea#edit will actually get an input event */
/* User will see the div's text that comes from #edit*/
/* The value typed into #edit is transparent so user only sees
div#view's text and textarea#edit's cursor */
#view {
position: absolute;
pointer-events: none;
z-index: 1;
outline: 3px inset grey;
width: 100%;
min-height: 50px;
left: 2px;
}
<!--UI enter target string and new string-->
<fieldset class='ui'>
<legend>Convert String</legend>
<label>From: </label><input id='from'>
<label>To: </label><input id='to'>
</fieldset>
<!--Wrap editable div and textarea in an relative element-->
<fieldset class='main'>
<!--Div and textaera are absolute see CSS-->
<div id="view" contenteditable="true"></div>
<textarea id='edit'></textarea>
</fieldset>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
答案 1 :(得分:1)
您替换了字符串但未分配回来。
请注意,更换后,cousor不会停留在您输入的位置。
$(document).ready(function() {
$('#contenteditableDiv').on('keyup', function(e) {
var $this = $(this)
var content = $this.html();
var watcher = (content.match(/cat/gi) || []).length;
var position = e
if (watcher === 1) {
var text = content.replace(/cat/g, "dog");
$this.html(text);
};
});
});
&#13;
div {
border: 1px gray solid;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable="true" id="contenteditableDiv"></div>
&#13;
答案 2 :(得分:0)
这个更简单的解决方案呢?
$("#contenteditableDiv").on('keyup', function() {
$(this).val($(this).val().replace(/cat/g, "dog"));
});
&#13;
#contenteditableDiv {
width: 90%;
height: 100px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="contenteditableDiv"></textarea>
&#13;
你的问题是$('#contenteditableDiv').html()
在呈现时返回元素的值,即为空
要获取当前值,您需要使用.val()
。
检查此问题,了解何时使用.html()
,.val()
,.text()
。
When do I use .val() vs .innerHTML?
答案 3 :(得分:0)
如果元素设置为contenteditable
,则没有任何缺点。
它与任何其他元素一样,以下代码段使用jquery NOT ,这是纯ecma6 javascript replace()。
自2015年以来在浏览器中推出。您的图书馆很难有机会处理好现代js,可能存在冲突。
onload =(()=>{
ctd.innerHTML = ctd.innerHTML.replace("world","<mark>world</mark>")
})
&#13;
<div contenteditable="true" id="ctd">Hello world</div>
&#13;
这就是说,关于具体的contenteditable
属性,我们可以使用 - ,因为不是很长时间 - document.execCommand(),它与浏览器{{3}一起使用}}
查看editing api上的更多功能。 最后的话,我的观点,jquery已经现在。
Ecma6是要走的路,我们可以用更少的代码,更快的速度和非常接近完整的浏览器支持来完成jquery提供的所有功能。
Js就是他现在因为jquery。
答案 4 :(得分:0)
在找到这个帖子并自己在这个主题上挣扎了一段时间后,我创建了一个 npm 包,它可以自动转换 contenteditable 元素中的给定关键字。