【问题标题】:How can I change input blink caret style with easy css, js如何使用简单的 css、js 更改输入闪烁插入符号样式
【发布时间】:2017-07-19 07:59:15
【问题描述】:

我想知道如何使用 css/javascript 来调整带有 CSS 的搜索框内的闪烁光标?

是否可以将默认闪烁插入符号替换为水平闪烁图标

【问题讨论】:

  • 。在您(包括我)之前,许多人都尝试过并失败了。如果你真的想追求它(祝你好运),你需要一个带有不可见文本的文本框,它下面的 div 然后更新以包含文本,然后另一个 div 以你想要的方式设置插入符号查看随着用户键入和选择而移动的内容。虽然,我认为 WebKit 浏览器可以原生地做到这一点......
  • Styling text input caret的可能重复
  • 有一个 CSS 属性可以做到这一点,但还不支持:caret-shape

标签: css caret input-field


【解决方案1】:

我认为这并不难。我做了一个简单的例子,它适用于除 Safari 之外的大多数现代浏览器。 它在画布上绘制插入符号,并将其设置为输入的背景,在从浏览器插入符号位置计算的位置上。

它检查浏览器是否支持caret-color css 属性,如果不支持,它什么也不做,因为系统插入符号和我们的插入符号将同时可见。从我测试的浏览器来看,只有 Safari 不支持。

$("input").on('change blur mouseup focus keydown keyup', function(evt) {
  var $el = $(evt.target);
  //check if the carret can be hidden
  //AFAIK from the modern mainstream browsers
  //only Safari doesn't support caret-color
  if (!$el.css("caret-color")) return;
  var caretIndex = $el[0].selectionStart;
  var textBeforeCarret = $el.val().substring(0, caretIndex);

  var bgr = getBackgroundStyle($el, textBeforeCarret);
  $el.css("background", bgr);
  clearInterval(window.blinkInterval);
  //just an examplethis should be in a module scope, not on window level
  window.blinkInterval = setInterval(blink, 600);
})

function blink() {
 
  $("input").each((index, el) => {
    var $el = $(el);
    if ($el.css("background-blend-mode") != "normal") {
      $el.css("background-blend-mode", "normal");
    } else {
      $el.css("background-blend-mode", "color-burn");
    }
  });
}


function getBackgroundStyle($el, text) {
  var fontSize = $el.css("font-size");
  var fontFamily = $el.css("font-family");

  var font = fontSize + " " + fontFamily;
  var canvas = $el.data("carretCanvas");
  //cache the canvas for performance reasons
  //it is a good idea to invalidate if the input size changes because of the browser text resize/zoom)
  if (canvas == null) {
    canvas = document.createElement("canvas");
    $el.data("carretCanvas", canvas);
    var ctx = canvas.getContext("2d");
    ctx.font = font;
    ctx.strokeStyle = $el.css("color");
    ctx.lineWidth = Math.ceil(parseInt(fontSize) / 5);
    ctx.beginPath();
    ctx.moveTo(0, 0);
    //aproximate width of the caret
    ctx.lineTo(parseInt(fontSize) / 2, 0);
    ctx.stroke();
  }
  var offsetLeft = canvas.getContext("2d").measureText(text).width + parseInt($el.css("padding-left"));
  return "#fff url(" + canvas.toDataURL() + ") no-repeat " +
    (offsetLeft - $el.scrollLeft()) + "px " +
    ($el.height() + parseInt($el.css("padding-top"))) + "px";
}
input {
  caret-color: transparent;
  padding: 3px;
  font-size: 15px;
  color: #2795EE;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" />

如果有兴趣,我可以稍微清理一下,然后将其封装在一个 jQuery 插件中。

编辑:忘记了闪烁,所以我添加了它。更好的方法是将其添加为 css 动画,在这种情况下,插入符号应位于输入上方的单独 html 元素中。

【讨论】:

  • 非常棒的解决方案 ;)
  • 感谢您的解决方案,基本上我是为电话文本字段制作这个的,再次感谢 :-) 干杯
  • 插入符号的移动速度不如删除或添加文本的速度,但效果就在这里。
【解决方案2】:

最新标准支持更改插入符号的颜色。但不改变它的宽度不是,我认为这是一种耻辱,因为这是视力障碍者的可及性问题。

自己实施此类更改的一种方法是首先尝试找出插入符号闪烁的位置,然后用看起来像插入符号但可能更宽的元素覆盖它。

这是一篇关于如何去做这样的事情的文章。这是一篇好文章,但最终解决方案总体上有点复杂。但看看它是否能解决你的问题:

https://medium.com/@jh3y/how-to-where-s-the-caret-getting-the-xy-position-of-the-caret-a24ba372990a

对于如何找到护理 x-y 位置,这可能是一个更简单的解释: How do I get the (x, y) pixel coordinates of the caret in text boxes?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-19
    • 1970-01-01
    • 2010-12-26
    • 2015-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多