term_input.html 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. <!--键入[[显示术语下拉菜单-->
  2. <html>
  3. <body>
  4. <style>
  5. .textarea,
  6. textarea {
  7. padding: 0;
  8. font-family: inherit;
  9. width: 100%;
  10. height: 100px;
  11. resize: vertical;
  12. font-size: 14px;
  13. line-height: 1;
  14. border: 1px solid #ddd;
  15. white-space: pre-wrap;
  16. word-break: break-all;
  17. z-index: 1;
  18. }
  19. #text_shadow{
  20. position: absolute;
  21. width: 300px;
  22. visibility: hidden;
  23. }
  24. .cursor{
  25. position: absolute;
  26. border-left: 1px solid #000;
  27. }
  28. #menu{
  29. width: 200px;
  30. height:300px;
  31. background-color: aqua;
  32. box-shadow: #000;
  33. position:absolute;
  34. display: none;
  35. }
  36. #menu ul{
  37. list-style-type: none;
  38. margin: 0;
  39. padding: 0;
  40. }
  41. #menu .focus{
  42. color:red;
  43. }
  44. </style>
  45. <h2>术语输入测试</h2>
  46. <div style='width:300px;position: relative;'>
  47. <div id="menu"></div>
  48. <div class="textarea" id="text_shadow" >
  49. 前端路迹<span class="cursor">&nbsp;</span>
  50. qinshenxue.com
  51. </div>
  52. <textarea>
  53. 前端路迹
  54. qinshenxue.com
  55. </textarea>
  56. </div>
  57. <script>
  58. var menuFocusIndex=0;
  59. var data=["amanussa","anadhiṭṭhita","anantarāya","anissaṭṭha","aniyata","antaravāsaka"];
  60. var textarea = document.querySelector('textarea');
  61. textarea.onkeydown = function (e) {
  62. textarea.clientHeight
  63. let menu = document.querySelector('#menu');
  64. switch (e.key) {
  65. case "ArrowDown"://down arrow
  66. if(menu.style.display=="block"){
  67. menuFocusIndex++;
  68. if(menuFocusIndex>5){
  69. menuFocusIndex=5;
  70. }
  71. menu.innerHTML=renderMenu({focus:menuFocusIndex});
  72. return false;
  73. }
  74. break;
  75. case "ArrowUp"://up arrow
  76. if(menu.style.display=="block"){
  77. menuFocusIndex--;
  78. if(menuFocusIndex<0){
  79. menuFocusIndex=0;
  80. }
  81. menu.innerHTML=renderMenu({focus:menuFocusIndex});
  82. return false;
  83. }
  84. break;
  85. case "Enter":
  86. if(menu.style.display=="block"){
  87. let value = textarea.value;
  88. let selectionStart = textarea.selectionStart;
  89. let str1 = value.slice(0, selectionStart)
  90. let str2 = value.slice(selectionStart);
  91. textarea.value = str1+data[menuFocusIndex]+"]]"+str2;
  92. menu.style.display="none";
  93. return false;
  94. }
  95. else{
  96. if(!e.shiftKey){
  97. return false;
  98. }
  99. }
  100. break;
  101. case "Escape":
  102. e.currentTarget.value="";
  103. break;
  104. default:
  105. break;
  106. }
  107. }
  108. textarea.onkeyup = function (e) {
  109. let value = textarea.value
  110. let selectionStart = textarea.selectionStart
  111. let str1 = value.slice(0, selectionStart)
  112. let str2 = value.slice(selectionStart)
  113. let textNode1 = document.createTextNode(str1)
  114. let textNode2 = document.createTextNode(str2)
  115. let cursor = document.createElement('span')
  116. cursor.innerHTML = '&nbsp;'
  117. cursor.setAttribute('class','cursor')
  118. let mirror = document.querySelector('.textarea')
  119. mirror.innerHTML = ''
  120. mirror.appendChild(textNode1)
  121. mirror.appendChild(cursor)
  122. mirror.appendChild(textNode2)
  123. let menu = document.querySelector('#menu');
  124. if(str1.slice(-2)=="[[" && menu.style.display!="block"){
  125. menuFocusIndex=0;
  126. menu.innerHTML=renderMenu({focus:0});
  127. menu.style.display="block";
  128. menu.style.top=cursor.offsetTop+14;
  129. menu.style.left=cursor.offsetLeft;
  130. }
  131. if(e.key=="Escape"){
  132. menu.style.display="none";
  133. }
  134. console.log(keynum);
  135. console.log(cursor.offsetLeft,cursor.offsetTop)
  136. }
  137. function renderMenu(params) {
  138. let html="<ul>";
  139. let index=0;
  140. let focusIndex = params.focus%data.length;
  141. for (const it of data) {
  142. html +="<li ";
  143. if(focusIndex==index){
  144. html +="class='focus' "
  145. }
  146. index++;
  147. html +=">"+index+ ". "+it+"<li>";
  148. }
  149. return html;
  150. }
  151. /*
  152. // element: t.refs.textarea
  153. function getCaretPosition(element) {
  154. let left;
  155. let top;
  156. if (document.selection) {
  157. element.focus();
  158. const range = document.selection.createRange();
  159. left = range.boundingLeft + element.scrollLeft;
  160. top = range.boundingTop + element.scrollTop;
  161. } else {
  162. const SHADOWEDITOR = '__shadow_editor__';
  163. const SHADOWEDITORTEXT = '__shadow_editor_text__';
  164. const SHADOWEDITORCARET = '__shadow_editor_caret__';
  165. const shadowEditor = element[SHADOWEDITOR] || document.createElement('div');
  166. const shadowEditorCaret = element[SHADOWEDITORCARET] || document.createElement('span');
  167. const shadowEditorText = element[SHADOWEDITORTEXT] || document.createElement('span');
  168. let focusOffset = { left: 0, top: 0 };
  169. if (!element[SHADOWEDITOR]) {
  170. // add shadpw element to element's cache
  171. element[SHADOWEDITOR] = shadowEditor;
  172. element[SHADOWEDITORCARET] = shadowEditorCaret;
  173. element[SHADOWEDITORTEXT] = shadowEditorText;
  174. // append shadow to document body
  175. shadowEditor.appendChild(shadowEditorText);
  176. shadowEditor.appendChild(shadowEditorCaret);
  177. document.body.appendChild(shadowEditor);
  178. // set shadow element's style
  179. const style = shadowEditor.style;
  180. const computed = window.getComputedStyle ? getComputedStyle(element) : element.currentStyle; // currentStyle for IE < 9
  181. if (element.nodeName != 'INPUT') {
  182. // only for textarea
  183. style.whiteSpace = 'pre-wrap';
  184. style.wordWrap = 'break-word';
  185. } else {
  186. style.whiteSpace = 'nowrap';
  187. }
  188. style.position = 'absolute';
  189. style.overflow = 'hidden';
  190. style.visibility = 'hidden';
  191. properties.forEach((prop) => {
  192. style[prop] = computed[prop];
  193. });
  194. shadowEditorCaret.textContent = '|';
  195. shadowEditorCaret.style.cssText = 'display:inline-block;width:0;overflow:hidden;word-wrap:break-word;word-break:break-all;';
  196. }
  197. const offset = getElementOffset(element);
  198. shadowEditor.style.top = `${offset.top}px`;
  199. shadowEditor.style.left = `${offset.left}px`;
  200. const index = element.selectionEnd;
  201. const SHADOWEDITORCONTENT = element.value.substring(0, index);
  202. shadowEditorText.textContent = SHADOWEDITORCONTENT;
  203. shadowEditorCaret.style.display = 'inline-block';
  204. try { focusOffset = getElementOffset(shadowEditorCaret); } catch (e) { }
  205. shadowEditorCaret.style.display = 'none';
  206. left = focusOffset.left - element.scrollLeft;
  207. top = focusOffset.top - element.scrollTop;
  208. const winOffset = getScrollOffset();
  209. left -= winOffset.x;
  210. top -= winOffset.y;
  211. }
  212. return {
  213. left,
  214. top,
  215. };
  216. }
  217. */
  218. /*
  219. 如果你只是想获得输入框中光标的 offset 的话, 你可以用从 At.js 剥离出来的 jQuery 插件: Caret.js
  220. 可以是用AT-JS jquery插件来实现你需要的效果:
  221. 下载地址:
  222. http://pan.baidu.com/share/link?shareid=495943&uk=386708086
  223. 使用方法:
  224. $("input[name=message]").atWho("@",{
  225. tpl: "<li id='${uid}' data-value='${name}'>${name} <small>${spacenote}</small></li>",
  226. 'data':friend_list
  227. });
  228. 评论
  229. 但是如果你想做,你题目描述的东西的话,还是建议用插件。 这里有一个不错的jquery插件: http://ichord.github.io/At.js/
  230. 评论
  231. */
  232. </script>
  233. </body>
  234. </html>