getElementbyID 在 DOM 加载后返回 null

问题描述 投票:0回答:0

用户单击 CONNECT 按钮以显示隐藏的 div 并隐藏包含调用 CONNECT 按钮的 div。

a) 如果用户单击取消,onClick 事件中的匿名函数会正确处理所有内容。

b) 如果用户点击新显示的 div 中的 SAVE 按钮隐藏自身并显示返回 NULL 元素的原始按钮。不将 saveWlan() 调用放在匿名函数中的原因是“this”未定义,我无法在 saveWlan 函数中执行其他处理,我不希望页面中有 20 个匿名函数副本。

下面的代码片段去掉了很多生成给定 HTML 的 CSS 和 javascript 代码,并显示了在用户单击第一个按钮以显示问题之前 HTML 页面的状态。

onClick='saveWlan(this)' 函数调用提供了一个有效的 'this' 对象的 ID,我可以查询,使用 split 函数解构并重建我要修改的元素的 ID(CONNECT 按钮的 div 容器).

console.log() 语句表明我已经正确读取了this.id 属性并重构了我希望修改的元素的ID 字符串,但是此时document.getElementById(...) 返回NULL。

进程启动前在开发者工具-->elements inspector中可以看到元素,所以对象不为NULL。

const saveWlan = async(element) => {
  console.log("[savingWlan]");
  document.getElementById('blocker-title').innerHTML = 'Saving';
  document.getElementById('blocker').classList.remove('hidden'); // this works !!


  console.log("element.id = " + element.id);

  const nameParts = element.id.split('-'); // "scanWlan-3-save"
  const wlanPrefix = nameParts[0]; // returns scanWlan
  const wlanIndex = nameParts[1]; // returns 3
  // I can now add a suffix of my choosing

  var idStringEdit = `'${wlanPrefix}-${wlanIndex}-edit'`; //scanWlan-3-edit
  var idStringConnect = `'${wlanPrefix}-${wlanIndex}-connect'`; //scanWlan-3-connect

  console.log("idStringEdit = " + idStringEdit); //idStringEdit = 'scanWlan-3-edit'
  console.log("idStringConnect = " + idStringConnect); //idStringConnect = 'scanWlan-3-connect'


  document.getElementById(`'${wlanPrefix}-${wlanIndex}-connect'`).classList.add('hidden'); // this doesn't work
  document.getElementById(`'${wlanPrefix}-${wlanIndex}-edit'`).classList.remove('hidden');

  const ssid = wlan.ssid;
  const password = document.getElementById(`'${wlanPrefix}-${wlanIndex}-password'`).value;

  console.log("wlanIndex = " + wlanIndex);
  console.log("wlanIndex.ssid = " + ssid);
  console.log("wlanIndex.password = " + password);

  var data = new FormData();
  data.append("ssid", ssid);
  data.append("password", password);

  // transfer data to server
}


// Window Interval functions:
//Interval never stops, we just stop responding to it!!

var scanning = true; //global scope 

function startScan() { // resume scanning for WiFi Networks every 15 seconds...  
  if (scanning == false) { // but only once every 15 seconds... ;)
    scanning = true;
  }
}

function doWifiScan() {
  if (scanning == true) fetchScannedList();
}

function stopScan() {
  scanning = false;
}
#blocker {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  top: 0;
  left: 0;
  z-index: 1;
  position: fixed;
  height: 100%;
  width: 100%;
  background: steelblue;
  opacity: 0.95;
  color: white;
}

.spacer {
  display: block;
  width: 100%;
  height: 80px;
}

.small {
  height: 5px;
}

.hidden {
  display: none !important;
}

.btn-container {
  display: flex;
  justify-content: flex-end;
  align-items: center;
}

.btn-container input {
  width: 15%;
  border: 1px solid lightgrey;
  border-radius: 5px;
  padding: 15px 32px;
  margin: 10px 5px;
}

.btn {
  border-radius: 5px;
  padding: 15px 10px;
  text-align: center;
  transition-duration: 0.4s;
  margin: 10px 5px;
  cursor: pointer;
  text-decoration: none;
}

.edit {
  background-color: dodgerblue;
  border: solid 1px dodgerblue;
  color: white;
}

.edit:hover {
  color: dodgerblue;
}

.save {
  background-color: yellowgreen;
  border: solid 1px yellowgreen;
  color: white;
}

.save:hover {
  color: yellowgreen;
}

.cancel {
  background-color: black;
  border: solid 1px black;
  color: white;
}

.cancel:hover {
  color: black;
}

.btn:hover {
  background-color: white;
}
<body>
  <div>
    <div class="row" id="rowScanWlan-3">
      <!-- row -->
      <div class="wifi-info">
        <!-- column 60%-->
        <div class="wifi-name" id="scanWlan-3-ssid">
          GI-VoIP
        </div>
      </div>
      <div class="column">
        <div class="btn-container" id="scanWlan-3-connect">
          <img src="" alt="||" height="35px" border="0">
          <img src="" alt="C" height="35px" border="0">
          <a id="scanWlan-3-show" class="btn edit" onclick="(function(){
      document.getElementById('scanWlan-3-edit').classList.remove('hidden');
      document.getElementById('scanWlan-3-connect').classList.add('hidden');
          stopScan();
      })();">
        Connect
    </a>
        </div>
      </div>
    </div>

  </div>
  <div class="spacer small">
    <!--  forces the row above to FILL a row, rather than wrapping multiple networks onto a single row -->
  </div>
  <div class="more-info hidden" id="scanWlan-3-edit">
    <div class="wifi-info">Enter Password:
      <input type="text" name="password" id="scanWlan-3-password"></div>
    <div class="column">
      <div class="btn-container" id="rowSsidScanWlan-3">
        <a id="scanWlan-3-save" class="btn save" onclick="saveWlan(this)">
         Save
        </a>
        <a id="scanWlan-3-cancel" class="btn edit" onclick="(function(){
      document.getElementById('scanWlan-3-password').value='';
      document.getElementById('scanWlan-3-edit').classList.add('hidden');
      document.getElementById('scanWlan-3-connect').classList.remove('hidden');
          startScan();
      })();">
      Cancel
        </a>
      </div>
    </div>
  </div>
  </div>

  <div id="blocker" class="hidden">
    <h2 id="blocker-title">Loading</h2>
    <div id="Saved">
      <p id="finished">
      </p>
    </div>
  </div>
</body>

javascript html css null getelementbyid
© www.soinside.com 2019 - 2024. All rights reserved.