微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

javascript – 在自定义文本区域中显示插入符号而不显示其文本

我有一个自定义textarea.在这个例子中,它随机地使字母变为红色或绿色.
var mydiv = document.getElementById('mydiv'),myta = document.getElementById('myta');
function updateDiv() {
  var fc;
  while (fc = mydiv.firstChild) mydiv.removeChild(fc);
  for (var i = 0; i < myta.value.length; i++) {
    var span = document.createElement('span');
    span.className = Math.random() < 0.5 ? 'green' : 'red';
    span.appendChild(document.createTextNode(myta.value[i]));
    mydiv.appendChild(span);
  }
};
myta.addEventListener('input',updateDiv);
body { position: relative }
div,textarea {
  -webkit-text-size-adjust: none;
  width: 100%;
  white-space: pre-wrap;
  word-wrap: break-word;
  overflow-wrap: break-word;
  font: 1rem sans-serif;
  padding: 2px;
  margin: 0;
  border-radius: 0;
  border: 1px solid #000;
  resize: none;
}
textarea {
  position: absolute;
  top: 0;
  color: transparent;
  background: transparent;
}
.red { color: #f00 }
.green { color: #0f0 }
<div id="mydiv"></div>
<textarea id="myta" autofocus=""></textarea>

一个带有textarea的输出div.因此textarea不会掩盖其下面的任何彩色物品,它的颜色和背景都设置为透明.除了插入符(用户代理提供的闪烁光标)是透明的以外,一切都在这里工作.

有没有办法显示插入符号而不显示textarea的文本?

如果我将div设置在textarea之上并给它指针-event:none,则textarea仍然可以在下面看到.这种安排也使得平滑滚动变得困难,因此它对我不起作用.

解决方法

只需插入自己的插入符号!
function blink() {
  document.getElementById('caret').hidden ^= 1;
  blinkTimeout = setTimeout(blink,500);
}
var mydiv = document.getElementById('mydiv'),myta = document.getElementById('myta'),blinkTimeout = setTimeout(blink,500),lastSelectionStart = 0,lastSelectionEnd = 0,whichSelection = true;
function updateDiv() {
  var fc;
  while (fc = mydiv.firstChild) mydiv.removeChild(fc);
  if (myta.selectionStart != lastSelectionStart) {
    lastSelectionStart = myta.selectionStart;
    whichSelection = false;
  }
  if (myta.selectionEnd != lastSelectionEnd) {
    lastSelectionEnd = myta.selectionEnd;
    whichSelection = true;
  }
  var cursorPos = whichSelection ? myta.selectionEnd : myta.selectionStart;
  for (var i = 0; i < myta.value.length; i++) {
    if (i == cursorPos) {
      var caret = document.createElement('span');
      caret.id = 'caret';
      caret.appendChild(document.createTextNode('\xA0'));
      mydiv.appendChild(caret);
      clearTimeout(blinkTimeout);
      blinkTimeout = setTimeout(blink,500);
    }
    var span = document.createElement('span');
    span.className = Math.random() < 0.5 ? 'green' : 'red';
    span.appendChild(document.createTextNode(myta.value[i]));
    mydiv.appendChild(span);
  }
  if (myta.value.length == cursorPos) {
    var caret = document.createElement('span');
    caret.id = 'caret';
    caret.appendChild(document.createTextNode('\xA0'));
    mydiv.appendChild(caret);
    clearTimeout(blinkTimeout);
    blinkTimeout = setTimeout(blink,500);
  }
};
myta.addEventListener('input',updateDiv);
myta.addEventListener('focus',updateDiv);
myta.addEventListener('mousedown',function() {
  setTimeout(updateDiv,0);
});
myta.addEventListener('keydown',0);
});
myta.addEventListener('blur',function() {
  document.getElementById('caret').hidden = true;
  clearTimeout(blinkTimeout);
});
body { position: relative }
div,textarea {
  -webkit-text-size-adjust: none;
  width: 100%;
  white-space: pre-wrap;
  word-wrap: break-word;
  overflow-wrap: break-word;
  font: 1rem sans-serif;
  padding: 2px;
  margin: 0;
  border-radius: 0;
  border: 1px solid #000;
  resize: none;
}
textarea {
  position: absolute;
  top: 0;
  color: transparent;
  background: transparent;
}
.red { color: #f00 }
.green { color: #0f0 }
#caret {
  display: inline-block;
  position: absolute;
  width: 1px;
  background: #000;
}
#caret[hidden] { display: none }
<div id="mydiv"><span id="caret">&nbsp;</span></div>
<textarea id="myta" autofocus=""></textarea>

我这里有一个< span> #caret插入到div中,通过使用JS切换其隐藏属性,每隔500ms闪烁一次.为了复制浏览器行为,我必须检测它是selectStart还是者插入符实际所在的selectionEnd,并使其在输入文本时保持稳定.

当跨度不是固定长度或嵌套时,这有点难以实现,但它比使用更复杂的荧光笔的contentEditable更容易.此功能会将插入符号插入正确的位置:

function insertNodeAtPosition(node,refNode,pos) {
    if (typeof(refNode.nodeValue) == 'string') refNode.parentNode.insertBefore(node,refNode.splitText(pos));
    else {
        for (var i = 0; i < refNode.childNodes.length; i++) {
            var chNode = refNode.childNodes[i];
            if (chNode.textContent.length <= pos && i != refNode.childNodes.length - 1) pos -= chNode.textContent.length;
            else return insertNodeAtPosition(node,chNode,pos);
        }
    }
}

用法(我是插入它的位置):

var caret = document.createElement('span');
caret.id = 'caret';
caret.appendChild(document.createTextNode('\xA0'));
insertNodeAtPosition(caret,mydiv,i);
clearTimeout(blinkTimeout);
blinkTimeout = setTimeout(blink,500);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐