要说我做的和其他人不同的事情是,我把光标的移动给禁用了。
文档们
- 官网 xtermjs.org/docs/
- 好人总结的文档1:blog.csdn.net/weixin_4213…
- 好人总结的文档2:juejin.cn/post/684490…
- 下面是一些例子:juejin.cn/post/691891…
- blog.csdn.net/duansamve/a…
- www.cnblogs.com/goloving/p/…
- www.cnblogs.com/goloving/p/…
- www.cnblogs.com/goloving/p/…
- blog.csdn.net/qq_31126175…
通讯方式
都是websocket这是肯定,只是有两种形式
一种是不管输入啥都传给后端
一种是按了回车后再把输入的内容传给后端,这边是第二种
构建变量
term = null; //终端
websocket = null;
curr_line = "";//要发送给后端的字符串
占满元素
import { FitAddon } from "xterm-addon-fit";
this.term = new Terminal({
//占满高
rows: Math.ceil(
(document.getElementsByClassName("container-children")[0].clientHeight -
150) /
14
),
});
const fitAddon = new FitAddon();
this.term.loadAddon(fitAddon);
fitAddon.fit(); //占满宽
光标不准
左移通常会移两格,还可以上下移动,瞎跑
所以我干脆把上下左右的功能去掉
我试着用document.onkeydown去阻止,没用,心态有点崩
我在文档里发现attachCustomKeyEventHandler
于是就实现了禁用上下左右按键移动光标的方法了
this.term.attachCustomKeyEventHandler((e) => {
console.log({ e });
// e = e.target;
var keyCode = e.keyCode || e.which || e.charCode;
const moveKey = [37, 38, 39, 40].includes(keyCode);
if (moveKey) return false;
});
输入
// 添加事件监听器,支持输入方法
this.term.onKey((e) => {
const printable =
!e.domEvent.altKey &&
!e.domEvent.altGraphKey &&
!e.domEvent.ctrlKey &&
!e.domEvent.metaKey;
if (e.domEvent.keyCode === 13) {
//回车
this.Send(term, this.curr_line);
this.term.prompt();
this.curr_line = "";
} else if (e.domEvent.keyCode === 8) {
// back 删除的情况
if (this.term._core.buffer.x > 2) {
if (this.curr_line.length) {
this.curr_line = this.curr_line.slice(0, this.curr_line.length - 1);
this.term.write("\b \b");
} else {
}
}
} else if (printable) {
//添加字符
this.curr_line += e.key;
this.term.write(e.key);
}
this.term.focus();
});
this.term.onData((key) => {
// 粘贴的情况
if (key.length > 1) {
this.term.write(key);
this.curr_line += key;
}
});
Send = (term, message) => {
this.websocket.send(message);
};
websocket
initWebsock = () => {
// let websocket = this.websocket;
let term = this.term;
let token = getToken();
this.websocket = new WebSocket("ws://" + window._CONFIG.WsSsh, token);
this.websocket.onopen = function (evt) {
term.write("connect");
};
this.websocket.onclose = function (evt) {
term.write("exit");
};
this.websocket.onmessage = function (evt) {
term.write(evt.data);
};
this.websocket.onerror = function (evt) {
term.write("connect fail err:" + evt.data);
};
};
全代码
import React, { Component } from "react";
import { Terminal } from "xterm";
import "xterm/css/xterm.css";
import { getToken } from "@libs/auth";
import { FitAddon } from "xterm-addon-fit";
export default class WebTerminal extends Component {
term = null;
websocket = null;
curr_line = "";
componentDidMount() {
let term = this.term;
this.term = new Terminal({
fontFamily: 'Menlo, Monaco, "Courier New", monospace',
fontWeight: 400,
fontSize: 14,
rows: Math.ceil(
(document.getElementsByClassName("container-children")[0].clientHeight -
150) /
14
),
});
this.term.open(document.getElementById("terminal"));
this.term.focus();
this.term.prompt = (_) => {
this.term.write("\r\n\x1b[33m$\x1b[0m ");
};
this.term.prompt();
const fitAddon = new FitAddon();
this.term.loadAddon(fitAddon);
fitAddon.fit();
this.term.prompt();
this.term.attachCustomKeyEventHandler((e) => {
console.log({ e });
// e = e.target;
var keyCode = e.keyCode || e.which || e.charCode;
const moveKey = [37, 38, 39, 40].includes(keyCode);
if (moveKey) return false;
});
// 添加事件监听器,支持输入方法
this.term.onKey((e) => {
const printable =
!e.domEvent.altKey &&
!e.domEvent.altGraphKey &&
!e.domEvent.ctrlKey &&
!e.domEvent.metaKey;
if (e.domEvent.keyCode === 13) {
this.Send(term, this.curr_line);
this.term.prompt();
this.curr_line = "";
} else if (e.domEvent.keyCode === 8) {
// back 删除的情况
if (this.term._core.buffer.x > 2) {
if (this.curr_line.length) {
this.curr_line = this.curr_line.slice(0, this.curr_line.length - 1);
this.term.write("\b \b");
} else {
}
}
} else if (printable) {
this.curr_line += e.key;
this.term.write(e.key);
}
this.term.focus();
console.log(1, "print", e.key);
});
this.term.onData((key) => {
// 粘贴的情况
if (key.length > 1) {
this.term.write(key);
this.curr_line += key;
}
});
this.initWebsock();
}
componentWillUnmount() {
this.term.dispose();
this.websocket.close()
}
initWebsock = () => {
// let websocket = this.websocket;
let term = this.term;
let token = getToken();
this.websocket = new WebSocket("ws://" + window._CONFIG.WsSsh, token);
this.websocket.onopen = function (evt) {
term.write("connect");
};
this.websocket.onclose = function (evt) {
term.write("exit");
};
this.websocket.onmessage = function (evt) {
term.write(evt.data);
};
this.websocket.onerror = function (evt) {
term.write("connect fail err:" + evt.data);
};
};
// prompt = (term) => {
// this.term.write("\r\n~$ ");
// };
Send = (term, message) => {
this.websocket.send(message);
};
render() {
return (
<div className="container-children" style={{ height: "100%" }}>
<div id="terminal" style={{ width: "100%" }}></div>
</div>
);
}
}