首页 > 解决方案 > 在 CSS 中为元素添加插入符号

问题描述

问题

我制作了一个<textarea>并使用 Javascript 将值放入<pre>标签中(这很奇怪),并且我想要contenteditable 一种在. 我不能只使用,因为我正在制作一个 JSON 格式化程序(我很无聊)并且我想添加语法突出显示。<pre>F7<textarea>

我有的

document.querySelector("pre.stuff").addEventListener("click", function() {
  document.querySelector("textarea.text").focus();
});
document.querySelector("textarea.text").addEventListener("input", function() {
    document.querySelector("pre.stuff").innerText = this.value;
});
textarea.text {
  position: absolute;
    border: none;
  padding: 0px;
  opacity: 0;
  width: 0px;
  height: 0px;
}
pre.stuff {
    width: calc(100% - 20px);
    height: 250px;
    border: solid gray 2px;
    margin: 0px;
    border-radius: 5px;
    padding: 10px;
    transition: 0.3s;
    font-family: "Source Code Pro", monospace;
    tab-size: var(--tab-size);
    overflow: scroll;
    cursor: text;
}
textarea.text:focus ~ pre.stuff, pre.stuff:focus {
    outline: none;
    box-shadow: #0066ff55 0px 0px 0px 4px; /* glowwww */
    border: solid #66a3ff 2px;
}
body {
    margin: 16px;
}
<link href="https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap" rel="stylesheet">
<textarea class="text"></textarea>
<pre class="stuff" spellcheck="false" tabindex="-1"></pre>
<br>
I removed the syntax highlighting part :P

此外,重点必须放在<textarea>否则它将不起作用。

标签: htmlcsscaret

解决方案


为此,您需要一个绝对定位的元素作为插入符号,textarea因为我所知道的没有属性可以让您操纵插入符号。因此,每当您的 textarea 的值发生变化时,您都必须创建自定义事件。这是您将如何执行此操作的方法。

请注意,如果您发现插入符号的过渡令人讨厌,您可以删除它。另请注意:为此,我正在使用一个库,可在此链接中找到

const txtarea = document.querySelector("textarea.text");
        const invis = $('#faux');


        document.querySelector("pre.stuff").addEventListener("click", function() {
          document.querySelector("textarea.text").focus();
        });
        document.querySelector("textarea.text").addEventListener("input", function() {
            document.querySelector("pre.stuff").innerText = this.value;
        });

        txtarea.addEventListener("keyup", move_caret);
        txtarea.addEventListener("keydown", move_caret);


        function move_caret() {
            let select = document.getSelection();
            let index = txtarea.selectionStart;

            let background = getComputedStyle(txtarea).color;

            const editor = $("textarea.text");
            let pos = editor.caret('position');
            let left = pos.left + 2 + "px";
            let top = pos.top + 2 + "px";
            let height = pos.height + "px";
            var css_data = {
                left,
                top,
                height,
                background
            };
            $("#caret").css(css_data);

        }
* {
            position: relative;
        }
        textarea.text {
            min-width: calc(100% - 20px);
            word-wrap: nowrap;
            height: 250px;
            border: solid gray 2px;
            margin: 0px;
            border-radius: 5px;
            padding: 10px;
            transition: 0.3s;
            font-family: "Source Code Pro", monospace;
            tab-size: var(--tab-size);
            overflow: scroll;
            cursor: text;
            opacity: 0;
            pointer-events: none;
            position: absolute;
        }
        pre.stuff {
            max-width: calc(100% - 20px);
            word-wrap: break-word;
            height: 250px;
            border: solid gray 2px;
            margin: 0px;
            border-radius: 5px;
            padding: 10px;
            transition: 0.3s;
            font-family: "Source Code Pro", monospace;
            tab-size: var(--tab-size);
            overflow: scroll;
            cursor: text;
        }
        textarea.text:focus ~ pre.stuff, pre.stuff:focus {
            outline: none;
            box-shadow: #0066ff55 0px 0px 0px 4px; /* glowwww */
            border: solid #66a3ff 2px;
        }
        body {
            margin: 16px;
        }


        #caret {
            width: 2px; 
            display: inline; 
            position: absolute;

            transition: left 137ms linear, top 137ms linear;
            animation: blink 450ms linear alternate infinite;
        }

        @keyframes blink {
            0% {opacity: 0;}
            20% {opacity: .5;}
            75% {opacity: .78}
            100% {opacity: 1}
        }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Caret.js/0.3.1/jquery.caret.min.js" integrity="sha512-qclRGh1kwCdmGsi68M9XYAhbCC4xpGRq9VqVlYAQmsG29wQG0DKke/QiMFmuFY1NGXdJ75Wjkhez5nMcuTelgQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="caret"></div>
    <span id="faux" style="display:none"></span>
    <link href="https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap" rel="stylesheet">
    <textarea class="text"></textarea>
    <div style="display: inline; width: min-content; height: min-content;">
        <pre class="stuff" spellcheck="false" tabindex="-1"></pre>
        
    </div>
    <br>


推荐阅读