如何在textarea中显示选定文本下方的div? [英] how to show a div below selected text in textarea?

查看:110
本文介绍了如何在textarea中显示选定文本下方的div?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个场景,我需要在文本区域中选择文本显示div(如弹出窗口)。但是,我使用鼠标按下它,div的位置有时不完全低于文本。



JavaScript:

  function getSel(){
//获取textarea的对象引用>
var txtarea = document.getElementById(mytextarea);
//获取第一个选定字符的索引
var start = txtarea.selectionStart;
//获取最后一个选定字符的索引
var finish = txtarea.selectionEnd;
//获取所有Text
var allText = txtarea.value;
//获取所选文本
var sel = allText.substring(start,finish);
sel = sel.replace(/ [\ S] / g,*);
//追加文字;
var newText = allText.substring(0,start)+ sel + allText.substring(finish,allText.length);
txtarea.value = newText;
$('#newpost')。offset({top:0,left:0})。hide();
}

$(文件).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('替换为星星');
})。on('select',function(e){
position = {top:e.pageY +10,左:e.pageX};
});
$('#newpost')。hide();
});
函数closePopUp(){
$('#newpost')。hide();
}

这是我的 plunker 链接



这里我的要求是显示文本的div选择。但是当我使用on-select而不是mouse-down时,div显示在text-area下面。



提前感谢。

解决方案

几天前在这个答案我建议当用户选择一些文本时,查找光标位置并在 textarea 上显示 div 的方法。



然而,这种方法有效,正如@anub所提到的, div 有时显示在所选文本的正下方,但是几个像素向上或向下 - 因为它的位置是根据第一个用户的点击确定的。



经过短暂的搜索我发现这篇文章描述了如何在textarea中找到所选文本的位置通过创建给定textarea的临时 div 克隆。



我采用了从那里获取getCursorXY 方法并用它来定位弹出窗口。



试一试!



  function getSel(){//获取textarea的对象引用> var txtarea = document.getElementById(mytextarea); //获取第一个选定字符的索引var start = txtarea.selectionStart; //获取最后一个选定字符的索引var finish = txtarea.selectionEnd; //获取所有Text var allText = txtarea.value; //获取所选文本var sel = Array(finish  -  start + 1).join(*); //追加文字; 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 //创建一个虚拟元素,它将是我们输入的克隆const div = document.createElement('div')//获取输入和克隆的计算样式它在虚拟元素const copyStyle = getComputedStyle(input)for(const prop of copyStyle){div.style [prop] = copyStyle [prop]} //我们需要一个在填充虚拟元素时替换空格的字符//如果这是一行< input /> const swap ='。'const inputValue = input.tagName ==='INPUT'? input.value.replace(/ / g,swap):input.value //将div内容设置为textarea的内容,直到选择const textContent = inputValue.substr(0,selectionPoint)//设置虚拟内容的文本内容element div div.textContent = textContent if(input.tagName ==='TEXTAREA')div.style.height ='auto'//如果单行输入则div必须是单行而不是像文本那样突破area if(input.tagName ==='INPUT')div.style.width ='auto'//创建一个标记元素以获取插入符号位置const span = document.createElement('span')//为span提供textContent剩余内容,以便重新创建的虚拟元素//尽可能接近span.textContent = inputValue.substr(selectionPoint)|| '。'//将span标记附加到div div.appendChild(span)//将虚拟元素附加到body document.body.appendChild(div)//获取标记位置,这是顶部和左侧的插入位置相对于输入const {offsetLeft:spanX,offsetTop:spanY} = span //最后,删除该虚拟元素// NOTE ::如果要查看该跨度呈现的位置,可以将其注释用于调试目的。 removeChild(div)//返回一个包含插入符号x和y的对象。考虑输入定位//这样你就不需要包装输入返回{left:inputX + spanX,top:inputY + spanY + offset,}}  

< pre class =snippet-code-css lang-css prettyprint-override> #mytextarea {width:600px;身高:200px;溢出:隐藏;位置:固定} #newpost {position:absolute;背景色:#ffffdc; border:1px solid #DCDCDC;边界半径:10px的;填充右:5像素;宽度:自动;身高:30px;} #newpost span {cursor:pointer;位置:绝对;顶部:0;右:5px; font-size:22px;} #newpost div {color:#0000ff;填充:10px的;保证金权:10px的;宽度:自动; cursor:pointer;}

 < script src =https ://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js>< /脚本>< HTML> < HEAD> < /头> <身体GT; < textArea id =mytextarea>< / textArea> < div id =newpost> < span onclick =closePopUp();>&#735;< / span> < div onclick =getSel()>< / div> < / div>< / body>< / html>  


I have a scenario,where I need to show a div(like popup) on-select of text in text-area.But, I used mouse-down for it,the position of div is not exactly below the text sometimes.

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();
}

Here is my plunker link

Here my requirement is to show a div on-select of text.But when I am using on-select instead of mouse-down,the div is showing below text-area.

Thanks in Advance.

解决方案

A few days ago in this answer I suggested an approach of finding the cursor position and displaying a div over the textarea when the user selects some text.

This approach works, however, as @anub has mentioned, div is sometimes displayed not right under the selected text, but a couple of pixels up or down - because it's position is determined based on the first user's click.

After a short search I found this post that describes how to find the position of the selected text in the textarea by creating a temporary div clone of the given textarea.

I've adopted the getCursorXY method from there and used it to position the popup.

Give it a try!

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,
  }
}

#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();">&#735;</span>
        <div onclick="getSel()"></div>
    </div>
</body>

</html>

这篇关于如何在textarea中显示选定文本下方的div?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆