javascript - 优化和重构在连接字符串(Javascript)中交换值的不同样式的按钮组?
问题描述
我正在涉足 JavaScript(和 CSS)。在这里提问的新手;接受反馈。我发帖的部分原因是为了帮助其他人找到我面临的挑战的答案。我找不到我试图通过谷歌搜索和挠头做的事情的例子。
代码做我想做的事。有哪些方法可以优化和重构它?
多个按钮组...独立样式...每个都可以通过单击更新连接字符串的各个部分。
https://jsfiddle.net/ncarlton/by8ragpc/1/
我正在使用 HTML、CSS 和 JavaScript。
代码的目标包括:
- 根据用户选择(在我的例子中是按钮)连接变量。
- 从默认选项开始。
- 独立设置每个按钮组的样式。这是因为这三个变量将存在于我最终实现的 GUI 的不同区域......它们代表不同的功能。该模型的每个按钮组的样式都不同。
- 任何按钮单击都会更新连接的字符串;没有“提交”按钮。
- 更新替换了连接字符串各自位置的值......所以每个按钮单击“交换”前一个值(不要重新排列第一个、中间、最后一个的顺序)。
JS:
//make default variables in UPPER to show that values should come from .js and not from .html
let _firstName = "MARTIN";
let _middleName = "LUTHER";
let _lastName = "KING";
//build the full Name
let fullName = _firstName + " " + _middleName + " " + _lastName;
//replace the <span>Need A. Change with the default values
//default values start as UPPERcase to show they came from variables and not innerHTML
document.getElementById("myName").innerHTML = fullName;
//swap out any of the name parts by a single button click: first, middle, last
//also style the buttons in each group to look different
function changeName() {
//First Name Selections and Style changes
const btnFirstSelect = function() {
this.parentNode.getElementsByClassName("btnSelFirst")[0].classList.remove("btnSelFirst");
this.classList.add("btnSelFirst");
_firstName = this.innerHTML;
fullName = _firstName + " " + _middleName + " " + _lastName;
document.getElementById("myName").innerHTML = fullName;
};
document.querySelectorAll(".btnsFirstName .btnFirst").forEach(btnFirst => btnFirst.addEventListener('click', btnFirstSelect));
//Middle Name Selections and Style changes
const btnMiddleSelect = function() {
this.parentNode.getElementsByClassName("btnSelMiddle")[0].classList.remove("btnSelMiddle");
this.classList.add("btnSelMiddle");
_middleName = this.innerHTML;
fullName = _firstName + " " + _middleName + " " + _lastName;
document.getElementById("myName").innerHTML = fullName;
};
document.querySelectorAll(".btnsMiddleName .btnMiddle").forEach(btnMiddle => btnMiddle.addEventListener('click', btnMiddleSelect));
//Last Name Selections and Syle changes
const btnLastSelect = function() {
this.parentNode.getElementsByClassName("btnSelLast")[0].classList.remove("btnSelLast");
this.classList.add("btnSelLast");
_lastName = this.innerHTML;
fullName = _firstName + " " + _middleName + " " + _lastName;
document.getElementById("myName").innerHTML = fullName;
};
document.querySelectorAll(".btnsLastName .btnLast").forEach(btnLast => btnLast.addEventListener('click', btnLastSelect));
}
window.onload = changeName;
//click a button and then reload the console with this
//confirm your selection changed the var by grabbing the innerHTML
//confirm the full name was also rebuilt
console.log(_firstName, _middleName, _lastName, fullName);
HMTL:
<body>
<h4>Name Builder from Button Choices</h4>
<div>My name is: <span id="myName">Need A. Change</span>
</div>
<hr />
<div class="btnsFirstName ">First name Choices:
<button class="btnFirst btnSelFirst">Martin</button>
<button class="btnFirst">Barack</button>
<button class="btnFirst">Jelly</button>
</div>
<div class="btnsMiddleName">Middle Name Choices:
<button class="btnMiddle btnSelMiddle">Luther</button>
<button class="btnMiddle">Hussein</button>
<button class="btnMiddle">Roll</button>
</div>
<div class="btnsLastName">Last Name Choices:
<button class="btnLast btnSelLast">King</button>
<button class="btnLast">Obama</button>
<button class="btnLast">Morton</button>
</div>
<p>(Each button click should build the full name by swapping out the value of the clicked button in the correct position. Ideally the button groups would change styles independently too.)</p>
</body>
CSS:
.btnFirst,
.btnMiddle,
.btnLast {
background-color: grey;
color: green;
}
.btnSelFirst {
background-color: black;
color: white;
outline: none;
}
.btnFirst:hover {
background-color: black;
color: white;
outline: none;
}
.btnSelMiddle {
background-color: white;
color: black;
outline: none;
}
.btnMiddle:hover {
background-color: white;
color: black;
outline: none;
}
.btnSelLast {
background-color: pink;
color: blue;
outline: none;
}
.btnLast:hover {
background-color: pink;
color: blue;
outline: none;
}
body {
font-family: Helvetica, Arial, Sans-Serif;
}
使用以下问题,我有点“添加”额外的冗余功能代码以使按钮以我想要的方式“工作”:如何将 javascript 应用于多个按钮组
我尝试了一些方法来减少代码冗余,但我希望学习各种技术。
解决方案
嘿,我想出了一些东西。
HTML
要点:
<button ... name="firstname">
:
- name 属性是指这组按钮,因为 lastname midname 和 firstname 使用一个函数
<button ... onClick="changeName(this)">
:
- 虽然这似乎是重复的,但当你做出反应时,这就是你在反应中的做法。所以如果你要学习反应是一件好事
- AddEventListener 可以隐藏在代码中,因此可能会对查找造成挑战
- 确保 js 附加在末尾
<body>
<h4>Name Builder from Button Choices</h4>
<div>My name is: <span id="myName">Need A. Change</span>
</div>
<hr />
<div class="btnsFirstName ">First name Choices:
<button class="btnFirst active" name="firstname" onClick="changeName(this)">Martin</button>
<button class="btnFirst" name="firstname" onClick="changeName(this)">Barack</button>
<button class="btnFirst" name="firstname" onClick="changeName(this)">Jelly</button>
</div>
<div class="btnsMiddleName">Middle Name Choices:
<button class="btnMiddle active" name="middlename" onClick="changeName(this)">Luther</button>
<button class="btnMiddle" name="middlename" onClick="changeName(this)">Hussein</button>
<button class="btnMiddle" name="middlename" onClick="changeName(this)">Roll</button>
</div>
<div class="btnsLastName">Last Name Choices:
<button class="btnLast active" name="lastname" onClick="changeName(this)">King</button>
<button class="btnLast" name="lastname" onClick="changeName(this)">Obama</button>
<button class="btnLast" name="lastname" onClick="changeName(this)">Morton</button>
</div>
<p>(Each button click should build the full name by swapping out the value of the clicked button in the correct position. Ideally the button groups would change styles independently too.)</p>
<script src="./script.js"></script>
</body>
JS
要点:
- 创建一个函数来更新 dom 中的全名
- 合并所有按钮的点击处理程序
//make default variables in UPPER to show that values should come from .js and not from .html
let _firstName = "MARTIN";
let _middleName = "LUTHER";
let _lastName = "KING";
// set as a func to conveniently update fullname in the DOM
const setFullname = () => {
document.getElementById("myName").innerHTML = `${_firstName} ${_middleName} ${_lastName}`;
}
// refer this function in HTML, example:
// <button class="btnFirst" onClick="changeName(this)">Jelly</button>
const changeName = el => {
el.parentNode.getElementsByClassName("active")[0].classList.remove("active");
el.classList.add("active");
switch(el.name) {
// el.name is the <button ... name="firstname">
case 'firstname':
_firstName = el.innerHTML;
break;
case 'middlename':
_middleName = el.innerHTML;
break;
case 'lastname':
_lastName = el.innerHTML;
break;
}
setFullname();
}
// call once in the beginning to set default
setFullname()
console.log("firstname: ", _firstName)
console.log("middlename: ", _middleName)
console.log("lastname: ", _lastName)
CSS
要点:
- 不要重复,如果可以的话,将相同的样式组合在一起。
- CSS
cascading style sheet
意味着继承起着重要作用,样式定义从.element
可以级联到.element.active
,element:hover
等等
.btnFirst,
.btnMiddle,
.btnLast {
background-color: grey;
color: green;
/* no need to set same css on every definition
* this will be also inherited to .btnFirst.active
* and so on
* */
outline: none;
}
.btnFirst.active,
.btnFirst:hover {
background-color: black;
color: white;
}
.btnMiddle.active,
.btnMiddle:hover {
background-color: white;
color: black;
}
.btnLast.active,
.btnLast:hover {
background-color: pink;
color: blue;
}
body {
font-family: Helvetica, Arial, Sans-Serif;
}
推荐阅读
- android - 没有找到 id 到 webview 的视图
- wpf - 如何在 WPF 中访问 BLE Midi 设备?
- mongodb - MongoDB使用`db.TestCollection.find({}).count()`查询Collection的计数报错
- rust - 来自静态和可变 C 指针的 Rust 引用?
- powerbi-desktop - 安装后无法打开 Microsoft Power BI Desktop
- java - 放弃将数据连接到交易视图
- python - Python列表处理
- reactjs - 按钮单击未在 React 上呈现输入字段
- javascript - 使用 Javascript / Node Js 拆分匹配数组和不匹配数组
- react-native - 如何渲染
- 使用 react-native-render-html 进行适当的缩进和标签?