我正在尝试使用javscript创建一个滑块。我想有两个函数 - 第一个,parseDom()
,应该负责从DOM获取元素;第二个configureRange()
应负责设置范围属性,例如min
和max
值。这两个函数都在匿名函数内部调用,该函数被分配给window.onload
变量。
function parseDom() {
var main = document.getElementById('main');
main.classList.add('red');
// red class added - main selector is ok
var rangeContainer = main.querySelector('.range-container');
rangeContainer.classList.add('green');
// green class added - rangeContainer selector is ok
var rangeInput = rangeContainer.querySelector('.range-input');
rangeInput.classList.add('crosshair');
// crosshair class added - rangeInput selector is ok
}
function configureRange(){
rangeInput.classList.add('pointer');
rangeInput.setAttribute('min', '0');
}
window.onload = function(){
parseDom();
configureRange();
}
但是,parseDom()
中的变量无法从configureRange()
加入,因为这些函数中的变量位于不同的范围内。所以configureRange()
中的代码不起作用。我可以在一个函数中而不是两个函数中完成所有操作,但这会使代码变得混乱。如何创建良好的模块化解决方案?
代码在这里: https://codepen.io/t411tocreate/pen/oeKwbW?editors=1111
答案 0 :(得分:2)
最简单的事情可能是通过configureRange
调用它来传递parseDom
所需的信息:
function parseDom() {
var main = document.getElementById('main');
main.classList.add('red');
// red class added - main selector is ok
var rangeContainer = main.querySelector('.range-container');
rangeContainer.classList.add('green');
// green class added - rangeContainer selector is ok
var rangeInput = rangeContainer.querySelector('.range-input');
rangeInput.classList.add('crosshair');
// crosshair class added - rangeInput selector is ok
configureRange(rangeInput); // <==== Added call
}
function configureRange(rangeInput){ // <==== Note new parameter
rangeInput.classList.add('pointer');
rangeInput.setAttribute('min', '0');
}
window.onload = function(){
parseDom();
// <==== Removed call
}
...或者通过控制器函数(parseAndConfigure
,无论如何)查找输入并将其传递给两个函数。
旁注:在保持函数较小并确保名称表示它的作用(似乎是你的目标)方面,parseDom
不解析任何东西,它不仅仅是识别相关的DOM元素(它还为它们添加了类)。也许有三个功能:getDom
,addClasses
和configureRange
或类似功能。然后:
window.onload = function() {
var dom = getDom();
addClasses(dom);
configureRange(dom);
}
......或类似的东西。
答案 1 :(得分:1)
您可以将元素保留在对象中,然后返回该对象,以便在其他任何地方重用
function parseDom() {
var els = (function(d) {
var main = d.getElementById('main'),
rangeContainer = main.querySelector('.range-container'),
rangeInput = rangeContainer.querySelector('.range-input');
return {main, rangeContainer, rangeInput};
})(document);
els.main.classList.add('red');
els.rangeContainer.classList.add('green');
els.rangeInput.classList.add('crosshair');
return els;
}
function configureRange(els) {
els.rangeInput.classList.add('pointer');
els.rangeInput.setAttribute('min', '0');
return els;
}
window.onload = function() {
var elems = parseDom();
configureRange(elems);
}
答案 2 :(得分:1)
最简单的方法是将选择器从parseDom函数中抽象出来,也许可以调用updateDom并解析顶层函数中的选择器,例如:
function updateDom(main, rangeContainer, rangeInput) {
main.classList.add('red');
// red class added - main selector is ok
rangeContainer.classList.add('green');
// green class added - rangeContainer selector is ok
rangeInput.classList.add('crosshair');
// crosshair class added - rangeInput selector is ok
}
function configureRange(rangeInput){
rangeInput.classList.add('pointer');
rangeInput.setAttribute('min', '0');
}
window.onload = function(){
var main = document.getElementById('main'),
rangeContainer = main.querySelector('.range-container'),
rangeInput = rangeContainer.querySelector('.range-input');
updateDom(main, rangeContainer, rangeInput);
configureRange(rangeInput);
}
答案 3 :(得分:0)
您可以在.onload
中声明变量,然后将它们作为参数传递给任意数量的函数:
function parseDom(main, rangeContainer, rangeInput) { // <= arguments
main.classList.add('red');
rangeContainer.classList.add('green');
rangeInput.classList.add('crosshair');
}
function configureRange(rangeInput){ // <= argument
rangeInput.classList.add('pointer');
rangeInput.setAttribute('min', '0');
}
window.onload = function(){
var main = document.getElementById('main'),
rangeContainer = main.querySelector('.range-container'),
rangeInput = rangeContainer.querySelector('.range-input'),
// other elements
parseDom(main, rangeContainer, rangeInput); // <= pass as arguments
configureRange(rangeInput); // <= pass as argument
}