尝试并且未能制作Linux终端

时间:2017-11-23 16:31:19

标签: javascript jquery html css

这可能是一个很容易找到的愚蠢问题,但我对所有这一切都很陌生,我似乎无法找到我正在寻找的东西,或者至少我没有#&# 39;不知道我需要寻找什么,因此我就在这里。

所以我要做的就是创建一种Linux终端......这就是我到目前为止所做的。

Linux looking terminal thingy

我坚持的是实际输入文字部分...... 我一直在尝试使用 contenteditable = true 创建一个div以及尝试输入元素,但似乎都没有按照我想要的方式工作。 我现在使用的结构是:

<div class="title" contenteditable="false" >
admin@localhost:~$ 
<div class="write-point" contenteditable="true" ></div>
<div class="linux-cursor" contenteditable="false"></div>

但是这只会删除整行文本。 &#34;管理@本地:〜$&#34;以及光标。

我还尝试使用JavaScript将光标放在文本之后,但它根本不起作用。

function forStackOverFlow() {
var textInput = document.getElementsByClassName('write-point');

textInput.onkeydown = function(e) {
    console.log(textInput.value);
    var childTag = document.getElementsByClassName("write-point");
    childTag.parentNode.insertBefore(textInput.value, childTag.nextSibling);
}};

所以我的主要问题是:

  • 将div(光标元素)移动到输入文本末尾(用户输入)的方法和内容
  • 是否可以允许用户在网页加载后立即输入?

谢谢,任何帮助都会很棒:)

2 个答案:

答案 0 :(得分:1)

您可以使用一些CSS更好地做到这一点,以确保“插入符”元素始终位于contenteditable之后,而某些JS确保contenteditable元素始终处于焦点。您可以尝试通过在autofocus元素上添加contenteditable并在插入符号元素中使用<label>来做最后一件事,但这不适用于contenteditable元素。请注意,不需要键盘事件侦听器:

const input = document.getElementById('input');
const caret = document.getElementById('caret');

// Move the focus back to the input if it moves away from it:
input.addEventListener('blur', (e) => {  
  input.focus();
});

// Set the focus to the input so that you can start typing straight away:
input.focus();
body {
  background: #000;
  color: #0F0;
  font-family: monospace;
  height: 100vh;
  box-sizing: border-box;
  overflow-x: hidden;
  overflow-y: scroll;
  margin: 0;
  padding: 16px;
}

#input {
  display: inline;
  word-break: break-all;
  outline: none;
  visibility: visible;
}

#caret {
  border: 0;
  padding: 0;
  outline: none;
  background-color: #0F0;
  display: inline-block;
  font-family: monospace;
}
admin@localhost:~$

<div id="input" contenteditable="true"></div><button id="caret" for="input">&nbsp;</button>

在一个更现实的示例中,您可能想要:

  • 避免将焦点集中在contenteditable元素中,因为那样会阻止选择先前的命令。相反,只有在用户按下某个键时,才将焦点放在contenteditable元素上。

  • 根据其位置显示不同的插入符:如果在输入的末尾则显示正方形,如果在其他地方,则显示行(除非使用 Ins 键启用了改写模式)。 / p>

  • 如果按下,则添加新的命令/条目。

  • 防止输入格式化的文本,并在需要时自动将其拆分为多个命令/条目。

const history = document.getElementById('history');
const input = document.getElementById('input');
const cursor = document.getElementById('cursor');

function focusAndMoveCursorToTheEnd(e) {  
  input.focus();
  
  const range = document.createRange();
  const selection = window.getSelection();
  const { childNodes } = input;
  const lastChildNode = childNodes && childNodes.length - 1;
  
  range.selectNodeContents(lastChildNode === -1 ? input : childNodes[lastChildNode]);
  range.collapse(false);

  selection.removeAllRanges();
  selection.addRange(range);
}

function handleCommand(command) {
  const line = document.createElement('DIV');
  
  line.textContent = `admin@localhost:~$ ${ command }`;
  
  history.appendChild(line);
}

// Every time the selection changes, add or remove the .noCursor
// class to show or hide, respectively, the bug square cursor.
// Note this function could also be used to enforce showing always
// a big square cursor by always selecting 1 chracter from the current
// cursor position, unless it's already at the end, in which case the
// #cursor element should be displayed instead.
document.addEventListener('selectionchange', () => {
  if (document.activeElement.id !== 'input') return;
  
  const range = window.getSelection().getRangeAt(0);
  const start = range.startOffset;
  const end = range.endOffset;
  const length = input.textContent.length;
  
  if (end < length) {
    input.classList.add('noCaret');
  } else {
    input.classList.remove('noCaret');
  }
});

input.addEventListener('input', () => {    
  // If we paste HTML, format it as plain text and break it up
  // input individual lines/commands:
  if (input.childElementCount > 0) {
    const lines = input.innerText.replace(/\n$/, '').split('\n');
    const lastLine = lines[lines.length - 1];
    
    for (let i = 0; i <= lines.length - 2; ++i) {
      handleCommand(lines[i]);
    }
  
    input.textContent = lastLine;
    
    focusAndMoveCursorToTheEnd();
  }
  
  // If we delete everything, display the square caret again:
  if (input.innerText.length === 0) {
    input.classList.remove('noCaret');  
  }  
});

document.addEventListener('keydown', (e) => {   
  // If some key is pressed outside the input, focus it and move the cursor
  // to the end:
  if (e.target !== input) focusAndMoveCursorToTheEnd();
});

input.addEventListener('keydown', (e) => {    
  if (e.key === 'Enter') {
    e.preventDefault();
        
    handleCommand(input.textContent);    
    input.textContent = '';
    focusAndMoveCursorToTheEnd();
  }
});

// Set the focus to the input so that you can start typing straigh away:
input.focus();
body {
  background: #000;
  color: #0F0;
  font-family: monospace;
  height: 100vh;
  box-sizing: border-box;
  overflow-x: hidden;
  overflow-y: scroll;
  word-break: break-all;
  margin: 0;
  padding: 16px;
}

#input {
  display: inline;
  outline: none;
  visibility: visible;
}

/*
  If you press the Insert key, the vertical line caret will automatically
  be replaced by a one-character selection.
*/
#input::selection {
  color: #000;
  background: #0F0;
}

#input:empty::before {
  content: ' ';
}

@keyframes blink {
  to {
    visibility: hidden;
  }
}

#input:focus + #caret {
  animation: blink 1s steps(5, start) infinite;
}

#input.noCaret + #caret {
  visibility: hidden;
}

#caret {
  border: 0;
  padding: 0;
  outline: none;
  background-color: #0F0;
  display: inline-block;
  font-family: monospace;
}
<div id="history"></div>

admin@localhost:~$

<div id="input" contenteditable="true"></div><button id="caret" for="input">&nbsp;</button>

通常,侦听键盘事件(keydown / keypress / keyup)来处理文本输入或光标通常是一个坏主意,因为输入值也可以可以通过在其中粘贴或放置文本来进行更新,并且存在很多边缘情况,例如箭头,删除,转义以及诸如全选,复制,粘贴之类的快捷方式...因此,我们试图提供所有按键的详尽清单应该照顾的不是最好的方法。

此外,这不适用于移动设备,因为大多数键会发射相同的值e.key = 'Unidentified'e.which== 229e.keyCode = 229

相反,通常最好依靠其他事件,例如input,并使用KeyboardEvents处理非常具体的键,例如

如果需要检查KeyboardEvent的属性值,例如e.keye.codee.whiche.keyCode,则可以使用https://keyjs.dev。我将很快添加有关此类跨浏览器不兼容性的信息!

Key.js \ JavaScript KeyboardEvent's key codes & key identifiers

免责声明:我是作者。

答案 1 :(得分:0)

我建议使用span而不是div,因为它是一个内联元素,在您的情况下更容易管理。

接下来,您可以通过监听器捕获eatch键盘的条目:

document.body.onkeydown

并告诉他将每个键附加到您可以显示的变量中。

我让您考虑一下您必须管理的所有功能,例如输入或退格事件。

您可以在此处播放并找到您需要的代码:http://keycode.info/

这是一个工作片段:

&#13;
&#13;
var command = "";

document.body.onkeydown = function(e){
    var writePoint = document.getElementById('writePoint');
    command += String.fromCharCode(e.keyCode);
    writePoint.innerHTML = command;
  };
&#13;
.linux-cursor{
  width:7px;
  height:15px;
  background-color:green;
  display:inline-block;
}
&#13;
<span class="title" contenteditable="false" >
  admin@localhost:~$ 
</span>
<span class="write-point" id="writePoint" contenteditable="true" ></span>
<span class="linux-cursor" contenteditable="false"></span>
&#13;
&#13;
&#13;

希望这对你有所帮助,它看起来像一个不错的项目。