我有一个场景,我需要用文本区域中的星号替换文本。替换文本后,默认事件 (Ctrl+Z) 不起作用。
JavaScript:
$(document).ready(function () {
closePopUp();
var newpost = $('#newpost');
$('#mytextarea').on('select', function (e) {
var txtarea = document.getElementById("mytextarea");
var start = txtarea.selectionStart;
var finish = txtarea.selectionEnd;
newpost.offset(getCursorXY(txtarea, start, 20)).show();
newpost.find('div').text('replace with stars');
});
});
const getCursorXY = (input, selectionPoint, offset) => {
const {
offsetLeft: inputX,
offsetTop: inputY,
} = input
// create a dummy element that will be a clone of our input
const div = document.createElement('div')
// get the computed style of the input and clone it onto the dummy element
const copyStyle = getComputedStyle(input)
for (const prop of copyStyle) {
div.style[prop] = copyStyle[prop]
}
// we need a character that will replace whitespace when filling our dummy element
// if it's a single line <input/>
const swap = '.'
const inputValue = input.tagName === 'INPUT' ? input.value.replace(/ /g, swap) : input.value
// set the div content to that of the textarea up until selection
const textContent = inputValue.substr(0, selectionPoint)
// set the text content of the dummy element div
div.textContent = textContent
if (input.tagName === 'TEXTAREA') div.style.height = 'auto'
// if a single line input then the div needs to be single line and not break out like a text area
if (input.tagName === 'INPUT') div.style.width = 'auto'
// create a marker element to obtain caret position
const span = document.createElement('span')
// give the span the textContent of remaining content so that the recreated dummy element
// is as close as possible
span.textContent = inputValue.substr(selectionPoint) || '.'
// append the span marker to the div
div.appendChild(span)
// append the dummy element to the body
document.body.appendChild(div)
// get the marker position, this is the caret position top and left relative to the input
const { offsetLeft: spanX,offsetTop: spanY } = span
// lastly, remove that dummy element
// NOTE:: can comment this out for debugging purposes if you want to see where that span is rendered
document.body.removeChild(div)
// return an object with the x and y of the caret. account for input positioning
// so that you don't need to wrap the input
return {
left: inputX + spanX,
top: inputY + spanY + offset,
}
}
这是我的 Plunker
我需要在执行“Ctrl+Z”时获取之前的文本。
提前致谢。
最佳答案
试试这个。它将保存最后一次替换并在 Ctrl+Z 上撤消它。
但是,如果要保存多个替换,则需要更复杂的逻辑。
var selection = {};
function undo(e) {
var evtobj = window.event? window.event : e;
if (evtobj.keyCode == 90 && evtobj.ctrlKey && selection.text) {
evtobj.preventDefault();
var txtarea = document.getElementById("mytextarea");
var allText = txtarea.value;
var newText = allText.substring(0, selection.start) + selection.text + allText.substring(selection.finish, allText.length);
txtarea.value = newText;
}
}
function getSel() {
// obtain the object reference for the textarea>
var txtarea = document.getElementById("mytextarea");
// obtain the index of the first selected character
var start = txtarea.selectionStart;
// obtain the index of the last selected character
var finish = txtarea.selectionEnd;
//obtain all Text
var allText = txtarea.value;
selection.text = allText.substring(start, finish);
selection.start = start;
selection.finish = finish;
// obtain the selected text
var sel = Array(finish - start + 1).join("*");
//append te text;
var newText = allText.substring(0, start) + sel + allText.substring(finish, allText.length);
txtarea.value = newText;
$('#newpost').offset({top: 0, left: 0}).hide();
}
function closePopUp() {
$('#newpost').offset({top: 0, left: 0}).hide();
}
$(document).ready(function () {
closePopUp();
var newpost = $('#newpost');
$('#mytextarea').on('select', function (e) {
var txtarea = document.getElementById("mytextarea");
var start = txtarea.selectionStart;
var finish = txtarea.selectionEnd;
newpost.offset(getCursorXY(txtarea, start, 20)).show();
newpost.find('div').text(Array(finish - start + 1).join("*"));
}).on('input', () => selection.text = null);
document.onkeydown = undo;
});
const getCursorXY = (input, selectionPoint, offset) => {
const {
offsetLeft: inputX,
offsetTop: inputY,
} = input
// create a dummy element that will be a clone of our input
const div = document.createElement('div')
// get the computed style of the input and clone it onto the dummy element
const copyStyle = getComputedStyle(input)
for (const prop of copyStyle) {
div.style[prop] = copyStyle[prop]
}
// we need a character that will replace whitespace when filling our dummy element
// if it's a single line <input/>
const swap = '.'
const inputValue = input.tagName === 'INPUT' ? input.value.replace(/ /g, swap) : input.value
// set the div content to that of the textarea up until selection
const textContent = inputValue.substr(0, selectionPoint)
// set the text content of the dummy element div
div.textContent = textContent
if (input.tagName === 'TEXTAREA') div.style.height = 'auto'
// if a single line input then the div needs to be single line and not break out like a text area
if (input.tagName === 'INPUT') div.style.width = 'auto'
// create a marker element to obtain caret position
const span = document.createElement('span')
// give the span the textContent of remaining content so that the recreated dummy element
// is as close as possible
span.textContent = inputValue.substr(selectionPoint) || '.'
// append the span marker to the div
div.appendChild(span)
// append the dummy element to the body
document.body.appendChild(div)
// get the marker position, this is the caret position top and left relative to the input
const { offsetLeft: spanX, offsetTop: spanY } = span
// lastly, remove that dummy element
// NOTE:: can comment this out for debugging purposes if you want to see where that span is rendered
document.body.removeChild(div)
// return an object with the x and y of the caret. account for input positioning
// so that you don't need to wrap the input
return {
left: inputX + spanX,
top: inputY + spanY + offset,
}
}
#mytextarea {width: 600px; height: 200px; overflow:hidden; position:fixed}
#newpost {
position:absolute;
background-color:#ffffdc;
border:1px solid #DCDCDC;
border-radius:10px;
padding-right:5px;
width: auto;
height: 30px;
}
#newpost span {
cursor:pointer;
position: absolute;
top: 0;
right: 5px;
font-size: 22px;
}
#newpost div {
color:#0000ff;
padding:10px;
margin-right:10px;
width: auto;
cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
</head>
<body>
<textArea id="mytextarea"></textArea>
<div id="newpost">
<span onclick="closePopUp();">˟</span>
<div onclick="getSel()"></div>
</div>
</body>
</html>
关于javascript - 如何使用 Ctrl+Z 事件将文本替换为星号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48499220/