我有一个场景,我需要在文本区域中选择文本显示div(如弹出窗口)。但是,我使用鼠标按下它,div的位置有时不完全低于文本
JavaScript的:
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;
// obtain the selected text
var sel = allText.substring(start, finish);
sel = sel.replace(/[\S]/g, "*");
//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();
}
$(document).ready(function () {
var position;
$('#newpost').hide();
$('#mytextarea').on('select', function (e) {
var str = $('#mytextarea').val();
$('#newpost').offset(position).show();
var txtarea = document.getElementById("mytextarea");
var start = txtarea.selectionStart;
var finish = txtarea.selectionEnd;
$('#newpost div').text('Replace with stars');
}).on('select', function (e) {
position = { top: e.pageY+10, left: e.pageX };
});
$('#newpost').hide();
});
function closePopUp() {
$('#newpost').hide();
}
这是我的plunker链接
这里我的要求是显示文本的div选择。但是当我使用on-select而不是mouse-down时,div显示在text-area下面。
先谢谢。
答案 0 :(得分:1)
几天前在this answer我提出了一种方法,即当用户选择一些文字时,找到光标位置并在div
上显示textarea
。
然而,正如@anub所提到的那样,这种方法很有效,div
有时会显示在所选文本的正下方,但是上下两个像素 - 因为它的位置是基于第一个用户点击。
经过短暂的搜索后,我发现this post描述了如何通过创建给定textarea的临时div
克隆来查找textarea中所选文本的位置。
我已经从那里采用了getCursorXY
方法并用它来定位弹出窗口。
试一试!
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;
// 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("*"));
});
});
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,
}
}
&#13;
#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;
}
&#13;
<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>
&#13;
答案 1 :(得分:0)
我在关闭弹出窗口并重新选择其他区域时遇到了这个问题,我通过
解决了这个问题function closePopUp() {
$('#newpost').offset({ top: 0, left: 0 }).hide();
}
检查出来