如何让文本域(textarea)的复制粘贴事件同步触发字符进度条与计数器?
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?
- Replaced
keydownwithinputevent: This ensures every text change (including pastes) triggers an update. - 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). - Added initial
updateUI()call: Ensures the counter starts at40and 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

