You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让文本域(textarea)的复制粘贴事件同步触发字符进度条与计数器?

Fix for Paste/Text Sync Issue in Twitter-like Textarea Progress Bar

Hey there! I see the problem—your current code only listens for the keydown event, which doesn't trigger when text is pasted (whether via Ctrl+V, right-click menu, or drag-and-drop). That's why your progress bar and counter don't update when you paste text. Let's fix this with a few simple tweaks:

Key Issue Explanation

The keydown event only fires when a physical key is pressed. It doesn't account for any text changes that happen without keyboard input (like pasting, cutting, or even auto-fill). The solution is to use the input event instead—it's designed to capture all changes to a form element's content, no matter how the content is modified.

Updated Code

First, let's refactor your JavaScript to use the input event and clean up the logic into a reusable function:

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

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

    // Set initial dash array/offset
    var pathLength = Math.PI * ( progress.getAttribute('r') * 2 );
    progress.style.strokeDashoffset = pathLength + 'px';
    progress.style.strokeDasharray = pathLength + 'px';

    // Reusable function to update all UI elements
    function updateUI() {
        var len = textarea.value.length,
            per = len / tweetLength;

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

        // Update progress bar colors
        progress.classList.toggle('warn', len > warningZone && len < dangerZone);
        progress.classList.toggle('danger', len >= dangerZone);
        progress.classList.toggle('tragedy', len === tweetLength);

        // Update counter
        counter.textContent = tweetLength - len;
        counter.classList.toggle('danger', len >= tweetLength);
    }

    // Listen for ALL content changes (paste, type, cut, etc.)
    textarea.addEventListener('input', updateUI);

    // Initialize UI on page load
    updateUI();
}());

What Changed?

  1. Replaced keydown with input event: This ensures every text change (including pastes) triggers an update.
  2. Encapsulated logic in updateUI(): Makes the code cleaner and allows us to call it manually (like on page load to set the initial counter value).
  3. Added initial updateUI() call: Ensures the counter starts at 40 and the progress bar is empty when the page loads, instead of being blank.

Your HTML and CSS can stay exactly the same—no changes needed there!

Testing the Fix

Now try pasting text into the textarea, cutting text, or even using drag-and-drop to add content. The progress bar and counter should update instantly, just like when you type manually.

内容的提问来源于stack exchange,提问作者Mitrixsen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 16:24:05