如何在HTML CSS js创建的键盘符号和数字之间切换?



我跟随一个视频创建了这个虚拟键盘,到现在为止我学到了很多。在创建的键盘,我想知道如何取代"完成"切换一行符号而不是关闭键盘的键。

我还希望它切换回字母键盘时,单击符号布局上的任何键。

我被困在改变布局。

const Keyboard = {
elements: {
main: null,
keysContainer: null,
keys: []
},
eventHandlers: {
oninput: null,
onclose: null
},
properties: {
value: "",
capsLock: false
},
init() {
// Create main elements
this.elements.main = document.createElement("div");
this.elements.keysContainer = document.createElement("div");
// Setup main elements
this.elements.main.classList.add("keyboard", "keyboard--hidden");
this.elements.keysContainer.classList.add("keyboard__keys");
this.elements.keysContainer.appendChild(this._createKeys());

this.elements.keys = this.elements.keysContainer.querySelectorAll(".keyboard__key");
// Add to DOM
this.elements.main.appendChild(this.elements.keysContainer);
document.body.appendChild(this.elements.main);
// Automatically use keyboard for elements with .use-keyboard-input
document.querySelectorAll(".use-keyboard-input").forEach(element => {
element.addEventListener("focus", () => {
this.open(element.value, currentValue => {
element.value = currentValue;
});
});
});
},
_createKeys() {
const fragment = document.createDocumentFragment();
const keyLayout = [
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "backspace",
"q", "w", "e", "r", "t", "y", "u", "i", "o", "p",
"caps", "a", "s", "d", "f", "g", "h", "j", "k", "l", "enter",
"done", "z", "x", "c", "v", "b", "n", "m", ",", ".", "?",
"space"
];
const SymbolLayout = [
"!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "backspace",
"q", "w", "e", "r", "t", "y", "u", "i", "o", "p",
"caps", "a", "s", "d", "f", "g", "h", "j", "k", "l", "enter",
"done", "z", "x", "c", "v", "b", "n", "m", ",", ".", "?",
"space"
];
// Creates HTML for an icon
const createIconHTML = (icon_name) => {
return `<i class="material-icons">${icon_name}</i>`;
};
keyLayout.forEach(key => {
const keyElement = document.createElement("button");
const insertLineBreak = ["backspace", "p", "enter", "?"].indexOf(key) !== -1;

// Add attributes/classes
keyElement.setAttribute("type", "button");
keyElement.classList.add("keyboard__key");
switch (key) {
case "backspace":
keyElement.classList.add("keyboard__key--wide");
keyElement.innerHTML = createIconHTML("backspace");
keyElement.addEventListener("click", () => {
this.properties.value = this.properties.value.substring(0, this.properties.value.length - 1);
this._triggerEvent("oninput");
});
break;
case "caps":
keyElement.classList.add("keyboard__key--wide", "keyboard__key--activatable");
keyElement.innerHTML = createIconHTML("keyboard_capslock");
keyElement.addEventListener("click", () => {
this._toggleCapsLock();
keyElement.classList.toggle("keyboard__key--active", this.properties.capsLock);
});
break;
case "enter":
keyElement.classList.add("keyboard__key--wide");
keyElement.innerHTML = createIconHTML("keyboard_return");
keyElement.addEventListener("click", () => {
this.properties.value += "n";
this._triggerEvent("oninput");
});
break;
case "space":
keyElement.classList.add("keyboard__key--extra-wide");
keyElement.innerHTML = createIconHTML("space_bar");
keyElement.addEventListener("click", () => {
this.properties.value += " ";
this._triggerEvent("oninput");
});
break;
case "done":
keyElement.classList.add("keyboard__key--wide", "keyboard__key--dark");
keyElement.innerHTML = createIconHTML("check_circle");
keyElement.addEventListener("click", () => {
this.close();
this._triggerEvent("onclose");
});
break;
default:
keyElement.textContent = key.toLowerCase();
keyElement.addEventListener("click", () => {
this.properties.value += this.properties.capsLock ? key.toUpperCase() : key.toLowerCase();
this._triggerEvent("oninput");
});
break;
}
fragment.appendChild(keyElement);
if (insertLineBreak) {
fragment.appendChild(document.createElement("br"));
}
});
return fragment;
},
_triggerEvent(handlerName) {
if (typeof this.eventHandlers[handlerName] == "function") {
this.eventHandlers[handlerName](this.properties.value);
}
},
_toggleCapsLock() {
this.properties.capsLock = !this.properties.capsLock;
for (const key of this.elements.keys) {
if (key.childElementCount === 0) {
key.textContent = this.properties.capsLock ? key.textContent.toUpperCase() : key.textContent.toLowerCase();
}
}
},
open(initialValue, oninput, onclose) {
this.properties.value = initialValue || "";
this.eventHandlers.oninput = oninput;
this.eventHandlers.onclose = onclose;
this.elements.main.classList.remove("keyboard--hidden");
},
close() {
this.properties.value = "";
this.eventHandlers.oninput = oninput;
this.eventHandlers.onclose = onclose;
this.elements.main.classList.add("keyboard--hidden");
}
};
window.addEventListener("DOMContentLoaded", function() {
Keyboard.init();
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: url(/bg.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
background: rgb(54, 49, 49);
}
.use-keyboard-input {
width: 100%;
background: rgba(255, 255, 255, 0.678);
border: 2px solid rgb(107, 104, 104);
border-radius: 10%;
}
h1 {
margin-top: 50%;
font-family: 'Roboto', sans-serif;
margin-bottom: 20px;
}
.keyboard {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
padding: 5px 0;
background: transparent;
user-select: none;
transition: bottom 0.4s;
}
.keyboard--hidden {
bottom: -100%;
}
.keyboard__keys {
text-align: center;
}
.keyboard__key {
height: 45px;
width: 6%;
max-width: 90px;
margin: 3px;
border-radius: 10px;
border: none;
background: rgba(218, 190, 218, 0.589);
color: #0c0101;
font-size: 1.05rem;
outline: none;
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
vertical-align: top;
padding: 0;
-webkit-tap-highlight-color: transparent;
position: relative;
}
.keyboard__key::after {
content: '';
height: 20px;
width: 95%;
text-align: center;
-webkit-border-radius: 40px;
border-radius: 40px;
background: -webkit-linear-gradient(bottom, rgba(255, 255, 255, 0.9) 0%, rgba(255, 255, 255, 0) 50%);
background: -moz-linear-gradient(bottom, rgba(255, 255, 255, 0.9) 0%, rgba(255, 255, 255, 0) 50%);
background: -o-linear-gradient(bottom, rgba(255, 255, 255, 0.9) 0%, rgba(255, 255, 255, 0) 50%);
background: linear-gradient(bottom, rgba(255, 255, 255, 0.9) 0%, rgba(255, 255, 255, 0) 50%);
display: block;
position: absolute;
top: 1px;
left: 5px;
opacity: 0.3;
}
.keyboard__key:active {
background: rgba(255, 255, 255, 0.12);
}
.keyboard__key--wide {
width: 12%;
}
.keyboard__key--extra-wide {
width: 36%;
max-width: 500px;
}
.keyboard__key--dark {
background: rgba(0, 0, 0, 0.25);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Virtual Keyboard using HTML5 &amp; JS Example</title>
<meta name="author" content="Codeconvey" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@500&display=swap" rel="stylesheet">
<!-- Style CSS -->
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<section>
<div class="rt-container">
<div class="col-rt-12">
<div class="Scriptcontent">
<h1>Click Here to Type</h1>
<textarea class="use-keyboard-input"></textarea>
<script src="js/keyboard.js"></script>
</div>
</div>
</div>
</section>
</body>
</html>

我要做的是让键盘布局成为函数的参数…这样你的代码可以做任何键盘,或者几乎因为操作将保持硬编码。

const keyLayout = [
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "backspace",
"q", "w", "e", "r", "t", "y", "u", "i", "o", "p",
"caps", "a", "s", "d", "f", "g", "h", "j", "k", "l", "enter",
"done", "z", "x", "c", "v", "b", "n", "m", ",", ".", "?",
"space"
];
const SymbolLayout = [
"!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "backspace",
"q", "w", "e", "r", "t", "y", "u", "i", "o", "p",
"caps", "a", "s", "d", "f", "g", "h", "j", "k", "l", "enter",
"done", "z", "x", "c", "v", "b", "n", "m", ",", ".", "?",
"space"
];
const Keyboard = {
elements: {
main: null,
keysContainer: null,
keys: []
},
eventHandlers: {
oninput: null,
onclose: null
},
properties: {
value: "",
capsLock: false
},
init() {
// Create main elements
this.elements.main = document.createElement("div");
this.elements.keysContainer = document.createElement("div");
// Setup main elements
this.elements.main.classList.add("keyboard", "keyboard--hidden");
this.elements.keysContainer.classList.add("keyboard__keys");
this.setLayout(keyLayout);
// Add to DOM
this.elements.main.appendChild(this.elements.keysContainer);
document.body.appendChild(this.elements.main);
// Automatically use keyboard for elements with .use-keyboard-input
document.querySelectorAll(".use-keyboard-input").forEach(element => {
element.addEventListener("focus", () => {
this.open(element.value, currentValue => {
element.value = currentValue;
});
});
});
},
setLayout(layout) {
this.elements.keysContainer.innerHTML = "";
this.elements.keysContainer.appendChild(this._createKeys(layout));
this.elements.keys = this.elements.keysContainer.querySelectorAll(".keyboard__key");
},
_createKeys(layout) {
const fragment = document.createDocumentFragment();
// Creates HTML for an icon
const createIconHTML = (icon_name) => {
return `<i class="material-icons">${icon_name}</i>`;
};
layout.forEach(key => {
const keyElement = document.createElement("button");
const insertLineBreak = ["backspace", "p", "enter", "?"].indexOf(key) !== -1;

// Add attributes/classes
keyElement.setAttribute("type", "button");
keyElement.classList.add("keyboard__key");
switch (key) {
case "backspace":
keyElement.classList.add("keyboard__key--wide");
keyElement.innerHTML = createIconHTML("backspace");
keyElement.addEventListener("click", () => {
this.properties.value = this.properties.value.substring(0, this.properties.value.length - 1);
this._triggerEvent("oninput");
});
break;
case "caps":
keyElement.classList.add("keyboard__key--wide", "keyboard__key--activatable");
keyElement.innerHTML = createIconHTML("keyboard_capslock");
keyElement.addEventListener("click", () => {
this._toggleCapsLock();
keyElement.classList.toggle("keyboard__key--active", this.properties.capsLock);
});
break;
case "enter":
keyElement.classList.add("keyboard__key--wide");
keyElement.innerHTML = createIconHTML("keyboard_return");
keyElement.addEventListener("click", () => {
this.properties.value += "n";
this._triggerEvent("oninput");
});
break;
case "space":
keyElement.classList.add("keyboard__key--extra-wide");
keyElement.innerHTML = createIconHTML("space_bar");
keyElement.addEventListener("click", () => {
this.properties.value += " ";
this._triggerEvent("oninput");
});
break;
case "done":
keyElement.classList.add("keyboard__key--wide", "keyboard__key--dark");
keyElement.innerHTML = createIconHTML("check_circle");
keyElement.addEventListener("click", () => {
//this.close();
this.setLayout(SymbolLayout);
//this._triggerEvent("onclose");
});
break;
default:
keyElement.textContent = key.toLowerCase();
keyElement.addEventListener("click", () => {
this.properties.value += this.properties.capsLock ? key.toUpperCase() : key.toLowerCase();
this._triggerEvent("oninput");
});
break;
}
fragment.appendChild(keyElement);
if (insertLineBreak) {
fragment.appendChild(document.createElement("br"));
}
});
return fragment;
},
_triggerEvent(handlerName) {
if (typeof this.eventHandlers[handlerName] == "function") {
this.eventHandlers[handlerName](this.properties.value);
}
},
_toggleCapsLock() {
this.properties.capsLock = !this.properties.capsLock;
for (const key of this.elements.keys) {
if (key.childElementCount === 0) {
key.textContent = this.properties.capsLock ? key.textContent.toUpperCase() : key.textContent.toLowerCase();
}
}
},
open(initialValue, oninput, onclose) {
this.properties.value = initialValue || "";
this.eventHandlers.oninput = oninput;
this.eventHandlers.onclose = onclose;
this.elements.main.classList.remove("keyboard--hidden");
},
close() {
this.properties.value = "";
this.eventHandlers.oninput = oninput;
this.eventHandlers.onclose = onclose;
this.elements.main.classList.add("keyboard--hidden");
}
};
window.addEventListener("DOMContentLoaded", function() {
Keyboard.init();
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: url(/bg.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
background: rgb(54, 49, 49);
}
.use-keyboard-input {
width: 100%;
background: rgba(255, 255, 255, 0.678);
border: 2px solid rgb(107, 104, 104);
border-radius: 10%;
}
h1 {
margin-top: 50%;
font-family: 'Roboto', sans-serif;
margin-bottom: 20px;
}
.keyboard {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
padding: 5px 0;
background: transparent;
user-select: none;
transition: bottom 0.4s;
}
.keyboard--hidden {
bottom: -100%;
}
.keyboard__keys {
text-align: center;
}
.keyboard__key {
height: 45px;
width: 6%;
max-width: 90px;
margin: 3px;
border-radius: 10px;
border: none;
background: rgba(218, 190, 218, 0.589);
color: #0c0101;
font-size: 1.05rem;
outline: none;
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
vertical-align: top;
padding: 0;
-webkit-tap-highlight-color: transparent;
position: relative;
}
.keyboard__key::after {
content: '';
height: 20px;
width: 95%;
text-align: center;
-webkit-border-radius: 40px;
border-radius: 40px;
background: -webkit-linear-gradient(bottom, rgba(255, 255, 255, 0.9) 0%, rgba(255, 255, 255, 0) 50%);
background: -moz-linear-gradient(bottom, rgba(255, 255, 255, 0.9) 0%, rgba(255, 255, 255, 0) 50%);
background: -o-linear-gradient(bottom, rgba(255, 255, 255, 0.9) 0%, rgba(255, 255, 255, 0) 50%);
background: linear-gradient(bottom, rgba(255, 255, 255, 0.9) 0%, rgba(255, 255, 255, 0) 50%);
display: block;
position: absolute;
top: 1px;
left: 5px;
opacity: 0.3;
}
.keyboard__key:active {
background: rgba(255, 255, 255, 0.12);
}
.keyboard__key--wide {
width: 12%;
}
.keyboard__key--extra-wide {
width: 36%;
max-width: 500px;
}
.keyboard__key--dark {
background: rgba(0, 0, 0, 0.25);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Virtual Keyboard using HTML5 &amp; JS Example</title>
<meta name="author" content="Codeconvey" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@500&display=swap" rel="stylesheet">
<!-- Style CSS -->
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<section>
<div class="rt-container">
<div class="col-rt-12">
<div class="Scriptcontent">
<h1>Click Here to Type</h1>
<textarea class="use-keyboard-input"></textarea>
<script src="js/keyboard.js"></script>
</div>
</div>
</div>
</section>
</body>
</html>

所以我添加了setLayout函数,它接收布局并使用_createKeys应用它

然后在done键事件中添加对setLayout的调用。

如果你想听我的建议,我会摆脱每个键上的所有事件,而是把一个在容器上,当点击的目标是子键时触发。使用键上的innerText或data属性来识别它。然后在键盘上发出一个可以被监听的事件,这样您就不用触摸键盘代码来添加单击的功能。

最新更新