首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JavaScript onchange 事件無法呼叫函數:常見錯誤與修正完整指南

     編輯:程式設計綜合問答

原始程式碼問題分析

<input type="file" name="uploadFile" onchange="javascript:my_check(this.value);"/>

三大關鍵錯誤

  1. `javascript:` 協議前綴多餘:事件屬性值直接寫 JS 運算式/陳述式,不需 `javascript:`
  2. `obj.innerHTML("...")` 語法錯誤:`innerHTML` 是**屬性**非函數,應為 `obj.innerHTML = "..."`
  3. 檔案型別檢查邏輯缺陷:`this.value` 僅含檔名 (如 `C:\fakepath\image.jpg`),`lastIndexOf(".")` 取副檔名可行,但 `document.write` 會覆蓋整個頁面

修正後完整程式碼

<!DOCTYPE html>
<html lang="zh-TW">
<head>
  <meta charset="UTF-8">
  <title>檔案上傳類型檢查</title>
  <style>
    .hidden { display: none; }
  </style>
</head>
<body>
  <form id="uploadForm" method="post" enctype="multipart/form-data">
    <input type="file" id="fileInput" name="uploadFile" accept="image/jpeg,image/png,image/gif" />
    <div id="submitBtnContainer" class="hidden">
      <input type="submit" value="上傳" />
    </div>
    <div id="errorMsg" class="hidden" style="color:red;"></div>
  </form>

  <script>
    // DOMContentLoaded 確保元素存在再綁定事件 (最佳實務)
    document.addEventListener('DOMContentLoaded', function() {
      const fileInput = document.getElementById('fileInput');
      const submitBtnContainer = document.getElementById('submitBtnContainer');
      const errorMsg = document.getElementById('errorMsg');

      fileInput.addEventListener('change', function() {
        const file = this.files[0];
        if (!file) return; // 使用者取消選擇

        // 1. 檢查副檔名 (雙重保險:accept 屬性 + JS 檢查)
        const allowedExt = ['.jpg', '.jpeg', '.png', '.gif'];
        const fileName = file.name.toLowerCase();
        const ext = fileName.substring(fileName.lastIndexOf('.'));
        
        if (allowedExt.includes(ext)) {
          // 合法:顯示上傳按鈕、隱藏錯誤
          submitBtnContainer.classList.remove('hidden');
          errorMsg.classList.add('hidden');
          errorMsg.textContent = '';
        } else {
          // 非法:隱藏按鈕、顯示錯誤、清空檔案選擇
          submitBtnContainer.classList.add('hidden');
          errorMsg.classList.remove('hidden');
          errorMsg.textContent = '非法圖片類型!僅允許 JPG, PNG, GIF';
          this.value = ''; // 清空 input
        }
      });
    });
  </script>
</body>
</html>

關鍵修正點對照表

原始錯誤修正做法說明
`onchange="javascript:my_check(...)"``addEventListener('change', ...)`分離結構與行為、避免全域汙染、支援多監聽器
`obj.innerHTML("...")``element.classList.toggle('hidden')` / `textContent``innerHTML` 是屬性;操作 CSS 類別比拼接 HTML 字串更安全、可維護
`document.write("錯誤")`顯示預留錯誤區塊 `errorMsg``document.write` 頁面載入後呼叫會清空整個文檔
無 `accept` 屬性`accept="image/jpeg,image/png,image/gif"`瀏覽器原生過濾檔案對話框,減少使用者錯誤選擇
依賴 `this.value` 取副檔名`file.name` (File API)`this.value` 有偽路徑 `C:\fakepath\`,`file.name` 直接得純檔名

進階:MIME 類型二次驗證 (更安全)

// 檢查檔案實際 MIME 類型 (防止偽裝副檔名)
const allowedMime = ['image/jpeg', 'image/png', 'image/gif'];
if (!allowedMime.includes(file.type)) {
    // 類型不符
}

⚠ `file.type` 由瀏覽器根據副檔名推斷,**非內容檢驗**。伺服器端**必須**再次驗證 (魔數/Magic Bytes、圖片解碼庫)。

總結

`onchange` 無法呼叫函數主因:**語法錯誤 (`javascript:`、`innerHTML()`)、API 使用錯誤 (`document.write`)、邏輯缺陷**
修正核心:**事件監聽器綁定 + File API (`files[0].name`) + CSS 類別切換 UI 狀態 + `accept` 屬性輔助**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved