Дисплей Div в положении курсора в Textarea [дубликат] -- javascript поле с участием dom пол Связанный проблема

Display DIV at Cursor Position in Textarea [duplicate]


59
vote

проблема

русский
<в сторону CLASS = "S-NEWACTS S-WELTIVE__info JS-Post-New Imide MB16« Роль = «Статус»>
Этот вопрос уже есть ответы здесь :
Как получить ( X, Y) Пиксельные координаты карета в текстовых полях? (3 ответа)
Закрыто 6 лет назад .

Для моего проекта, который я хотел бы предоставить автоматическое завершение для конкретной текстуарии. Похож на то, как работает IntelliSense / Omnicomede. Для этого, однако я должен выяснить абсолютное положение курсора, чтобы я знал, где должен появиться дивы.

Оказывается: это (почти я надеюсь) невозможно достичь. У кого-нибудь есть некоторые аккуратные идеи, как решить эту проблему?

Английский оригинал

For a project of mine I would love to provide auto completion for a specific textarea. Similar to how intellisense/omnicomplete works. For that however I have to find out the absolute cursor position so that I know where the DIV should appear.

Turns out: that's (nearly I hope) impossible to achieve. Does anyone has some neat ideas how to solve that problem?

</div
     
       
       

Список ответов

35
 
vote

<Сильная> версия 2 моего хакового эксперимента

Эта новая версия работает с каким-либо шрифтом, который можно скорректировать по требованию, и любой размер текстура.

После замечения того, что некоторые из вас все еще пытаются заставить это работать, я решил попробовать новый подход. На этот раз мои результаты намного лучше - по крайней мере, на Google Chrome на Linux. У меня больше нет для меня Windows PC, поэтому я могу проверить только на Chrome / Firefox на Ubuntu. Мои результаты работают 100% последовательно на Chrome, и давайте скажем где-то около 70 - 80% на Firefox, но я не представляю, что было бы невероятно трудно найти несоответствия.

Эта новая версия зависит от объекта Canvas. В моем моем Пример я фактически показываю, что очень холст - просто так вы можете увидеть его в действии, но это могло бы Очень легко сделать с скрытым объектом Canvas.

Это наверное, наверняка взлома, и я предвидясь раньше времени для моего скорее брошенного кода. По крайней мере, в Google Chrome, он работает последовательно, независимо от того, какой шрифт я его установил, или размер текстура. Я использовал Пример Sam Saffron для показать координаты курсора (серый фон Div). Я также добавил ссылку «Randomize», чтобы вы могли видеть его работать в разных размерах и стилях и стилях шрифта / техареи, и посмотреть обновление положения курсора на лету. Я рекомендую смотреть на Полная страница Demo Итак, вы можете лучше увидеть, как можно увидеть компаньон холст.

Я суммирую, как это работает ...

Основная идея состоит в том, что мы пытаемся перерезать текстура на холсте, как можно более тесно. Поскольку браузер использует тот же двигатель шрифта для обоих, так и для Texarea, мы можем использовать функциональность измерений шрифта Canvas для выяснения, где есть все. Оттуда мы можем использовать методы холста, доступные нам, чтобы выяснить наши координаты.

В первую очередь мы корректируем наш холст, чтобы соответствовать размерам Textarea. Это полностью для визуальных целей, поскольку размер холста на самом деле не имеет значения в нашем исходе. Поскольку холст на самом деле не предусматривает средство Word Wrap, я должен был воплотить в воображение (воровать / брать / брать вместе) средство разрыва строк в максимально возможное соответствие текстура. Это то, где вы, вероятно, найдут, вам нужно сделать самые перекрестные браузеры.

После Word Wrap, все остальное - это базовая математика. Мы разделяем линии в массив, чтобы имитировать Word Wrap, и теперь мы хотим петлю через эти линии и пройти весь путь до точки, когда наш текущий выбор заканчивается. Для этого мы просто подсчитаны персонажи и как только мы превзойдем <Код> sqlite30 , мы знаем, что мы пошли достаточно далеко. Умножьте подсчет строки вверх до этой точки с высотой линии, и у вас есть <код> sqlite31 координата.

<Код> sqlite32 координата очень похож, кроме нас, используя <код> sqlite33 . Пока мы печатаем правильное количество символов, которые дадут нам ширину линии, которая тянутся к холсте, что происходит, чтобы закончиться после того, как последний выписанный символ, который является символом перед текущимслом <код> sqlite34 Положение.

При попытке отладить это для других браузеров, вещь для поиска, где строки не нарушаются должным образом. Вы увидите в некоторых местах, что последнее слово на линии в холсте, возможно, обернуто на текстуре или наоборот. Это связано с тем, как браузер обрабатывает Word Wraps. Пока вы получаете упаковку в холсте, чтобы соответствовать текстуарию, ваш курсор должен быть правильным.

Я влюбив источник ниже. Вы должны быть в состоянии скопировать и вставить его, но если вы сделаете, я спрашиваю, что вы загружаете свою собственную копию jQuery-fieldselection вместо того, чтобы ударить на свой сервер.

Я также увеличил Новая демонстрация , а также скрипка .

Удачи!

 <код> sqlite35  

<Сильная> ошибка

Есть одна ошибка, которую я делаю, вспоминаю. Если вы поместите курсор перед первой буквой на строку, она показывает «положение» как последнее письмо на предыдущей строке. Это связано с тем, как выбора. День работа. Я не думаю, что это должно быть слишком сложно искать это дело и исправить его соответственно.


<Сильная> Версия 1

Оставив это здесь, чтобы вы могли видеть прогресс без необходимости копаться через историю редактирования.

Это не идеально, и это, безусловно, это хак, но я получил его, чтобы работать довольно хорошо на WinXP IE, FF, Safari, Chrome и Opera.

Насколько я могу сказать, нет никакого способа напрямую узнать X / Y курсора в любом браузере. IE метод , Упомянутый по jQuery 1.2.6 , jQuery-fieldselections и jQuery-размеры

Демо: http://enobrev.info/cursor/

и код:

 <код> sqlite33  

 

Version 2 of My Hacky Experiment

This new version works with any font, which can be adjusted on demand, and any textarea size.

After noticing that some of you are still trying to get this to work, I decided to try a new approach. My results are FAR better this time around - at least on google chrome on linux. I no longer have a windows PC available to me, so I can only test on chrome / firefox on Ubuntu. My results work 100% consistently on Chrome, and let's say somewhere around 70 - 80% on Firefox, but I don't imagine it would be incredibly difficult to find the inconsistencies.

This new version relies on a Canvas object. In my example, I actually show that very canvas - just so you can see it in action, but it could very easily be done with a hidden canvas object.

This is most certainly a hack, and I apologize ahead of time for my rather thrown together code. At the very least, in google chrome, it works consistently, no matter what font I set it to, or size of textarea. I used Sam Saffron's example to show cursor coordinates (a gray-background div). I also added a "Randomize" link, so you can see it work in different font / texarea sizes and styles, and watch the cursor position update on the fly. I recommend looking at the full page demo so you can better see the companion canvas play along.

I'll summarize how it works...

The underlying idea is that we're trying to redraw the textarea on a canvas, as closely as possible. Since the browser uses the same font engine for both and texarea, we can use canvas's font measurement functionality to figure out where things are. From there, we can use the canvas methods available to us to figure out our coordinates.

First and foremost, we adjust our canvas to match the dimensions of the textarea. This is entirely for visual purposes since the canvas size doesn't really make a difference in our outcome. Since Canvas doesn't actually provide a means of word wrap, I had to conjure (steal / borrow / munge together) a means of breaking up lines to as-best-as-possible match the textarea. This is where you'll likely find you need to do the most cross-browser tweaking.

After word wrap, everything else is basic math. We split the lines into an array to mimic the word wrap, and now we want to loop through those lines and go all the way down until the point where our current selection ends. In order to do that, we're just counting characters and once we surpass selection.end, we know we have gone down far enough. Multiply the line count up until that point with the line-height and you have a y coordinate.

The x coordinate is very similar, except we're using context.measureText. As long as we're printing out the right number of characters, that will give us the width of the line that's being drawn to Canvas, which happens to end after the last character written out, which is the character before the currentl selection.end position.

When trying to debug this for other browsers, the thing to look for is where the lines don't break properly. You'll see in some places that the last word on a line in canvas may have wrapped over on the textarea or vice-versa. This has to do with how the browser handles word wraps. As long as you get the wrapping in the canvas to match the textarea, your cursor should be correct.

I'll paste the source below. You should be able to copy and paste it, but if you do, I ask that you download your own copy of jquery-fieldselection instead of hitting the one on my server.

I've also upped a new demo as well as a fiddle.

Good luck!

<!DOCTYPE html> <html lang="en-US">     <head>         <meta charset="utf-8" />         <title>Tooltip 2</title>         <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>         <script type="text/javascript" src="http://enobrev.info/cursor/js/jquery-fieldselection.js"></script>         <style type="text/css">             form {                 float: left;                 margin: 20px;             }              #textariffic {                 height: 400px;                 width: 300px;                 font-size: 12px;                 font-family: 'Arial';                 line-height: 12px;             }              #tip {                 width:5px;                 height:30px;                 background-color: #777;                 position: absolute;                 z-index:10000             }              #mock-text {                 float: left;                 margin: 20px;                 border: 1px inset #ccc;             }              /* way the hell off screen */             .scrollbar-measure {                 width: 100px;                 height: 100px;                 overflow: scroll;                 position: absolute;                 top: -9999px;             }              #randomize {                 float: left;                 display: block;             }         </style>         <script type="text/javascript">             var oCanvas;             var oTextArea;             var $oTextArea;             var iScrollWidth;              $(function() {                 iScrollWidth = scrollMeasure();                 oCanvas      = document.getElementById('mock-text');                 oTextArea    = document.getElementById('textariffic');                 $oTextArea   = $(oTextArea);                  $oTextArea                         .keyup(update)                         .mouseup(update)                         .scroll(update);                  $('#randomize').bind('click', randomize);                  update();             });              function randomize() {                 var aFonts      = ['Arial', 'Arial Black', 'Comic Sans MS', 'Courier New', 'Impact', 'Times New Roman', 'Verdana', 'Webdings'];                 var iFont       = Math.floor(Math.random() * aFonts.length);                 var iWidth      = Math.floor(Math.random() * 500) + 300;                 var iHeight     = Math.floor(Math.random() * 500) + 300;                 var iFontSize   = Math.floor(Math.random() * 18)  + 10;                 var iLineHeight = Math.floor(Math.random() * 18)  + 10;                  var oCSS = {                     'font-family':  aFonts[iFont],                     width:          iWidth + 'px',                     height:         iHeight + 'px',                     'font-size':    iFontSize + 'px',                     'line-height':  iLineHeight + 'px'                 };                  console.log(oCSS);                  $oTextArea.css(oCSS);                  update();                 return false;             }              function showTip(x, y) {                 $('#tip').css({                       left: x + 'px',                       top: y + 'px'                   });             }              // https://stackoverflow.com/a/11124580/14651             // https://stackoverflow.com/a/3960916/14651              function wordWrap(oContext, text, maxWidth) {                 var aSplit = text.split(' ');                 var aLines = [];                 var sLine  = "";                  // Split words by newlines                 var aWords = [];                 for (var i in aSplit) {                     var aWord = aSplit[i].split(' ');                     if (aWord.length > 1) {                         for (var j in aWord) {                             aWords.push(aWord[j]);                             aWords.push(" ");                         }                          aWords.pop();                     } else {                         aWords.push(aSplit[i]);                     }                 }                  while (aWords.length > 0) {                     var sWord = aWords[0];                     if (sWord == " ") {                         aLines.push(sLine);                         aWords.shift();                         sLine = "";                     } else {                         // Break up work longer than max width                         var iItemWidth = oContext.measureText(sWord).width;                         if (iItemWidth > maxWidth) {                             var sContinuous = '';                             var iWidth = 0;                             while (iWidth <= maxWidth) {                                 var sNextLetter = sWord.substring(0, 1);                                 var iNextWidth  = oContext.measureText(sContinuous + sNextLetter).width;                                 if (iNextWidth <= maxWidth) {                                     sContinuous += sNextLetter;                                     sWord = sWord.substring(1);                                 }                                 iWidth = iNextWidth;                             }                             aWords.unshift(sContinuous);                         }                          // Extra space after word for mozilla and ie                         var sWithSpace = (jQuery.browser.mozilla || jQuery.browser.msie) ? ' ' : '';                         var iNewLineWidth = oContext.measureText(sLine + sWord + sWithSpace).width;                         if (iNewLineWidth <= maxWidth) {  // word fits on current line to add it and carry on                             sLine += aWords.shift() + " ";                         } else {                             aLines.push(sLine);                             sLine = "";                         }                          if (aWords.length === 0) {                             aLines.push(sLine);                         }                     }                 }                 return aLines;             }              // http://davidwalsh.name/detect-scrollbar-width             function scrollMeasure() {                 // Create the measurement node                 var scrollDiv = document.createElement("div");                 scrollDiv.className = "scrollbar-measure";                 document.body.appendChild(scrollDiv);                  // Get the scrollbar width                 var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;                  // Delete the DIV                 document.body.removeChild(scrollDiv);                  return scrollbarWidth;             }              function update() {                 var oPosition  = $oTextArea.position();                 var sContent   = $oTextArea.val();                 var oSelection = $oTextArea.getSelection();                  oCanvas.width  = $oTextArea.width();                 oCanvas.height = $oTextArea.height();                  var oContext    = oCanvas.getContext("2d");                 var sFontSize   = $oTextArea.css('font-size');                 var sLineHeight = $oTextArea.css('line-height');                 var fontSize    = parseFloat(sFontSize.replace(/[^0-9.]/g, ''));                 var lineHeight  = parseFloat(sLineHeight.replace(/[^0-9.]/g, ''));                 var sFont       = [$oTextArea.css('font-weight'), sFontSize + '/' + sLineHeight, $oTextArea.css('font-family')].join(' ');                  var iSubtractScrollWidth = oTextArea.clientHeight < oTextArea.scrollHeight ? iScrollWidth : 0;                  oContext.save();                 oContext.clearRect(0, 0, oCanvas.width, oCanvas.height);                 oContext.font = sFont;                 var aLines = wordWrap(oContext, sContent, oCanvas.width - iSubtractScrollWidth);                  var x = 0;                 var y = 0;                 var iGoal = oSelection.end;                 aLines.forEach(function(sLine, i) {                     if (iGoal > 0) {                         oContext.fillText(sLine.substring(0, iGoal), 0, (i + 1) * lineHeight);                          x = oContext.measureText(sLine.substring(0, iGoal + 1)).width;                         y = i * lineHeight - oTextArea.scrollTop;                          var iLineLength = sLine.length;                         if (iLineLength == 0) {                             iLineLength = 1;                         }                          iGoal -= iLineLength;                     } else {                         // after                     }                 });                 oContext.restore();                  showTip(oPosition.left + x, oPosition.top + y);             }          </script>     </head>     <body>          <a href="#" id="randomize">Randomize</a>          <form id="tipper">             <textarea id="textariffic">Aliquam urna. Nullam augue dolor, tincidunt condimentum, malesuada quis, ultrices at, arcu. Aliquam nunc pede, convallis auctor, sodales eget, aliquam eget, ligula. Proin nisi lacus, scelerisque nec, aliquam vel, dictum mattis, eros. Curabitur et neque. Fusce sollicitudin. Quisque at risus. Suspendisse potenti. Mauris nisi. Sed sed enim nec dui viverra congue. Phasellus velit sapien, porttitor vitae, blandit volutpat, interdum vel, enim. Cras sagittis bibendum neque. Proin eu est. Fusce arcu. Aliquam elit nisi, malesuada eget, dignissim sed, ultricies vel, purus. Maecenas accumsan diam id nisi.  Phasellus et nunc. Vivamus sem felis, dignissim non, lacinia id, accumsan quis, ligula. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed scelerisque nulla sit amet mi. Nulla consequat, elit vitae tempus vulputate, sem libero rhoncus leo, vulputate viverra nulla purus nec turpis. Nam turpis sem, tincidunt non, congue lobortis, fermentum a, ipsum. Nulla facilisi. Aenean facilisis. Maecenas a quam eu nibh lacinia ultricies. Morbi malesuada orci quis tellus.  Sed eu leo. Donec in turpis. Donec non neque nec ante tincidunt posuere. Pellentesque blandit. Ut vehicula vestibulum risus. Maecenas commodo placerat est. Integer massa nunc, luctus at, accumsan non, pulvinar sed, odio. Pellentesque eget libero iaculis dui iaculis vehicula. Curabitur quis nulla vel felis ullamcorper varius. Sed suscipit pulvinar lectus.</textarea>          </form>          <div id="tip"></div>          <canvas id="mock-text"></canvas>     </body> </html> 

Bug

There's one bug I do recall. If you put the cursor before the first letter on a line, it shows the "position" as the last letter on the previous line. This has to do with how selection.end work. I don't think it should be too difficult to look for that case and fix it accordingly.


Version 1

Leaving this here so you can see the progress without having to dig through the edit history.

It's not perfect and it's most Definitely a hack, but I got it to work pretty well on WinXP IE, FF, Safari, Chrome and Opera.

As far as I can tell there's no way to directly find out the x/y of a cursor on any browser. The IE method, mentioned by Adam Bellaire is interesting, but unfortunately not cross-browser. I figured the next best thing would be to use the characters as a grid.

Unfortunately there's no font metric information built into any of the browsers, which means a monospace font is the only font type that's going to have a consistent measurement. Also, there's no reliable means of figuring out a font-width from the font-height. At first I'd tried using a percentage of the height, which worked great. Then I changed the font-size and everything went to hell.

I tried one method to figure out character width, which was to create a temporary textarea and keep adding characters until the scrollHeight (or scrollWidth) changed. It seems plausable, but about halfway down that road, I realized I could just use the cols attribute on the textarea and figured there are enough hacks in this ordeal to add another one. This means you can't set the width of the textarea via css. You HAVE to use the cols for this to work.

The next problem I ran into is that, even when you set the font via css, the browsers report the font differently. When you don't set a font, mozilla uses monospace by default, IE uses Courier New, Opera "Courier New" (with quotes), Safari, 'Lucida Grand' (with single quotes). When you do set the font to monospace, mozilla and ie take what you give them, Safari comes out as -webkit-monospace and Opera stays with "Courier New".

So now we initialize some vars. Make sure to set your line height in the css as well. Firefox reports the correct line height, but IE was reporting "normal" and I didn't bother with the other browsers. I just set the line height in my css and that resolved the difference. I haven't tested with using ems instead of pixels. Char height is just font size. Should probably pre-set that in your css as well.

Also, one more pre-setting before we start placing characters - which really had me scratching my head. For ie and mozilla, texarea chars are < cols, everything else is <= chars. So Chrome can fit 50 chars across, but mozilla and ie would break the last word off the line.

Now we're going to create an array of first-character positions for every line. We loop through every char in the textarea. If it's a newline, we add a new position to our line array. If it's a space, we try to figure out if the current "word" will fit on the line we're on or if it's going to get pushed to the next line. Punctuation counts as a part of the "word". I haven't tested with tabs, but there's a line there for adding 4 chars for a tab char.

Once we have an array of line positions, we loop through and try to find which line the cursor is on. We're using hte "End" of the selection as our cursor.

x = (cursor position - first character position of cursor line) * character width

y = ((cursor line + 1) * line height) - scroll position

I'm using jquery 1.2.6, jquery-fieldselection, and jquery-dimensions

The Demo: http://enobrev.info/cursor/

And the code:

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml">     <head>         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />         <title>Tooltip</title>         <script type="text/javascript" src="js/jquery-1.2.6.js"></script>         <script type="text/javascript" src="js/jquery-fieldselection.js"></script>         <script type="text/javascript" src="js/jquery.dimensions.js"></script>         <style type="text/css">             form {                 margin: 20px auto;                 width: 500px;             }              #textariffic {                 height: 400px;                 font-size: 12px;                 font-family: monospace;                 line-height: 15px;             }              #tip {                 position: absolute;                 z-index: 2;                 padding: 20px;                 border: 1px solid #000;                 background-color: #FFF;             }         </style>         <script type="text/javascript">             $(function() {                 $('textarea')                     .keyup(update)                     .mouseup(update)                     .scroll(update);             });              function showTip(x, y) {                                 y = y + $('#tip').height();                  $('#tip').css({                     left: x + 'px',                     top: y + 'px'                 });             }              function update() {                 var oPosition = $(this).position();                 var sContent = $(this).val();                  var bGTE = jQuery.browser.mozilla || jQuery.browser.msie;                  if ($(this).css('font-family') == 'monospace'           // mozilla                 ||  $(this).css('font-family') == '-webkit-monospace'   // Safari                 ||  $(this).css('font-family') == '"Courier New"') {    // Opera                     var lineHeight   = $(this).css('line-height').replace(/[^0-9]/g, '');                         lineHeight   = parseFloat(lineHeight);                     var charsPerLine = this.cols;                     var charWidth    = parseFloat($(this).innerWidth() / charsPerLine);                       var iChar = 0;                     var iLines = 1;                     var sWord = '';                      var oSelection = $(this).getSelection();                     var aLetters = sContent.split("");                     var aLines = [];                      for (var w in aLetters) {                         if (aLetters[w] == " ") {                             iChar = 0;                             aLines.push(w);                             sWord = '';                         } else if (aLetters[w] == " ") {                                 var wordLength = parseInt(sWord.length);                               if ((bGTE && iChar + wordLength >= charsPerLine)                             || (!bGTE && iChar + wordLength > charsPerLine)) {                                 iChar = wordLength + 1;                                 aLines.push(w - wordLength);                             } else {                                                 iChar += wordLength + 1; // 1 more char for the space                             }                              sWord = '';                         } else if (aLetters[w] == " ") {                             iChar += 4;                         } else {                             sWord += aLetters[w];                              }                     }                      var iLine = 1;                     for(var i in aLines) {                         if (oSelection.end < aLines[i]) {                             iLine = parseInt(i) - 1;                             break;                         }                     }                      if (iLine > -1) {                         var x = parseInt(oSelection.end - aLines[iLine]) * charWidth;                     } else {                         var x = parseInt(oSelection.end) * charWidth;                     }                     var y = (iLine + 1) * lineHeight - this.scrollTop; // below line                      showTip(oPosition.left + x, oPosition.top + y);                 }             }          </script>     </head>     <body>         <form id="tipper">             <textarea id="textariffic" cols="50"> Aliquam urna. Nullam augue dolor, tincidunt condimentum, malesuada quis, ultrices at, arcu. Aliquam nunc pede, convallis auctor, sodales eget, aliquam eget, ligula. Proin nisi lacus, scelerisque nec, aliquam vel, dictum mattis, eros. Curabitur et neque. Fusce sollicitudin. Quisque at risus. Suspendisse potenti. Mauris nisi. Sed sed enim nec dui viverra congue. Phasellus velit sapien, porttitor vitae, blandit volutpat, interdum vel, enim. Cras sagittis bibendum neque. Proin eu est. Fusce arcu. Aliquam elit nisi, malesuada eget, dignissim sed, ultricies vel, purus. Maecenas accumsan diam id nisi.  Phasellus et nunc. Vivamus sem felis, dignissim non, lacinia id, accumsan quis, ligula. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed scelerisque nulla sit amet mi. Nulla consequat, elit vitae tempus vulputate, sem libero rhoncus leo, vulputate viverra nulla purus nec turpis. Nam turpis sem, tincidunt non, congue lobortis, fermentum a, ipsum. Nulla facilisi. Aenean facilisis. Maecenas a quam eu nibh lacinia ultricies. Morbi malesuada orci quis tellus.  Sed eu leo. Donec in turpis. Donec non neque nec ante tincidunt posuere. Pellentesque blandit. Ut vehicula vestibulum risus. Maecenas commodo placerat est. Integer massa nunc, luctus at, accumsan non, pulvinar sed, odio. Pellentesque eget libero iaculis dui iaculis vehicula. Curabitur quis nulla vel felis ullamcorper varius. Sed suscipit pulvinar lectus.              </textarea>          </form>          <p id="tip">Here I Am!!</p>     </body> </html> 
</div
 
 
         
         
4
 
vote

Я опубликовал тему, связанную с этой проблемой на российском сайте JavaScript.

Если вы не понимаете, что русская попытка переведена в Google версии: http://translate.google.ru/translate?js=y&aMpprev=_t&hl=ru&ie=1&amp-8&layout=1&eotf=1&u=http: //javascript.ru/forum/events/7771-poluchit-koordinaty-kursora-v-tekstovom-pole-v-pikselyakh.html&sl=ru&ttl=en

THRE - некоторые проблемы разметки в примерах кода в переведенной версии, чтобы вы могли Прочитайте код в оригинальном российском посте .

Идея проста. Нет простого, универсального и перекрестного браузера для получения положения курсора в пикселях. Честно говоря, говоря, но только для Internet Explorer.

В других браузерах, если вам действительно нужно рассчитать его, вы должны ...

    .
  • Создать невидимый div
  • Скопируйте все стили и содержание текстового поля в этот div
  • Затем вставьте элемент HTML в той же позиции в тексте, где CARET находится в текстовом поле
  • Получить координаты этого HTML-элемента

 

I posted a topic related to this problem on a Russian JavaScript site.

If you don't understand Russian try translated by Google version: http://translate.google.ru/translate?js=y&prev=_t&hl=ru&ie=UTF-8&layout=1&eotf=1&u=http://javascript.ru/forum/events/7771-poluchit-koordinaty-kursora-v-tekstovom-pole-v-pikselyakh.html&sl=ru&tl=en

Thre is some markup issues in the code examples in translated version so you can read the code in the original Russian post.

The idea is simple. There is no easy, universal and cross-browser method to get cursor position in pixels. Frankly speaking there is, but only for Internet Explorer.

In other browsers if you do really need to calculate it you have to ...

  • create an invisible DIV
  • copy all styles and content of the text box into that DIV
  • then insert HTML element at exactly the same position in text where the caret is in the text box
  • get coordinates of that HTML element
</div
 
 
 
 
4
 
vote

Я не буду объяснять проблемы, связанные с этим, потому что они хорошо объяснены на других постах. Просто указываю на возможное решение, у него есть некоторая ошибка, но это отправная точка.

К счастью, на Github есть сценария для расчета позиции Caret относительно его контейнера, но это требует jQuery. page github Вот: jquery-caret-position-getter, спасибо в Бевис.Жао.

На основании этого я реализовал следующий код: Проверьте его в действии Здесь в jsfiddle.net / a>

 <код> sqlite34  
 

I won't explain the problems related to this stuff again because they are well explained in other posts. Just will point a possible solution, it has some bug but it's a starting point.

Fortunately there is a scrip on Github to calculate the caret position relative to it's container, but it requires jQuery. GitHub page here: jquery-caret-position-getter, Thanxs to Bevis.Zhao.

Based on it I have implemented the next code: check it in action here in jsFiddle.net

<html><head>     <meta http-equiv="content-type" content="text/html; charset=UTF-8">     <title>- jsFiddle demo by mjerez</title>     <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.js"></script>     <link rel="stylesheet" type="text/css" href="http://jsfiddle.net/css/normalize.css">     <link rel="stylesheet" type="text/css" href="http://jsfiddle.net/css/result-light.css">        <script type="text/javascript" src="https://raw.github.com/beviz/jquery-caret-position-getter/master/jquery.caretposition.js"></script>          <style type="text/css">         body{position:relative;font:normal 100% Verdana, Geneva, sans-serif;padding:10px;}         .aux{background:#ccc;opacity: 0.5;width:50%;padding:5px;border:solid 1px #aaa;}         .hidden{display:none}         .show{display:block; position:absolute; top:0px; left:0px;}     </style>     <script type="text/javascript">//<![CDATA[      $(document).keypress(function(e) {         if ($(e.target).is('input, textarea')) {             var key = String.fromCharCode(e.which);             var ctrl = e.ctrlKey;             if (ctrl) {                 var display = $("#autocomplete");                 var editArea = $('#editArea');                             var pos = editArea.getCaretPosition();                 var offset = editArea.offset();                 // now you can use left, top(they are relative position)                 display.css({                     left: offset.left + pos.left,                     top:  offset.top + pos.top,                     color : "#449"                 })                 display.toggleClass("show");                 return false;             }         }      });     window.onload = (function() {         $("#editArea").blur(function() {             if ($("#autocomplete").hasClass("show")) $("#autocomplete").toggleClass("show");         })     });     //]]>       </script> </head> <body>     <p>Click ctrl+space to while you write to diplay the autocmplete pannel.</p>     </br>     <textarea id="editArea" rows="4" cols="50"></textarea>     </br>     </br>     </br>     <div id="autocomplete" class="aux hidden ">         <ol>             <li>Option a</li>             <li>Option b</li>             <li>Option c</li>             <li>Option d</li>         </ol>     </div> </body> 
</div
 
 
 
 
4
 
vote
<Р> Обратите внимание, что этот вопрос является дубликатом один спросил месяц назад, и я ответил <сильный> здесь . Я буду только поддерживать ответ на эту ссылку, так как этот вопрос должен был быть закрыт, как дублирующие лет назад.

Копия ответа

<Р> Я искал текстовой каретка координаты плагин для метеор автозаполнения , поэтому я «ве оценили все 8 плагинов на GitHub. Побеждает, безусловно, TextArea-каретка-позиционным от Компонент < / STRONG>.

Особенности

    . <Литий> точность пикселей
  • нет зависимостей вообще
  • Совместимость браузера: Chrome, Safari, Firefox (несмотря на два <а HREF = "https://bugzilla.mozilla.org/show_bug.cgi?id=984275" отн = "NOFOLLOW noreferrer"> ошибки
он имеет), IE9 +; может работать, но не протестированы в Opera, IE8 или старшем
  • поддерживает любую семью и размер шрифта, а также текст-преобразования
  • текстовая область может иметь произвольное заполнение или границы
  • <Литий> не путать с помощью горизонтальных или вертикальных полос прокрутки в текстовое поле
  • поддерживает жесткие переносы, вкладки (за исключением на IE) и последовательных пробелов в тексте
  • Правильное положение на линии дольше, чем столбцов в текстовой области
  • положение
  • нет «призрак» в пустом пространстве
  • в конце строки, когда упаковка длинных слов

    Вот демо - http://jsfiddle.net/dandv/aFPA7/

    Как это работает

    <Р> зеркало <код> <div> создается вне экрана и стиль так же, как <код> <textarea> . Затем текст текстового поля до каретки копируется в DIV и <код> <span> вставляются сразу после него. Затем, текстовое содержание пролета устанавливаются в оставшуюся части текста в текстовом поле для того, чтобы точно воспроизвести обертку в поддельных делах. <Р> Это единственный способ гарантированно обработать все случаи края, имеющие отношение к оберточной длинных линий. Он также используется GitHub для определения положения его <сильный> @ пользователя в раскрывающемся списке.
     

    Note that this question is a duplicate of a one asked a month earlier, and I've answered it here. I'll only maintain the answer at that link, since this question should have been closed as duplicate years ago.

    Copy of the answer

    I've looked for a textarea caret coordinates plugin for meteor-autocomplete, so I've evaluated all the 8 plugins on GitHub. The winner is, by far, textarea-caret-position from Component.

    Features

    • pixel precision
    • no dependencies whatsoever
    • browser compatibility: Chrome, Safari, Firefox (despite two bugs it has), IE9+; may work but not tested in Opera, IE8 or older
    • supports any font family and size, as well as text-transforms
    • the text area can have arbitrary padding or borders
    • not confused by horizontal or vertical scrollbars in the textarea
    • supports hard returns, tabs (except on IE) and consecutive spaces in the text
    • correct position on lines longer than the columns in the text area
    • no "ghost" position in the empty space at the end of a line when wrapping long words

    Here's a demo - http://jsfiddle.net/dandv/aFPA7/

    enter image description here

    How it works

    A mirror <div> is created off-screen and styled exactly like the <textarea>. Then, the text of the textarea up to the caret is copied into the div and a <span> is inserted right after it. Then, the text content of the span is set to the remainder of the text in the textarea, in order to faithfully reproduce the wrapping in the faux div.

    This is the only method guaranteed to handle all the edge cases pertaining to wrapping long lines. It's also used by GitHub to determine the position of its @ user dropdown.

    </div
     
     
     
     
    1
     
    vote
    <Р> Это блог оказывается близким тоже ответить на вопрос. Я не пробовал мой сам, но автор утверждает, что его испытания с FF3, Chrome, IE, Opera, Safari. Код на GitHub
     

    This blog appears to be close too answering the question. I haven't tried it my self, but author says its tested with FF3, Chrome, IE, Opera, Safari. Code is on GitHub

    </div
     
     
         
         
    1
     
    vote
    <Р> установил его здесь: http://jsfiddle.net/eMwKd/4/ <Р> Единственным недостатком является то, что уже при условии, функция <код> getCaret() рассасывается в неправильном положении на клавишу. для этого красного курсора, кажется, за реальный курсором, если вы не отпустите кнопку. <Р> у меня будет еще заглянуть в него. <Р> обновление: гм, слово-упаковка не является точным, если слишком длинные строки ..
     

    fixed it here: http://jsfiddle.net/eMwKd/4/

    only downside is that the already provided function getCaret() resolves to the wrong position on key down. therefor the red cursor seems to be behind the real cursor unless you release the key.

    I will have another look into it.

    update: hm, word-wrapping is not accurate if lines too long..

    </div
     
     
             
             
    0
     
    vote

    Это Пост в блоге, похоже, решает ваш вопрос, но, к сожалению, автор признает, что он только проверил его в IE 6.

    Дом в IE не предоставляет информации о относительной позиции с точки зрения персонажей; Однако он обеспечивает ограничение и смещение значений для браузера. Таким образом, я использовал эти значения, чтобы определить относительные границы характера. Затем, используя JavaScript Textrange, я создал механизм для работы с такими мерами для расчета позиции линии и столбца для шрифтов фиксированной ширины в данной Textarea.

    Во-первых, относительные границы для текстуарии должны быть рассчитаны на основе размера используемого шрифта фиксированного ширины. Для этого исходное значение Textarea должно храниться в локальной переменной JavaScript и очистить значение. Затем Textrange создается для определения верхних и левых границ текстуарии.

     

    This blog post seems to address your question, but unfortunately the author admits he has only tested it in IE 6.

    The DOM in IE does not provide information regarding relative position in terms of characters; however, it does provide bounding and offset values for browser-rendered controls. Thus, I used these values to determine the relative bounds of a character. Then, using the JavaScript TextRange, I created a mechanism for working with such measures to calculate the Line and Column position for fixed-width fonts within a given TextArea.

    First, the relative bounds for the TextArea must be calculated based upon the size of the fixed-width font used. To do this, the original value of the TextArea must be stored in a local JavaScript variable and clear the value. Then, a TextRange is created to determine the Top and Left bounds of the TextArea.

    </div
     
     
    0
     
    vote

    Может быть, это порадует вас, он расскажет вам позицию выбора и позитивность курсора, поэтому попробуйте проверить таймер, чтобы получить автоматическую позицию или снизить флажок, чтобы получить позицию, нажав кнопку «Получить»

     <код>    <form>  <p>  <input type="button" onclick="evalOnce();" value="Get Selection"> timer: <input id="eval_switch" type="checkbox" onclick="evalSwitchClicked(this)"> <input id="eval_time" type="text" value="200" size="6"> ms </p> <textarea id="code" cols="50" rows="20">01234567890123456789012345678901234567890123456789 01234567890123456789012345678901234567890123456789 01234567890123456789012345678901234567890123456789 01234567890123456789012345678901234567890123456789 01234567890123456789012345678901234567890123456789 Sample text area. Please select above text. </textarea> <textarea id="out" cols="50" rows="20"></textarea> </form> <div id="test"></div> <script>  function Selection(textareaElement) { this.element = textareaElement; } Selection.prototype.create = function() { if (document.selection != null && this.element.selectionStart == null) { return this._ieGetSelection(); } else { return this._mozillaGetSelection(); } } Selection.prototype._mozillaGetSelection = function() { return { start: this.element.selectionStart, end: this.element.selectionEnd  };  } Selection.prototype._ieGetSelection = function() { this.element.focus(); var range = document.selection.createRange(); var bookmark = range.getBookmark(); var contents = this.element.value; var originalContents = contents; var marker = this._createSelectionMarker(); while(contents.indexOf(marker) != -1) { marker = this._createSelectionMarker();  } var parent = range.parentElement(); if (parent == null || parent.type != "textarea") { return { start: 0, end: 0 }; } range.text = marker + range.text + marker; contents = this.element.value; var result = {}; result.start = contents.indexOf(marker); contents = contents.replace(marker, ""); result.end = contents.indexOf(marker); this.element.value = originalContents; range.moveToBookmark(bookmark); range.select(); return result; } Selection.prototype._createSelectionMarker = function() { return "##SELECTION_MARKER_" + Math.random() + "##"; }  var timer; var buffer = ""; function evalSwitchClicked(e) { if (e.checked) { evalStart(); } else { evalStop(); } } function evalStart() { var o = document.getElementById("eval_time"); timer = setTimeout(timerHandler, o.value); } function evalStop() { clearTimeout(timer); } function timerHandler() { clearTimeout(timer); var sw = document.getElementById("eval_switch"); if (sw.checked) { evalOnce(); evalStart(); } } function evalOnce() { try { var selection = new Selection(document.getElementById("code")); var s = selection.create(); var result = s.start + ":" + s.end; buffer += result; flush();  } catch (ex) { buffer = ex; flush(); } } function getCode() { // var s.create() // return document.getElementById("code").value; } function clear() { var out = document.getElementById("out"); out.value = ""; } function print(str) { buffer += str + " "; } function flush() { var out = document.getElementById("out"); out.value = buffer; buffer = "";  }  </script>   

    Смотрите демонстрацию здесь: jsbin.com

     

    maybe this will please you , it will tell the position of selection and the positition of the cursor so try to check the timer to get automatic position or uncheck to get position by clicking on Get Selection button

       <form>  <p>  <input type="button" onclick="evalOnce();" value="Get Selection"> timer: <input id="eval_switch" type="checkbox" onclick="evalSwitchClicked(this)"> <input id="eval_time" type="text" value="200" size="6"> ms </p> <textarea id="code" cols="50" rows="20">01234567890123456789012345678901234567890123456789 01234567890123456789012345678901234567890123456789 01234567890123456789012345678901234567890123456789 01234567890123456789012345678901234567890123456789 01234567890123456789012345678901234567890123456789 Sample text area. Please select above text. </textarea> <textarea id="out" cols="50" rows="20"></textarea> </form> <div id="test"></div> <script>  function Selection(textareaElement) { this.element = textareaElement; } Selection.prototype.create = function() { if (document.selection != null && this.element.selectionStart == null) { return this._ieGetSelection(); } else { return this._mozillaGetSelection(); } } Selection.prototype._mozillaGetSelection = function() { return { start: this.element.selectionStart, end: this.element.selectionEnd  };  } Selection.prototype._ieGetSelection = function() { this.element.focus(); var range = document.selection.createRange(); var bookmark = range.getBookmark(); var contents = this.element.value; var originalContents = contents; var marker = this._createSelectionMarker(); while(contents.indexOf(marker) != -1) { marker = this._createSelectionMarker();  } var parent = range.parentElement(); if (parent == null || parent.type != "textarea") { return { start: 0, end: 0 }; } range.text = marker + range.text + marker; contents = this.element.value; var result = {}; result.start = contents.indexOf(marker); contents = contents.replace(marker, ""); result.end = contents.indexOf(marker); this.element.value = originalContents; range.moveToBookmark(bookmark); range.select(); return result; } Selection.prototype._createSelectionMarker = function() { return "##SELECTION_MARKER_" + Math.random() + "##"; }  var timer; var buffer = ""; function evalSwitchClicked(e) { if (e.checked) { evalStart(); } else { evalStop(); } } function evalStart() { var o = document.getElementById("eval_time"); timer = setTimeout(timerHandler, o.value); } function evalStop() { clearTimeout(timer); } function timerHandler() { clearTimeout(timer); var sw = document.getElementById("eval_switch"); if (sw.checked) { evalOnce(); evalStart(); } } function evalOnce() { try { var selection = new Selection(document.getElementById("code")); var s = selection.create(); var result = s.start + ":" + s.end; buffer += result; flush();  } catch (ex) { buffer = ex; flush(); } } function getCode() { // var s.create() // return document.getElementById("code").value; } function clear() { var out = document.getElementById("out"); out.value = ""; } function print(str) { buffer += str + " "; } function flush() { var out = document.getElementById("out"); out.value = buffer; buffer = "";  }  </script> 

    look the demo here : jsbin.com

    </div
     
     
     
     
    0
     
    vote

    Я не знаю решение для textarea , но он уверен, что работает для <код> div с contenteditable .

    Вы можете использовать <код> Range API. Вроде так: (да, вам действительно нужно только эти 3 строки кода)

     <код> // get active selection var selection = window.getSelection(); // get the range (you might want to check selection.rangeCount // to see if it's popuplated) var range = selection.getRangeAt(0);  // will give you top, left, width, height console.log(range.getBoundingClientRect());   

    Я не уверен в совместимости браузера, но я обнаружил, что работает в новейшем Chrome, Firefox и даже IE7 (я думаю, что я проверен 7, в противном случае это было 9).

    Вы можете даже сделать «сумасшедшие» такие вещи, как это: если вы печатаете <код> "#hash" и курсор на последнем <код> h , вы можете посмотреть в текущий диапазон Для # символ переместите диапазон обратно n символов и получите ограничение rect-rect-rect этого диапазона, это сделает popup-div кажется «придерживаться» к слову.

    Один незначительный недостаток заключается в том, что <код> textarea0 иногда может быть немного багги. Курсор любит ходить на невозможные места, и теперь вы должны иметь дело с входом HTML. Но я уверен, что поставщики браузера будут решать эти проблемы, начиная с ними сайтов.

    Другой совет, который я могу дать: посмотреть на <код> textarea1 Библиотека. Он пытается стать полностью представленным поперечным совместимым библиотекой диапазона. Вы не нуждаетесь в это, но если вы имеете дело со старыми браузерами, это может стоить вам.

     

    I don't know a solution for textarea but it sure works for a div with contenteditable.

    You can use the Range API. Like so: (yes, you really only need just these 3 lines of code)

    // get active selection var selection = window.getSelection(); // get the range (you might want to check selection.rangeCount // to see if it's popuplated) var range = selection.getRangeAt(0);  // will give you top, left, width, height console.log(range.getBoundingClientRect()); 

    I'm not sure about browser compatibility but I've found it works in the latest Chrome, Firefox and even IE7 (I think I tested 7, otherwise it was 9).

    You can even do 'crazy' things like this: if you're typing "#hash" and the cursor is at the last h, you can look in the current range for the # character, move the range back by n characters and get the bounding-rect of that range, this will make the popup-div seem to 'stick' to the word.

    One minor drawback is that contenteditable can be a bit buggy sometimes. The cursor likes to go to impossible places and you now have to deal with HTML input. But I'm sure browser vendors will address these problems are more sites starting using them.

    Another tip I can give is: look at the rangy library. It attempts to be a fully featured cross-compatible range library. You don't need it, but if you're dealing with old browsers it might be worth you while.

    </div
     
     
    0
     
    vote

    Есть описание одного взлома для офсет CARET: Координаты Textarea X / Y Caret - jQuery Plugin

    Также будет лучше использовать элемент div с textarea2 атрибутом, если вы можете использовать функции HTML5.

     

    There is description of one hack for caret offset: Textarea X/Y caret coordinates - jQuery plugin

    Also it will be better to use div element with contenteditable attribute if you can use html5 features.

    </div
     
     
    -1
     
    vote

    Как насчет добавления элемента промежутка к клонированию div и установка поддельного курсора на основе этого промежутка на основе этого пролета? Я обновил вашу widdle Здесь . Также вот только бит js только

     <код> // http://stackoverflow.com/questions/263743/how-to-get-caret-position-in-textarea var map = []; var pan = '<span>|</span>'  //found @ http://davidwalsh.name/detect-scrollbar-width  function getScrollbarWidth() {     var scrollDiv = document.createElement("div");     scrollDiv.className = "scrollbar-measure";     document.body.appendChild(scrollDiv);      // Get the scrollbar width     var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;      // Delete the DIV      document.body.removeChild(scrollDiv);      return scrollbarWidth; }  function getCaret(el) {     if (el.selectionStart) {         return el.selectionStart;     } else if (document.selection) {         el.focus();          var r = document.selection.createRange();         if (r == null) {             return 0;         }          var re = el.createTextRange(),             rc = re.duplicate();         re.moveToBookmark(r.getBookmark());         rc.setEndPoint('EndToStart', re);          return rc.text.length;     }     return 0; }   $(function() {     var span = $('#pos span');     var textarea = $('textarea');      var note = $('#note');      css = getComputedStyle(document.getElementById('textarea'));     try {         for (i in css) note.css(css[i]) && (css[i] != 'width' && css[i] != 'height') && note.css(css[i], css.getPropertyValue(css[i]));     } catch (e) {}      note.css('max-width', '300px');     document.getElementById('note').style.visibility = 'hidden';     var height = note.height();     var fakeCursor, hidePrompt;      textarea.on('keyup click', function(e) {         if (document.getElementById('textarea').scrollHeight > 100) {             note.css('max-width', 300 - getScrollbarWidth());         }          var pos = getCaret(textarea[0]);          note.text(textarea.val().substring(0, pos));         $(pan).appendTo(note);         span.text(pos);          if (hidePrompt) {             hidePrompt.remove();         }         if (fakeCursor) {             fakeCursor.remove();         }          fakeCursor = $("<div style='width:5px;height:30px;background-color: #777;position: absolute;z-index:10000'>&nbsp;</div>");          fakeCursor.css('opacity', 0.5);         fakeCursor.css('left', $('#note span').offset().left + 'px');         fakeCursor.css('top', textarea.offset().top + note.height() - (30 + textarea.scrollTop()) + 'px');          hidePrompt = fakeCursor.clone();         hidePrompt.css({             'width': '2px',             'background-color': 'white',             'z-index': '1000',             'opacity': '1'         });          hidePrompt.appendTo(textarea.parent());         fakeCursor.appendTo(textarea.parent());            return true;     }); });   

    . <Сильное> Обновление : Я вижу, что есть ошибка, если первая строка не содержит жестких разрывов, но если это, кажется, хорошо работает.

     

    How about appending a span element to the cloning div and setting the fake cursor based on this span's offsets? I have updated your fiddle here. Also here's the JS bit only

    // http://stackoverflow.com/questions/263743/how-to-get-caret-position-in-textarea var map = []; var pan = '<span>|</span>'  //found @ http://davidwalsh.name/detect-scrollbar-width  function getScrollbarWidth() {     var scrollDiv = document.createElement("div");     scrollDiv.className = "scrollbar-measure";     document.body.appendChild(scrollDiv);      // Get the scrollbar width     var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;      // Delete the DIV      document.body.removeChild(scrollDiv);      return scrollbarWidth; }  function getCaret(el) {     if (el.selectionStart) {         return el.selectionStart;     } else if (document.selection) {         el.focus();          var r = document.selection.createRange();         if (r == null) {             return 0;         }          var re = el.createTextRange(),             rc = re.duplicate();         re.moveToBookmark(r.getBookmark());         rc.setEndPoint('EndToStart', re);          return rc.text.length;     }     return 0; }   $(function() {     var span = $('#pos span');     var textarea = $('textarea');      var note = $('#note');      css = getComputedStyle(document.getElementById('textarea'));     try {         for (i in css) note.css(css[i]) && (css[i] != 'width' && css[i] != 'height') && note.css(css[i], css.getPropertyValue(css[i]));     } catch (e) {}      note.css('max-width', '300px');     document.getElementById('note').style.visibility = 'hidden';     var height = note.height();     var fakeCursor, hidePrompt;      textarea.on('keyup click', function(e) {         if (document.getElementById('textarea').scrollHeight > 100) {             note.css('max-width', 300 - getScrollbarWidth());         }          var pos = getCaret(textarea[0]);          note.text(textarea.val().substring(0, pos));         $(pan).appendTo(note);         span.text(pos);          if (hidePrompt) {             hidePrompt.remove();         }         if (fakeCursor) {             fakeCursor.remove();         }          fakeCursor = $("<div style='width:5px;height:30px;background-color: #777;position: absolute;z-index:10000'>&nbsp;</div>");          fakeCursor.css('opacity', 0.5);         fakeCursor.css('left', $('#note span').offset().left + 'px');         fakeCursor.css('top', textarea.offset().top + note.height() - (30 + textarea.scrollTop()) + 'px');          hidePrompt = fakeCursor.clone();         hidePrompt.css({             'width': '2px',             'background-color': 'white',             'z-index': '1000',             'opacity': '1'         });          hidePrompt.appendTo(textarea.parent());         fakeCursor.appendTo(textarea.parent());            return true;     }); }); 

    UPDATE: I can see that there's an error if the first line contains no hard line-breaks but if it does it seems to work well.

    </div
     
     
     
     

    Связанный проблема

    -1  Что не так с этим кодом jQuery, его сумасшедшая? [закрыто]  ( What is wrong with this jquery code its driving my crazy ) 
    <в сторону CLASS = "S-NEWACTS S-WELTIVE__info JS-Post-New Imide MB16« Роль = «Статус»> закрыт. Этот вопрос не соответствует Рекомендациям переполнения ...

    2  Fullcalendar сейчас () индикатор позиционируется неправильно  ( Fullcalendar now indicator positioned wrongly ) 
    в Fullcalendar, при настройке параметров Mintime и maxtime ныне () индикаторы не расположены должным образом. У меня есть jsfiddle , чтобы пока...

    0  Как вы загружаете файл JavaScript в объем  ( How do you load a javascript file into a scope ) 
    Я пытаюсь выяснить, как загрузить содержимое файла JavaScript в объем. Причина этого я хочу иметь возможность иметь возможности подключения и воспроизведения ...

    0  Почему Autoseizecolumn () Loop, похоже, замораживает сценарий Google Apps?  ( Why does an autoresizecolumn loop seem to freeze a google apps script ) 
    Все, что я пытаюсь сделать, это изменить размер всеми колонны в электронной таблице. Это автономная электронная таблица. Я использую: <код> function format(...

    1  Форма подписки Rapidmail перенаправляет после подписки электронной почты - MailChimp  ( Rapidmail subscription form redirect after email subscription mailchimp ) 
    Я создаю веб-страницу, которая включает в себя очень простую форму подписки, в основном собирая адреса электронной почты, заинтересованные в продукте. Для это...

    0  JavaScript Ball Collision  ( Javascript ball collision ) 
    Я пытаюсь создать простую игру JavaScript с простыми физиками. Я могу определить, когда 2 шарика столкнулись, но у меня возникли проблемы с обработкой столкно...

    0  OnClick = "Commentcheck ({{Meeting.people}})", ожидаемый идентификатор, строка или номер  ( Onclick authoritycheckmeeting people expected identifier string or num ) 
    У меня возникли проблемы с отправкой <код> {{meeting.people}} Value на функцию JS. Код подписан на Сообщение об ошибке говорит: ожидаемый идентификатор, ст...

    1  Удалить таблицу TR при сохранении AddClass  ( Remove table tr while maintaining addclass ) 
    Хорошо, у меня есть таблица TR, которая удаляется, когда вы нажимаете кнопку. Я использую Animate.css и хотел бы добавить класс после того, как мой запрос AJA...

    0  Обновление происхождения перетаскивания / прокрутки после обновления данных с переходом в D3  ( Update drag scroll origin after an update of the data with transition in d3 ) 
    Я работаю на диаграмме с перетаскиванием, масштабированием и обновлениями. Это в основном работает, однако, после добавления новых данных позиция перетаскиван...

    30  Как я могу использовать Nodejs с Windows 7? [закрыто]  ( How can i use nodejs with windows 7 ) 
    <в сторону CLASS = "S-NEWACTS S-WELTIVE__info JS-Post-New Imide MB16« Роль = «Статус»> <Путь d = "M15 6.38A6.48 6.48 0 007.78. 04H-.02A6.49 6.49 0 002.05 ...

    1  JavaScript: Получение идентификатора родителя из документа  ( Javascript getting the id of the parent from a document ) 
    У меня возникли проблемы с тем, чтобы получить идентификатор родителя документа, который здесь «iFrame1». Как вы можете видеть, что JavaScript должен проживат...

    0  в то время как цикл превышает каждый метод  ( While loop over takes the each method ) 
    Я добавляю элемент на страницу, используя статический номер в соответствии с кликом пользователя. Таким образом, элемент имеет серийный номер в соответствии с...

    0  Скрывая неупорядоченный список, когда у него нет элементов  ( Hiding an unordered list when it has no elements ) 
    У меня есть проблема, которая кажется сначала, как общий язык No-Brainer и легкая задача. У меня есть плагин JavaScript на моей странице, который генерирует...

    1  Функциональность ломтики массива JavaScript на картах JavaScript  ( Javascript array slice functionality in javascript maps ) 
    в массивах JavaScript у нас есть один метод под названием Slice, который возвращает неглубокую копию части массива. Можно ли сделать то же самое в картах JS. ...

    0  Google Map не отображает  ( Google map not displaying ) 
    У меня есть карта Google, которая используется здесь: http://www.comehike.com/outdoors/birds/birds.php Теперь я вижу сообщения об ошибках .j для 1) Инициа...

    Связанный проблема

    -1  Что не так с этим кодом jQuery, его сумасшедшая? [закрыто] 
    2  Fullcalendar сейчас () индикатор позиционируется неправильно 
    0  Как вы загружаете файл JavaScript в объем 
    0  Почему Autoseizecolumn () Loop, похоже, замораживает сценарий Google Apps? 
    1  Форма подписки Rapidmail перенаправляет после подписки электронной почты - MailChimp 
    0  JavaScript Ball Collision 
    0  OnClick = "Commentcheck ({{Meeting.people}})", ожидаемый идентификатор, строка или номер 
    1  Удалить таблицу TR при сохранении AddClass 
    0  Обновление происхождения перетаскивания / прокрутки после обновления данных с переходом в D3 
    30  Как я могу использовать Nodejs с Windows 7? [закрыто] 
    1  JavaScript: Получение идентификатора родителя из документа 
    0  в то время как цикл превышает каждый метод 
    0  Скрывая неупорядоченный список, когда у него нет элементов 
    1  Функциональность ломтики массива JavaScript на картах JavaScript 
    0  Google Map не отображает