基于HTML的Console Terminal开发:输入锁定与光标闪烁实现问题
Hey there! Let's tackle your two terminal functionality issues step by step. I've updated your code to address both requirements, with clear explanations for each part:
1. Disable Previous Input & Focus New Input After Pressing Enter
Right now, after hitting Enter, old input fields stay editable — we need to lock them down and automatically shift focus to the new input box. Here's how to fix that:
- When Enter is pressed, target the last
.stdinelement, set itscontenteditabletofalse(to disable editing) and remove itsid(avoiding duplicate IDs since we generate new inputs each time). - After appending the new
.stdinelement, call.focus()on it to move the cursor over automatically. - I also adjusted the keypress listener to only trigger on
.stdinelements instead of the entire document, which prevents unintended triggers elsewhere.
Modified JavaScript code snippet (key changes highlighted):
var terminal = $('#terminal'); // Initialize first input on page load (matches your "press Enter to start" flow) $(document).ready(function() { terminal.append('<div class="static"><span class="fa fa-arrow-right console-arrow"></span> ~ </div>'); terminal.append('<div class="stdin" contenteditable="true"></div>'); }); // Listen for Enter only on editable stdin fields $(document).on('keypress', '.stdin[contenteditable="true"]', function(e) { if (e.which === 13) { e.preventDefault(); var stdin = $(this).text(); console.log(stdin); consoleInteration(stdin); } }); function consoleInteration(stdin) { // Lock the current input field $('.stdin').last().attr('contenteditable', false).removeAttr('id'); // Simulated AJAX result const result = "This is the output from the shell"; terminal.append('<br><div class="static">' + result + '</div><br>'); terminal.append('<div class="static"><span class="fa fa-arrow-right console-arrow"></span> ~ </div>'); // Create new input and focus it immediately const newInput = $('<div class="stdin" contenteditable="true"></div>'); terminal.append(newInput); newInput.focus(); // Auto-scroll to bottom to show latest content terminal.scrollTop(terminal[0].scrollHeight); }
2. Implement Terminal-Style Text Blinking Effect
To replicate that classic terminal blink (like the snippet you referenced), we'll use CSS keyframes to animate opacity. We'll add a blinking cursor to the active input field, which is a standard terminal UI touch:
Add these CSS rules to your existing styles:
/* Blinking cursor animation */ @keyframes blink { 0%, 50% { opacity: 1; } 51%, 100% { opacity: 0; } } .stdin[contenteditable="true"]:after { content: '|'; color: #fff; animation: blink 1s infinite; margin-left: 2px; } /* Optional: Stop blinking when input loses focus */ .stdin[contenteditable="true"]:not(:focus):after { animation: none; }
Full Working Code
Here's the complete integrated code with both fixes:
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <div id="terminal" class="terminal"> </div>
CSS
.terminal { width: 100%; padding: 4px; background-color: black; opacity: 0.7; height: 650px; color: #fff; font-family: 'Source Code Pro', monospace; font-weight: 200; font-size: 14px; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; overflow-y: auto; } .terminal div { display: inline-block; } .terminal .static { color: #5ed7ff; font-weight: bold; } .console-arrow { color: #bde371; } /* Blinking cursor animation */ @keyframes blink { 0%, 50% { opacity: 1; } 51%, 100% { opacity: 0; } } .stdin[contenteditable="true"]:after { content: '|'; color: #fff; animation: blink 1s infinite; margin-left: 2px; } .stdin[contenteditable="true"]:not(:focus):after { animation: none; }
JavaScript
var terminal = $('#terminal'); // Initialize first input on page load $(document).ready(function() { terminal.append('<div class="static"><span class="fa fa-arrow-right console-arrow"></span> ~ </div>'); terminal.append('<div class="stdin" contenteditable="true"></div>'); }); // Listen for Enter only on editable stdin fields $(document).on('keypress', '.stdin[contenteditable="true"]', function(e) { if (e.which === 13) { e.preventDefault(); var stdin = $(this).text(); console.log(stdin); consoleInteration(stdin); } }); function consoleInteration(stdin) { // Disable and lock the current input $('.stdin').last().attr('contenteditable', false).removeAttr('id'); // Simulated AJAX result const result = "This is the output from the shell"; terminal.append('<br><div class="static">' + result + '</div><br>'); terminal.append('<div class="static"><span class="fa fa-arrow-right console-arrow"></span> ~ </div>'); // Create new input and focus it const newInput = $('<div class="stdin" contenteditable="true"></div>'); terminal.append(newInput); newInput.focus(); // Auto-scroll to bottom of terminal terminal.scrollTop(terminal[0].scrollHeight); }
Quick Notes:
- I added initial input setup on page load so users can start typing immediately (if you want to hide it until the first Enter press, just move that initialization into the keypress handler).
- The blinking effect is tied to the active editable input, mimicking a real terminal cursor.
- Auto-scrolling ensures users always see the latest input/output without manual scrolling.
内容的提问来源于stack exchange,提问作者qweq

