简体   繁体   English

如何使复制粘贴事件在文本区域中工作?

[英]How can I make copy-paste event work in a text area?

I've created a textbox, a similar one that Twitter has when making a post, including the blue progress bar SVG circle on the bottom right corner that slowly increases, based on the number of letters you type and turns red when you go over the max amount of characters.我创建了一个文本框,与 Twitter 发布帖子时的文本框类似,包括右下角的蓝色进度条 SVG 圆圈,根据您键入的字母数量,当您输入 Z34D1ZF91FB12E5A89A5A7 时,该圆圈会缓慢增加并变为红色最大字符数。

Mine works with text so far.到目前为止,我的作品适用于文本。 However, it breaks a bit when I copy-paste the text in. Here is an example of it.但是,当我复制粘贴文本时,它会中断一点。这是一个例子。

在此处输入图像描述

Is there any way I can make it work even when I copy-paste the text in?即使我复制粘贴文本,有什么方法可以让它工作吗?

My code我的代码

 var orb = (function() { var progress = document.querySelector('.progress'), textarea = document.querySelector('textarea'), counter = document.querySelector('.counter'); /** * GRAB ELEMENTS */ var tweetLength = 40, warningZone = Math.floor( tweetLength * (1/2) ), dangerZone = Math.floor( tweetLength * (3/4) ); /** * SET DASH-ARRAY/OFFSET */ var pathLength = Math.PI * ( progress.getAttribute('r') * 2 ); progress.style.strokeDashoffset = pathLength + 'px'; progress.style.strokeDasharray = pathLength + 'px'; /** * ON KEYDOWN */ textarea.addEventListener('keydown', function( event ) { var len = textarea.value.length, per = textarea.value.length / tweetLength; var handleProgress = function() { if ( len <= tweetLength ) { var newOffset = pathLength - (pathLength * per) + 'px'; progress.style.strokeDashoffset = newOffset; } } handleProgress(); var handleColours = function() { progress.classList.toggle('warn', len > warningZone && len < dangerZone); progress.classList.toggle('danger', len >= dangerZone); progress.classList.toggle('tragedy', len == tweetLength); } handleColours(); var handleCounter = function() { counter.textContent = tweetLength - len; counter.classList.toggle('danger', len >= tweetLength); } handleCounter(); }); }());
 html { box-sizing: border-box; } *, *:before, *:after { box-sizing: inherit; } body { color: #777; text-align: center; font-family: Montserrat, sans-serif; font-size: 100%; background-image: url("../img/happy.png"); background-position: 50% 12em; background-repeat: no-repeat; background-size: 85%; height: 100vh; margin: 0; } form { position: relative; margin: 0px auto; width: 25em; } textarea { color: #333; font-size: 0.9em; font-family: inherit; border: 2px solid #333; background: #fff; border-radius: 0.333em; outline: none; display: block; padding: 0.6em; max-width: 100%; width: 100%; height: 100px; }.counter { color: #777; font-size: 0.8125em; position: absolute; bottom: 0.625em; right: 0.80em; } svg { transform: rotate(-90deg); } svg circle { fill: none; stroke-width: 1; }.underlay { stroke: #ccc; }.progress { color: #1da1f2; stroke-width: 3; transition: .2s stroke-width ease-in-out; } /* colors */.safe { color: #1da1f2; }.warn { color: #ffad1f; }.danger { color: #e0245e; }.tragedy { stroke-width: 5; animation: blink.4s ease-out; } @keyframes blink { 0% { stroke-width: 5; } 10% { stroke-width: 10; } 100% { stroke-width: 5; } } /*# sourceMappingURL=style.css.map */
 <,DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Orb me. baby</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <svg height="90" width="90"> <circle class="underlay" cx="50%" cy="50%" r="26"></circle> <circle class="progress" cx="50%" cy="50%" r="26" stroke="currentColor"></circle> </svg> <form> <textarea cols="10" rows="3" autofocus></textarea> <span class="counter"></span> </form> <script src = "js/app.module.js"></script> <script src="js/app.js"></script> </body> </html>

is better use 'keyup' and i change your js code:最好使用'keyup',我改变你的js代码:

 var orb = (function () {
        var progress = document.querySelector('.progress'),
            textarea = document.querySelector('textarea'),
            counter = document.querySelector('.counter');


        /**
         * GRAB ELEMENTS
         */


        var tweetLength = 40,
            warningZone = Math.floor(tweetLength * (1 / 2)),
            dangerZone = Math.floor(tweetLength * (3 / 4));


        /**
         * SET DASH-ARRAY/OFFSET
         */
        var pathLength = Math.PI * (progress.getAttribute('r') * 2);

        progress.style.strokeDashoffset = pathLength + 'px';
        progress.style.strokeDasharray = pathLength + 'px';


        /**
         * ON KEYDOWN
         */
        textarea.addEventListener('keyup', function (event) {

            var len = textarea.value.length,
                per = textarea.value.length / tweetLength;

            var handleProgress = function () {
                if (len <= tweetLength) {
                    var newOffset = pathLength - (pathLength * per) + 'px';
                    progress.style.strokeDashoffset = newOffset;
                }
            }
            handleProgress();

            var handleColours = function () {
                progress.classList.toggle('warn', len > warningZone && len < dangerZone);
                progress.classList.toggle('danger', len > dangerZone);
                progress.classList.toggle('tragedy', len >= tweetLength);
                if (len >= tweetLength) {
                    progress.style.strokeDasharray = 0 + 'px';
                }else{
                    progress.style.strokeDasharray = pathLength + 'px';

                }
            }
            handleColours();

            var handleCounter = function () {
                counter.textContent = tweetLength - len;
                counter.classList.toggle('danger', len >= tweetLength);
            }
            handleCounter();

        });

    }());

I used keyup too.我也用过keyup
I changed handleCounter() function and a little bit in handleProgress() .我更改了handleCounter() function 和一些handleProgress()
Since you didn't mentioned what to do when the string length is greater than 40 while pasting, I Assumed better to slice() a string to first 40 characters and here is the result.由于您没有提到粘贴时字符串长度大于 40 时该怎么做,我假设最好将字符串slice()到前 40 个字符,结果如下。
In handleCounter() , If user pressed more than 40 characters at a time then if condition executes and obviously len becomes more than 40 causes negative value in counter but this is managed.handleCounter()中,如果用户一次按下超过 40 个字符,那么if条件执行并且显然len变得超过 40 会导致计数器中的负值,但这是管理的。 It happens because of keyup .它发生是因为keyup

 var counter = document.getElementsByClassName('counter')[0]; var maxCount = 40; var warningZone = Math.floor(maxCount * (1 / 2)); var dangerZone = Math.floor(maxCount * (3 / 4)); counter.innerHTML = maxCount; var textArea = document.getElementsByTagName('textarea')[0]; var progress = document.querySelector('.progress'); var pathLength = Math.PI * (progress.getAttribute('r') * 2); progress.style.strokeDashoffset = pathLength + 'px'; progress.style.strokeDasharray = pathLength + 'px'; function fun() { var len = textArea.value.length; var per = textArea.value.length / maxCount; var handleProgress = function() { if (len <= maxCount) { var newOffset = pathLength - (pathLength * per) + 'px'; progress.style.strokeDashoffset = newOffset; } else { progress.style.strokeDashoffset = 0; } } handleProgress(); var handleColours = function() { progress.classList.toggle('warn', len > warningZone && len < dangerZone); progress.classList.toggle('danger', len >= dangerZone); progress.classList.toggle('tragedy', len >= maxCount); } handleColours(); var handleCounter = function() { if (len > maxCount) { counter.classList.toggle('danger', len >= maxCount); textArea.value = textArea.value.slice(0, maxCount); counter.innerHTML = 0; } else { counter.innerHTML = maxCount - len; } } handleCounter(); }
 html { box-sizing: border-box; } *, *:before, *:after { box-sizing: inherit; } body { color: #777; text-align: center; font-family: Montserrat, sans-serif; font-size: 100%; background-image: url("../img/happy.png"); background-position: 50% 12em; background-repeat: no-repeat; background-size: 85%; height: 100vh; margin: 0; } form { position: relative; margin: 0px auto; width: 25em; } textarea { color: #333; font-size: 0.9em; font-family: inherit; border: 2px solid #333; background: #fff; border-radius: 0.333em; outline: none; display: block; padding: 0.6em; max-width: 100%; width: 100%; height: 100px; }.counter { color: #777; font-size: 0.8125em; position: absolute; bottom: 0.625em; right: 0.80em; } svg { transform: rotate(-90deg); } svg circle { fill: none; stroke-width: 1; }.underlay { stroke: #ccc; }.progress { color: #1da1f2; stroke-width: 3; transition: .2s stroke-width ease-in-out; } /* colors */.safe { color: #1da1f2; }.warn { color: #ffad1f; }.danger { color: #e0245e; }.tragedy { stroke-width: 5; animation: blink.4s ease-out; } @keyframes blink { 0% { stroke-width: 5; } 10% { stroke-width: 10; } 100% { stroke-width: 5; } }
 <body> <svg height="90" width="90"> <circle class="underlay" cx="50%" cy="50%" r="26"></circle> <circle class="progress" cx="50%" cy="50%" r="26" stroke="currentColor"></circle> </svg> <form> <textarea onkeyup='fun()' cols="10" rows="3" autofocus></textarea> <span class="counter"></span> </form> </body>

If anything needed, Mention in comment.如有需要,请在评论中提及。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM