簡體   English   中英

JavaScript-函數無法訪問其他函數作用域中的變量

[英]JavaScript - function can't acces variables from another function scope

我正在嘗試使用javscript創建一個滑塊。 我想擁有兩個函數-首先, parseDom()應該負責從DOM中獲取元素; 第二個參數configureRange()應該負責設置范圍屬性,例如minmax 這兩個函數都在匿名函數內部調用,該匿名函數被分配給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();
}

但是,不能從configureRange() parseDom()中的變量,因為這些函數內部的變量處於不同的范圍內。 因此我的configureRange()內部的代碼無法正常工作。 我可以用一個函數而不是兩個函數來完成所有事情,但這會使代碼混亂。 如何創建一個好的模塊化解決方案?

代碼在這里: https : //codepen.io/t411tocreate/pen/oeKwbW?editors=1111

最簡單的事情可能是通過讓parseDom調用configureRange所需的信息:

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元素(它還會添加類)。 也許是三個函數: getDomaddClassesconfigureRange或類似的函數。 然后:

window.onload = function() {
    var dom = getDom();
    addClasses(dom);
    configureRange(dom);
}

...或類似的東西。

您可以將元素保留在一個對象中,然后返回該對象,以在其他任何地方重用

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);
}

最簡單的方法是從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);
}

您可以在.onload聲明變量,然后將它們作為參數傳遞給.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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM