Obtener las coordenadas (X, Y) de la ultima letra de un textarea

Tengo un dropdown que quiero posicionar en el ultimo carácter del textarea, pero no se como lograrlo, he investigado como capturar la posición del cursor del textarea pero no he encontrado algo útil y no tengo ni idea de como hacerlo

Este es mi código que tengo hasta ahora:

$(function(){
  $('textarea').on('keyup',function(evt){
    if(evt.which >= 96 && evt.which < 106){
      //console.log(String.fromCharCode(evt.which-48))
    }
    //console.log($('textarea').val());
    if($('div.dropdown').hasClass('open')){
      $('div.dropdown').removeClass('open');
    }else{
      $('div.dropdown').addClass('open');
    }
  })
});
textarea{
  border: 1px solid gray;
  height: 100px;
  min-width: 100%;
  max-width: 100%;
}





Mi resultado esperado es esto: introducir la descripción de la imagen aquí

5
задан 16.11.2016, 21:19
2 ответа

textareaHelper - plugin jQuery, что podrГ, - когда пример решает твою проблему

Здесь, как оно функционирует:

$('textarea').on('keyup paste cut mouseup', function () {
  var $textarea = $(this),
      $dropdown = $('div.dropdown');
  
  // Obtenemos el alto del textarea
  var contentHeight = $textarea.textareaHelper('height');
  
  // Seteamos el alto del contenido, ya que vamos a agrandarlo a medida que escribimos
  $textarea.height(contentHeight);
  
  // Movemos el dropdown justo despues del textarea
  $dropdown.insertAfter($textarea);
  
  // Posicionamos el dropdown a las coords del caret
  $dropdown.css(
    $(this).textareaHelper('caretPos')
  );
});
.textareaHelperContainer {
  position: relative;
}

.textareaHelperContainer .dropdown {
  position: absolute;
  margin-top: 15px; /* apenas mayor al font-size */
  margin-left: 2px; /* una pequeña separacion */
}

textarea {
  width: 250px;
  min-height: 100px;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<script type="text/javascript" src="//code.jquery.com/jquery-1.8.3.js"></script>
<script type="text/javascript" src="http://rawgithub.com/Codecademy/textarea-helper/master/textarea-helper.js"></script>

<div class="textareaHelperContainer">
  <textarea></textarea>
</div>
<div class="textareaHelperContainer">
  <textarea></textarea>
</div>

<div class="dropdown open">
  <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
    <li><a href="#">Action</a></li>
    <li><a href="#">Another action</a></li>
    <li><a href="#">Something else here</a></li>
    <li role="separator" class="divider"></li>
    <li><a href="#">Separated link</a></li>
  </ul>
</div>
2
ответ дан 24.11.2019, 12:35
  • 1
    brother, считая, что ты имеешь má s 1000 точек, ты должен знать, что важно размещать пример, что fá cilmente может быть extraí do вышедшей в свет ссылки. Главный мотив состоит в том, чтобы предотвращать будущие сломанные ссылки. Привет :D –  fredyfx 16.11.2016, 21:55
  • 2
    @fredyfx, у тебя есть вся razó n, deberí чтобы высказать мнение, плохая mí в. Я обновил мой ответ. –  Marcos 16.11.2016, 22:03
  • 3
    дай ему! мы создаем между всеми лучший испанский сайт помощи в programació n :D –  fredyfx 16.11.2016, 22:07
  • 4
    Он мне нравится из-за простоты có я говорю, но размещаю ли я другие этикетки перед textarea поле ввода, которое следует за курсором textarea, не двигает posició n textarea –  JuankGlezz 17.11.2016, 02:58
  • 5
    @JuankGlezz, я обновил мой ответ, чтобы давать solució n в проблему, о которой ты упоминаешь. –  Marcos 17.11.2016, 13:14

Приспособленный этот ответ в SOen , который выполняет то, что я действительно ищу, и дает мне результат, который я ищу действительно.

то, что делается, состоит в том, чтобы создавать копию styles textarea в одном div, который курсор div был бы span

годом CГіdigo оригинально в GitHub

Я cГіdigo quedarГ - в следующего способа:

$(function(){
  $('textarea').on('keyup',function(evt){
    var pos = getCaretCoordinates(this,this.selectionEnd);
    $('div.dropdown').css({
      'position': 'absolute',
      'top': this.offsetTop - this.scrollTop + 15 + pos.top + 'px',
      'left': this.offsetLeft - this.scrollLeft + pos.left + 'px'
    });
    
  });
  

});
var properties = [
  'boxSizing',
  'width',
  'height',
  'overflowX',
  'overflowY',
  
  'borderTopWidth',
  'borderRightWidth',
  'borderBottomWidth',
  'borderLeftWidth',
  
  'paddingTop',
  'paddingRight',
  'paddingBottom',
  'paddingLeft',
  
  'fontStyle',
  'fontVariant',
  'fontWeight',
  'fontStretch',
  'fontSize',
  'lineHeight',
  'fontFamily',
  
  'textAlign',
  'textTransform',
  'textIndent',
  'textDecoration',
  
  'letterSpacing',
  'wordSpacing'
];

var isFirefox = !(window.mozInnerScreenX == null);
var mirrorDiv, computed, style;

getCaretCoordinates = function (element, position) {
  // clon del textarea en forma de div
  mirrorDiv = document.getElementById(element.nodeName + '--mirror-div');
  if (!mirrorDiv) {
    mirrorDiv = document.createElement('div');
    mirrorDiv.id = element.nodeName + '--mirror-div';//TEXTAREA--mirror-div
    document.body.appendChild(mirrorDiv);
  }
  
  style = mirrorDiv.style;
  computed = getComputedStyle(element);//obtenemos las propiedades del textarea
  
  // estilos por default
  style.whiteSpace = 'pre-wrap';
  style.wordWrap = 'break-word';  // only for textarea-s
  
  // position off-screen
  style.position = 'absolute';  // required to return coordinates properly
  style.top = element.offsetTop + parseInt(computed.borderTopWidth) + 'px';
  style.left = element.offsetLeft + parseInt(computed.borderLeftWidth) + 'px';
  style.visibility = 'hidden';  // no necesitamos que sea visible
  
  // transferir las propiedades al div
  properties.forEach(function (prop) {
    style[prop] = computed[prop];
  });
  
  if (isFirefox) {
    style.width = parseInt(computed.width) - 2 + 'px'  
    // Firefox adds 2 pixels to the padding - https://bugzilla.mozilla.org/show_bug.cgi?id=753662
    // Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275
    if (element.scrollHeight > parseInt(computed.height))
      style.overflowY = 'scroll';
  } else {
    style.overflow = 'hidden';  
    // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'
  }  
  
  mirrorDiv.textContent = element.value.substring(0, position);
  if (element.nodeName === 'INPUT')
    mirrorDiv.textContent = mirrorDiv.textContent.replace(/\s/g, "\u00a0");
  
  var span = document.createElement('span');
  span.textContent = element.value.substring(position) || '.';  
  // obtenemos los valores del textarea y los escribimos en caso que se encuentre texto por delante dentro del span para obtener la posision exacta
  span.style.backgroundColor = "lightgrey";
  mirrorDiv.appendChild(span);
  
  var coordinates = {
    top: span.offsetTop + parseInt(computed['borderTopWidth']),
    left: span.offsetLeft + parseInt(computed['borderLeftWidth'])
  };
  
  return coordinates;
}
textarea{
  border: 2px solid gray;
  height: 100px;
  min-width: 100%;
  max-width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<textarea></textarea>
<textarea></textarea>
<div class="dropdown open">
  <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
    <li><a href="#">Action</a></li>
    <li><a href="#">Another action</a></li>
    <li><a href="#">Something else here</a></li>
    <li role="separator" class="divider"></li>
    <li><a href="#">Separated link</a></li>
  </ul>
</div>
1
ответ дан 24.11.2019, 12:35

Теги

Похожие вопросы