You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

onclick事件传递函数参数提示“未定义”问题排查

解决Watchlist添加按钮onclick传参未定义/异常问题

问题描述

我在开发「添加到收藏清单(Watchlist)」功能时遇到两个问题:

  • 初始代码中,点击按钮触发onclick事件时,传递的data.imdbID参数提示「未定义」
  • 尝试用slice(2)移除imdbID开头的tt前缀后,点击按钮出现异常结果

原代码

HTML代码

<html>
    <head>
        <link rel="stylesheet" href="index.css">
        <link rel="preconnect" href="https://fonts.googleapis.com">
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap" rel="stylesheet">
    </head>
    <body>
        <div class="container">
            <header>
                <div class="head">
                    <h1>Find your film</h1>
                    <a href="#">My Watchlist</a>
                </div>
                <div class="search-bar">
                    <i class="fa-solid fa-magnifying-glass icon"></i>
                    <input type="text" class="input-field" id="input-text">
                    <button type="submit" class="submit" id="submit-btn">Search</button>
                </div>
            </header>
            <main id="body-container"></main>
        </div>
        <script src="index.js"></script>
        <script src="https://kit.fontawesome.com/a7b56fbb1c.js" crossorigin="anonymous"></script>
    </body>
</html>

初始JS代码

const body = document.getElementById("body-container")
const watchlistBtn = document.getElementsByClassName("add-watchlist")

let watchlist = []


document.getElementById("submit-btn").addEventListener("click", function() {
    let searchValue = document.getElementById("input-text").value
    let arr = []
    fetch(`https://www.omdbapi.com/?i=tt3896198&apikey=f2f47683&type=movie&s=${searchValue}`)
    .then(res => res.json())
    .then(data => {
        for (let i = 0; i < data.Search.length; i++) {
            arr.push(data.Search[i].imdbID)
            }
        for (let item of arr) {
            fetch(`https://www.omdbapi.com/?apikey=f2f47683&i=${item}`)
                .then(res => res.json())
                .then(data => {
                    renderMovie(data)
            })
        }
    })
})

function renderMovie(data) {
    body.innerHTML += `
    <div class="list-container">
        <div class="movie-container">
            <img src="${data.Poster}" class="poster">
            <div class="movie-details">
                <div class="row-1">
                    <h2 id="movie-title">${data.Title}</h2>
                    <i class="fa-solid fa-star"></i>
                    <p id="movie-rating">${data.imdbRating}</p>
                </div>
                <div class="row-2">
                    <p id="run-time">${data.Runtime}</p>
                    <p id="genre">${data.Genre}</p>
                    <div id="button-container">
                        <button class="add-watchlist" onclick="addToWatchlist(${data.imdbID})"><i class="fa-solid fa-plus"></i> Watchlist</button>
                    </div>
                </div>
                <p class="description">${data.Plot}</p>
            </div>
        </div>
    </div>
    ` 
}


function addToWatchlist(dataID) {
    watchlist.push(dataID)
    console.log(dataID)
}

修改后的JS代码(出现异常的版本)

function renderMovie(data) {
    let numb = data.imdbID.slice(2)
    body.innerHTML += `
    <div class="list-container">
        <div class="movie-container">
            <img src="${data.Poster}" class="poster">
            <div class="movie-details">
                <div class="row-1">
                    <h2 id="movie-title">${data.Title}</h2>
                    <i class="fa-solid fa-star"></i>
                    <p id="movie-rating">${data.imdbRating}</p>
                </div>
                <div class="row-2">
                    <p id="run-time">${data.Runtime}</p>
                    <p id="genre">${data.Genre}</p>
                    <div id="button-container">
                        <button class="add-watchlist" onclick="addToWatchlist(${numb})"><i class="fa-solid fa-plus"></i> Watchlist</button>
                    </div>
                </div>
                <p class="description">${data.Plot}</p>
            </div>
        </div>
    </div>
    ` 
}

function addToWatchlist(dataID) {
    watchlist.push(dataID)
    console.log(dataID)
}

问题原因

  1. 初始代码的「未定义」问题:data.imdbID是字符串类型(如tt123456),直接写在模板字符串的onclick中时,渲染后的HTML会变成onclick="addToWatchlist(tt123456)"。浏览器会把tt123456当作变量名而非字符串,因未定义该变量而报错。
  2. 修改后异常问题:用slice(2)得到的是数字开头的字符串(如123456或007),渲染后变成onclick="addToWatchlist(007)"。JS会把带前导零的数字当作八进制数解析,导致ID值错误(比如007会被解析为7);同时我们需要的是字符串类型的ID,而非数字类型。

解决方案

方案1:给参数添加引号(快速修复)

在模板字符串中给data.imdbID包裹单引号,让浏览器识别为字符串:

function renderMovie(data) {
    body.innerHTML += `
    <div class="list-container">
        <div class="movie-container">
            <img src="${data.Poster}" class="poster">
            <div class="movie-details">
                <div class="row-1">
                    <h2 id="movie-title">${data.Title}</h2>
                    <i class="fa-solid fa-star"></i>
                    <p id="movie-rating">${data.imdbRating}</p>
                </div>
                <div class="row-2">
                    <p id="run-time">${data.Runtime}</p>
                    <p id="genre">${data.Genre}</p>
                    <div id="button-container">
                        <!-- 给参数添加单引号 -->
                        <button class="add-watchlist" onclick="addToWatchlist('${data.imdbID}')"><i class="fa-solid fa-plus"></i> Watchlist</button>
                    </div>
                </div>
                <p class="description">${data.Plot}</p>
            </div>
        </div>
    </div>
    ` 
}

方案2:使用事件委托(更健壮)

内联onclick不利于代码维护,推荐用事件委托绑定事件,避免字符串解析问题:

const body = document.getElementById("body-container")
let watchlist = []

// 保留搜索逻辑,修改renderMovie函数移除onclick,添加data-id属性
document.getElementById("submit-btn").addEventListener("click", function() {
    let searchValue = document.getElementById("input-text").value
    let arr = []
    fetch(`https://www.omdbapi.com/?i=tt3896198&apikey=f2f47683&type=movie&s=${searchValue}`)
    .then(res => res.json())
    .then(data => {
        for (let i = 0; i < data.Search.length; i++) {
            arr.push(data.Search[i].imdbID)
            }
        for (let item of arr) {
            fetch(`https://www.omdbapi.com/?apikey=f2f47683&i=${item}`)
                .then(res => res.json())
                .then(data => {
                    renderMovie(data)
            })
        }
    })
})

function renderMovie(data) {
    body.innerHTML += `
    <div class="list-container">
        <div class="movie-container">
            <img src="${data.Poster}" class="poster">
            <div class="movie-details">
                <div class="row-1">
                    <h2 id="movie-title">${data.Title}</h2>
                    <i class="fa-solid fa-star"></i>
                    <p id="movie-rating">${data.imdbRating}</p>
                </div>
                <div class="row-2">
                    <p id="run-time">${data.Runtime}</p>
                    <p id="genre">${data.Genre}</p>
                    <div id="button-container">
                        <!-- 添加data-id存储imdbID -->
                        <button class="add-watchlist" data-id="${data.imdbID}"><i class="fa-solid fa-plus"></i> Watchlist</button>
                    </div>
                </div>
                <p class="description">${data.Plot}</p>
            </div>
        </div>
    </div>
    ` 
}

// 事件委托绑定点击事件
body.addEventListener('click', function(e) {
    const targetBtn = e.target.closest('.add-watchlist');
    if(targetBtn) {
        const dataID = targetBtn.dataset.id;
        watchlist.push(dataID);
        console.log(dataID);
    }
})

内容的提问来源于stack exchange,提问作者mohammed shajahan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 02:24:38