在 JS 中,主要操作 DOM 元素时,有任何模式或 Class 样式可以遵循吗?
In JS there is any Pattern or Class style to follow when primarily manipulating DOM Elements?
我正在尝试改进和清理我的代码,这些代码经常有这堆“querySelectors”和全局变量,所以我想知道,在这种情况下 类 有任何模式或用途吗?或者只是在很多功能中分解它并分离文件是 'right' 要做的事吗?
此代码只是我所说的“查询选择器集合”
的一个示例
//variables
const form = document.querySelector("#form_contrato");
const btnRespAluno = document.querySelector("#label_checkbox_resp_aluno");
const btnCombo = document.querySelector("#label_check_combo");
const checkCombo = document.querySelector("#check_combo");
const cursoSelect = document.querySelector("#curso_nome");
const select = document.getElementById("curso_nome");
const comboCurso1 = document.querySelector("#combo_curso_1");
const comboCurso2 = document.querySelector("#combo_curso_2");
const valor = document.querySelector("#curso_valor");
const desconto = document.querySelector("#curso_desconto");
const total = document.querySelector("#curso_total");
const comboTextarea = document.querySelector("#combo_textarea");
const modulos = document.querySelector("#curso_modulos");
const duracao = document.querySelector("#curso_duracao");
const parcelas = document.querySelector("#curso_parcelas");
const vencimento = document.querySelector("#curso_vencimento");
const fieldsetAluno = document.querySelector("#fieldset_aluno");
const loadinContrato = document.querySelector("#loading_contrato");
//Listeners
form.addEventListener("submit", sendForm);
btnRespAluno.addEventListener("input", checkboxRespAluno);
btnCombo.addEventListener("input", inputComboCheckbox);
cursoSelect.addEventListener("change", insertCursoInfo);
comboCurso2.addEventListener("input", insertComboTextarea);
valor.addEventListener("input", insertInputValorTotal);
desconto.addEventListener("input", insertInputValorTotal);
desconto.addEventListener("change", insertComboTextarea);
//Masks
VMasker(document.querySelector("#curso_valor")).maskMoney();
VMasker(document.querySelector("#curso_desconto")).maskMoney();
VMasker(document.querySelector("#resp_cep")).maskPattern("99999-999");
VMasker(document.querySelector("#resp_cpf")).maskPattern("999.999.999-99");
VMasker(document.querySelector("#resp_rg")).maskPattern("99.999.999-S");
VMasker(document.querySelector("#aluno_rg")).maskPattern("99.999.999-S");
VMasker(document.querySelector("#aluno_cep")).maskPattern("99999-999");
function insertInputValue(value, target) {
document.querySelector(target).value = value;
}
function insertInputDateValue(...) {
...
}
function replaceToNonBreakSpaceHifen(...) {
...
}
//and alot of other functions and function calls bellow....
是的,将其分解为模块(或 functions/IIFEs)以获得单独的功能是可行的方法。您不需要任何 class
语法,因为您没有在任何地方创建对象,而且您的听众似乎也不共享任何状态。
所以只注意重复使用的变量(在多个地方使用)。对于其他一切,将变量、addEventListener
调用和侦听器声明放在一起。您甚至可以避免一次性使用临时变量,只需将 document.querySelector("…").addEventListener("…", function(event) { … });
写成一条语句即可。
如果你需要它们,你就需要它们,但它看起来确实很笨重。这实际上取决于您的用例。元素作为变量有时可以动态访问。例如,这里有一个带有一堆值、名称、ID 和类型的表单。在不设置变量的情况下,我们可以循环获取它们的值,tagNames等
document.querySelector('form').addEventListener('submit', (e) => {
e.preventDefault();
[...e.target.querySelectorAll('input, datalist, select, textarea')].forEach(el => {
let val = el.value;
if (['select', 'datalist'].includes(el.tagName.toLowerCase())) val = el.querySelector('option[selected]').value;
console.log('tagname: ', el.tagName, 'name: ', el.name, 'id: ', el.id, 'value: ', val);
})
})
label{
display:block;
margin-bottom:5px;
}
<form>
<label>Name <input type="text" name="customer_name" value="test value" required>
</label>
<label>Phone <input type="tel" value="123-123-1234" name="phone_number">
</label>
<label>Email <input type="email" name="email_address" value="test@value.com" >
</label>
<label>Pickup Date/Time <input type="date" value="2021-10-02" name="pickup_time" required>
</label>
<label>Pickup Place <select id="pickup_place" name="pickup_place">
<option value="" selected="selected">Select One</option><option value="office" selected>Taxi Office</option><option value="town_hall" >Town Hall</option><option value="telepathy" >We'll Guess!</option>
</select>
</label>
<label>Dropoff Place <input type="text" name="dropoff_place" value="test value" required list="destinations">
</label>
<datalist id="destinations">
<option value="Airport"><option value="Beach">
<option selected value="Fred Flinstone's House">
</datalist>
<label>Special Instructions
<textarea name="comments" maxlength="500">Bring chocolate cake</textarea>
</label>
<button>Submit Booking</button>
</form>
事件侦听器函数有时可以合并,测试侦听器 event.type
和目标 event.target
。比如mouseover和mouseout的逻辑可以这样组合,像这样
const onMO = (e) => {
console.log('Listener fired for:', e.type, 'on', e.target.tagName, 'with class name', e.target.getAttribute('class'));
}
let m = document.querySelector('.mo');
m.addEventListener('mouseover', onMO);
m.addEventListener('mouseout', onMO)
.mo {
padding: 20px;
text-align: center;
background: #f0f0f0;
}
<div class='mo'>Mouse in and out</div>
我正在尝试改进和清理我的代码,这些代码经常有这堆“querySelectors”和全局变量,所以我想知道,在这种情况下 类 有任何模式或用途吗?或者只是在很多功能中分解它并分离文件是 'right' 要做的事吗?
此代码只是我所说的“查询选择器集合”
的一个示例 //variables
const form = document.querySelector("#form_contrato");
const btnRespAluno = document.querySelector("#label_checkbox_resp_aluno");
const btnCombo = document.querySelector("#label_check_combo");
const checkCombo = document.querySelector("#check_combo");
const cursoSelect = document.querySelector("#curso_nome");
const select = document.getElementById("curso_nome");
const comboCurso1 = document.querySelector("#combo_curso_1");
const comboCurso2 = document.querySelector("#combo_curso_2");
const valor = document.querySelector("#curso_valor");
const desconto = document.querySelector("#curso_desconto");
const total = document.querySelector("#curso_total");
const comboTextarea = document.querySelector("#combo_textarea");
const modulos = document.querySelector("#curso_modulos");
const duracao = document.querySelector("#curso_duracao");
const parcelas = document.querySelector("#curso_parcelas");
const vencimento = document.querySelector("#curso_vencimento");
const fieldsetAluno = document.querySelector("#fieldset_aluno");
const loadinContrato = document.querySelector("#loading_contrato");
//Listeners
form.addEventListener("submit", sendForm);
btnRespAluno.addEventListener("input", checkboxRespAluno);
btnCombo.addEventListener("input", inputComboCheckbox);
cursoSelect.addEventListener("change", insertCursoInfo);
comboCurso2.addEventListener("input", insertComboTextarea);
valor.addEventListener("input", insertInputValorTotal);
desconto.addEventListener("input", insertInputValorTotal);
desconto.addEventListener("change", insertComboTextarea);
//Masks
VMasker(document.querySelector("#curso_valor")).maskMoney();
VMasker(document.querySelector("#curso_desconto")).maskMoney();
VMasker(document.querySelector("#resp_cep")).maskPattern("99999-999");
VMasker(document.querySelector("#resp_cpf")).maskPattern("999.999.999-99");
VMasker(document.querySelector("#resp_rg")).maskPattern("99.999.999-S");
VMasker(document.querySelector("#aluno_rg")).maskPattern("99.999.999-S");
VMasker(document.querySelector("#aluno_cep")).maskPattern("99999-999");
function insertInputValue(value, target) {
document.querySelector(target).value = value;
}
function insertInputDateValue(...) {
...
}
function replaceToNonBreakSpaceHifen(...) {
...
}
//and alot of other functions and function calls bellow....
是的,将其分解为模块(或 functions/IIFEs)以获得单独的功能是可行的方法。您不需要任何 class
语法,因为您没有在任何地方创建对象,而且您的听众似乎也不共享任何状态。
所以只注意重复使用的变量(在多个地方使用)。对于其他一切,将变量、addEventListener
调用和侦听器声明放在一起。您甚至可以避免一次性使用临时变量,只需将 document.querySelector("…").addEventListener("…", function(event) { … });
写成一条语句即可。
如果你需要它们,你就需要它们,但它看起来确实很笨重。这实际上取决于您的用例。元素作为变量有时可以动态访问。例如,这里有一个带有一堆值、名称、ID 和类型的表单。在不设置变量的情况下,我们可以循环获取它们的值,tagNames等
document.querySelector('form').addEventListener('submit', (e) => {
e.preventDefault();
[...e.target.querySelectorAll('input, datalist, select, textarea')].forEach(el => {
let val = el.value;
if (['select', 'datalist'].includes(el.tagName.toLowerCase())) val = el.querySelector('option[selected]').value;
console.log('tagname: ', el.tagName, 'name: ', el.name, 'id: ', el.id, 'value: ', val);
})
})
label{
display:block;
margin-bottom:5px;
}
<form>
<label>Name <input type="text" name="customer_name" value="test value" required>
</label>
<label>Phone <input type="tel" value="123-123-1234" name="phone_number">
</label>
<label>Email <input type="email" name="email_address" value="test@value.com" >
</label>
<label>Pickup Date/Time <input type="date" value="2021-10-02" name="pickup_time" required>
</label>
<label>Pickup Place <select id="pickup_place" name="pickup_place">
<option value="" selected="selected">Select One</option><option value="office" selected>Taxi Office</option><option value="town_hall" >Town Hall</option><option value="telepathy" >We'll Guess!</option>
</select>
</label>
<label>Dropoff Place <input type="text" name="dropoff_place" value="test value" required list="destinations">
</label>
<datalist id="destinations">
<option value="Airport"><option value="Beach">
<option selected value="Fred Flinstone's House">
</datalist>
<label>Special Instructions
<textarea name="comments" maxlength="500">Bring chocolate cake</textarea>
</label>
<button>Submit Booking</button>
</form>
事件侦听器函数有时可以合并,测试侦听器 event.type
和目标 event.target
。比如mouseover和mouseout的逻辑可以这样组合,像这样
const onMO = (e) => {
console.log('Listener fired for:', e.type, 'on', e.target.tagName, 'with class name', e.target.getAttribute('class'));
}
let m = document.querySelector('.mo');
m.addEventListener('mouseover', onMO);
m.addEventListener('mouseout', onMO)
.mo {
padding: 20px;
text-align: center;
background: #f0f0f0;
}
<div class='mo'>Mouse in and out</div>