使用 for() 循环搜索用 JS 制作的 table

Search a table made with JS with for() loop

我正在尝试设置一个搜索栏来搜索 table,该 table 通过按名称或电子邮件循环从 API 带来的数据生成,但我找不到出问题了控制台显示未捕获的 ReferenceError: sBar 未定义在 window.onload 请记住,我是 JS 的新手。我真的很抱歉,这很愚蠢,但我已尽力而为,我对无法看到错误感到非常沮丧

这是我的HTML

<body>
  <div>
    <label for="finder">Find User:</label>
    <input type="search" id="searchInput" name="sInput" placeholder="Search 
    user">
    <button id="sButton">Search</button>
  </div>
  <table class="table table-responsive">
    <thead class="thead-dark">
      <tr>
        <th scope="col">Id</th>
        <th scope="col">Name</th>
        <th scope="col">Username</th>
        <th scope="col">Email</th>
        <th scope="col">Address</th>
        <th scope="col">Phone</th>
        <th scope="col">Website</th>
        <th scope="col">Company</th>
      </tr>
    </thead>
    <tbody name="tTable">
    </tbody>
  </table>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js">
</script>
<script src="script.js">
</script>

小米JS

window.onload = function(){    

    let uList = document.querySelector('[name =tTable]');  

    fetchCall('https://jsonplaceholder.typicode.com/users', getUsers);
    sButton.addEventListener('click', 
    fetchCall('https://jsonplaceholder.typicode.com/users', sBar), false);


  function sBar(getObject) {
    let sUser = getObject;
    let inputBar = document.getElementById("searchInput");
    let text = inputBar.textContent;
    let textView = text.toUpperCase();
    for (let i = 0; i < getObject.length; i++) {
         let uObject = sUser[i];
      if (textView == uObject.name || textView == uObject.email) {
        let new_tTable = document.createElement('tbody');
        uList.parentNode.replaceChild(new_tTable, uList)

        let row = uList.insertRow();   
        let idInput = document.createElement('td');
        let nameInput = document.createElement('td');     
        let usernameInput = document.createElement('td');    
        let emailInput = document.createElement('td');      
        let cityInput = document.createElement('td');      
        let phoneInput = document.createElement('td');      
        let websiteInput = document.createElement('td');      
        let companyInput = document.createElement('td');      

        idInput.textContent = uObject.id;
        nameInput.textContent = uObject.name;
        usernameInput.textContent = uObject.username;
        emailInput.textContent = uObject.email;
        cityInput.textContent = uObject.address.city;
        phoneInput.textContent = uObject.phone;
        websiteInput.textContent = uObject.website;
        companyInput.textContent = uObject.company.name;
        row.appendChild(idInput);
        row.appendChild(nameInput);
        row.appendChild(usernameInput);
        row.appendChild(emailInput);
        row.appendChild(cityInput);
        row.appendChild(phoneInput);
        row.appendChild(websiteInput);
        row.appendChild(companyInput);  
     } else {
       alert("User not found");         
     }
   }
} 


  function fetchCall(url, fn){
    fetch(url)
        .then(function(response){
            return response.json();
        })
        .then(function(endPoint){
            fn(endPoint);
        })
        .catch(function(error){
            console.error(error);
        })
    }

  function getUsers(getObject) {
    let user = getObject;      
      for (let i = 0; i < getObject.length; i++) {
        let userObject = user[i];
        let row = uList.insertRow();   
        let idInput = document.createElement('td');
        let nameInput = document.createElement('td');     
        let usernameInput = document.createElement('td');    
        let emailInput = document.createElement('td');      
        let cityInput = document.createElement('td');      
        let phoneInput = document.createElement('td');      
        let websiteInput = document.createElement('td');      
        let companyInput = document.createElement('td');      

        idInput.textContent = userObject.id;
        nameInput.textContent = userObject.name;
        usernameInput.textContent = userObject.username;
        emailInput.textContent = userObject.email;
        cityInput.textContent = userObject.address.city;
        phoneInput.textContent = userObject.phone;
        websiteInput.textContent = userObject.website;
        companyInput.textContent = userObject.company.name;
        row.appendChild(idInput);
        row.appendChild(nameInput);
         row.appendChild(usernameInput);
         row.appendChild(emailInput);
         row.appendChild(cityInput);
         row.appendChild(phoneInput);
         row.appendChild(websiteInput);
         row.appendChild(companyInput);        
        }
      } 
    }

您可能需要单独定义 window.onload 和其他函数。

window.onload = function(){    

    let uList = document.querySelector('[name =tTable]');  

    fetchCall('https://jsonplaceholder.typicode.com/users', getUsers);
    sButton.addEventListener('click', 
    fetchCall('https://jsonplaceholder.typicode.com/users', sBar), false);
};

  function sBar(getObject) {
    let sUser = getObject;
    let inputBar = document.getElementById("searchInput");
    let text = inputBar.textContent;
    let textView = text.toUpperCase();
    for (let i = 0; i < getObject.length; i++) {
         let uObject = sUser[i];
        if (textView == uObject.name || textView == 
       uObject.email) {
        let new_tTable = document.createElement('tbody');
        uList.parentNode.replaceChild(new_tTable, uList)


        let row = uList.insertRow();   
        let idInput = document.createElement('td');
        let nameInput = document.createElement('td');     
        let usernameInput = document.createElement('td');    
        let emailInput = document.createElement('td');      
        let cityInput = document.createElement('td');      
        let phoneInput = document.createElement('td');      
        let websiteInput = document.createElement('td');      
        let companyInput = document.createElement('td');      

        idInput.textContent = uObject.id;
        nameInput.textContent = uObject.name;
        usernameInput.textContent = uObject.username;
        emailInput.textContent = uObject.email;
        cityInput.textContent = uObject.address.city;
        phoneInput.textContent = uObject.phone;
        websiteInput.textContent = uObject.website;
        companyInput.textContent = uObject.company.name;
        row.appendChild(idInput);
        row.appendChild(nameInput);
         row.appendChild(usernameInput);
         row.appendChild(emailInput);
         row.appendChild(cityInput);
          row.appendChild(phoneInput);
         row.appendChild(websiteInput);
         row.appendChild(companyInput);  
          } else{
           alert("User not found");
               }
       }
   } 


  function fetchCall(url, fn){
    fetch(url)
        .then(function(response){
            return response.json();
        })
        .then(function(endPoint){
            fn(endPoint);
        })
        .catch(function(error){
            console.error(error);
        })
    }

  function getUsers(getObject) {
    let user = getObject;      
      for (let i = 0; i < getObject.length; i++) {
        let userObject = user[i];
        let row = uList.insertRow();   
        let idInput = document.createElement('td');
        let nameInput = document.createElement('td');     
        let usernameInput = document.createElement('td');    
        let emailInput = document.createElement('td');      
        let cityInput = document.createElement('td');      
        let phoneInput = document.createElement('td');      
        let websiteInput = document.createElement('td');      
        let companyInput = document.createElement('td');      

        idInput.textContent = userObject.id;
        nameInput.textContent = userObject.name;
        usernameInput.textContent = userObject.username;
        emailInput.textContent = userObject.email;
        cityInput.textContent = userObject.address.city;
        phoneInput.textContent = userObject.phone;
        websiteInput.textContent = userObject.website;
        companyInput.textContent = userObject.company.name;
        row.appendChild(idInput);
        row.appendChild(nameInput);
         row.appendChild(usernameInput);
         row.appendChild(emailInput);
         row.appendChild(cityInput);
         row.appendChild(phoneInput);
         row.appendChild(websiteInput);
         row.appendChild(companyInput);        
        }
      } 

您已将回调 sBar() 附加到搜索输入的 onchange 事件。但是没有 sBar() 函数的定义(注意它不接受 argument/parameter)。您只定义了一个具有相同名称 "sBar" 的函数,它接受(需要)您命名为 getObject 的参数。

删除参数"getObject"并修改前几行以在搜索输入中获取当前输入的文本。获取搜索输入值的示例代码是:

var value = document.getElementById("searchInput").value;

旁注:

您可能需要使用另一个事件发射器而不是 onchange。只有当您将焦点放在输入元素而不是实际输入上时才会触发。

If you want to track changes as they type, use "onkeydown". If you need to trap paste operations with the mouse, use "onpaste" (IE, FF3) and "oninput" (FF, Opera, Chrome, Safari1).

请看this link

设置事件时调用函数,但需要绑定。

sButton.addEventListener('click', fetchCall.bind(this, 'https://jsonplaceholder.typicode.com/users', sBar), false);

我也建议在全局范围内创建一个函数。

uList = document.querySelector('[name =tTable]');

window.onload = function () {
    fetchCall('https://jsonplaceholder.typicode.com/users', getUsers);
    sButton.addEventListener('click', fetchCall.bind(this, 'https://jsonplaceholder.typicode.com/users', sBar), false);
}

function sBar(getObject) {
    let sUser = getObject;
    let inputBar = document.getElementById("searchInput");
    let text = inputBar.textContent;
    let textView = text.toUpperCase();
    for (let i = 0; i < getObject.length; i++) {
        let uObject = sUser[i];
        if (textView == uObject.name || textView ==
            uObject.email) {
            let new_tTable = document.createElement('tbody');
            uList.parentNode.replaceChild(new_tTable, uList)


            let row = uList.insertRow();
            let idInput = document.createElement('td');
            let nameInput = document.createElement('td');
            let usernameInput = document.createElement('td');
            let emailInput = document.createElement('td');
            let cityInput = document.createElement('td');
            let phoneInput = document.createElement('td');
            let websiteInput = document.createElement('td');
            let companyInput = document.createElement('td');

            idInput.textContent = uObject.id;
            nameInput.textContent = uObject.name;
            usernameInput.textContent = uObject.username;
            emailInput.textContent = uObject.email;
            cityInput.textContent = uObject.address.city;
            phoneInput.textContent = uObject.phone;
            websiteInput.textContent = uObject.website;
            companyInput.textContent = uObject.company.name;
            row.appendChild(idInput);
            row.appendChild(nameInput);
            row.appendChild(usernameInput);
            row.appendChild(emailInput);
            row.appendChild(cityInput);
            row.appendChild(phoneInput);
            row.appendChild(websiteInput);
            row.appendChild(companyInput);
        } else {
            alert("User not found");
        }
    }
}


function fetchCall(url, fn) {
    fetch(url)
        .then(function (response) {
            return response.json();
        })
        .then(function (endPoint) {
            fn(endPoint);
        })
        .catch(function (error) {
            console.error(error);
        })
}

function getUsers(getObject) {
    let user = getObject;
    for (let i = 0; i < getObject.length; i++) {
        let userObject = user[i];
        let row = uList.insertRow();
        let idInput = document.createElement('td');
        let nameInput = document.createElement('td');
        let usernameInput = document.createElement('td');
        let emailInput = document.createElement('td');
        let cityInput = document.createElement('td');
        let phoneInput = document.createElement('td');
        let websiteInput = document.createElement('td');
        let companyInput = document.createElement('td');

        idInput.textContent = userObject.id;
        nameInput.textContent = userObject.name;
        usernameInput.textContent = userObject.username;
        emailInput.textContent = userObject.email;
        cityInput.textContent = userObject.address.city;
        phoneInput.textContent = userObject.phone;
        websiteInput.textContent = userObject.website;
        companyInput.textContent = userObject.company.name;
        row.appendChild(idInput);
        row.appendChild(nameInput);
        row.appendChild(usernameInput);
        row.appendChild(emailInput);
        row.appendChild(cityInput);
        row.appendChild(phoneInput);
        row.appendChild(websiteInput);
        row.appendChild(companyInput);
    }
}

async/await & fetch()

核心功能基于async/awaitfetch(),特殊语法请到上面的link

老实说,我不知道如何解决 OP 的所有问题 (Ooriginal Post ) 代码。一般来说,您应该按步骤考虑该过程:

  1. 从URL得到JSON。您确定 fetchAll() 有效吗?

  2. 一旦你可以用 fetchCall() 获得 JSON 将 JSON 传递给 getUser()

  3. 如果fetchCall()returns一个值(看起来确实是...)使用整个函数作为一个值。

  4. 事件侦听器和处理程序具有您必须遵守的特定签名,使用命名回调或匿名回调很重要:

命名回调(无参数*)

DOMObj.addEventListener('event', namedFunction);
function namedFunction(e) {...

命名回调(带参数)

DOMObj.addEventListener('event', function(e) {
  namedFunction(num, str);
});
function namedFunction(num, str) {...

匿名回调

DOMObj.addEventListener('event', function(e) {...

以下演示使用async function getUser(url, id)简化Promise,使用fetch(),一次提取JSON一个用户id。 function getData(json)getUser() 与 JSON.

一起返回

搜索输入已更改为 type='number',因为用户的 user.id 属性 是参考。它还包含在 <form> 标记中,因此回调 function findUser(url, id) 将由提交事件触发。它基本上是 getUser().

的函数包装器

演示

<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet">
<style>
fieldset.fieldset {width:max-content;padding: 10px 0 0}
input.input, label.label {display:inline-block;font:inherit;width:9ch;height:30px;line-height:30px;vertical-align:middle;text-align:center;}
input.input {width:6ch;padding-right:0;margin-right:8px}
input.button {font:inherit;height: 30px;line-height:20px;}
</style>
</head>
<body>
  <main class='container'>
    <section class='row'>
      <form id='main' class='form inline-form'>
        <fieldset class='fieldset form-group'>
          <label class='label control-label float-left' for="find">User ID:</label>
          <input id="find" class='input form-control float-left' type="number" min='1' max='10'>
          <input class="button btn btn-dark btn-sm float-left" type='submit' value='Find'>
       </fieldset>
    </form>
  </section>
  <section class='row'>
  <table class="table table-responsive">
    <thead class="thead-dark">
      <tr>
        <th scope="col">ID</th>
        <th scope="col">Name</th>
        <th scope="col">Username</th>
        <th scope="col">Email</th>
        <th scope="col">Phone</th>
        <th scope="col">Company</th>
        <th scope="col">City</th>
        <th scope="col">Website</th>
      </tr>
    </thead>
  </table>
 </section>
</main>
<script>

const main = document.forms[0];

const getData = (user) => {
  const uList = document.querySelector('.table');
  let row = uList.insertRow();  
  let cell = idx => row.insertCell(idx);
  
  for (let i = 0; i < 8; i++) {
    let C = cell(i);
    switch(i) {
      case 0:
      user.id = user.id > 9 ? "" + user.id: "0" + user.id;
      C.textContent = user.id;
      break;
      case 1:
      C.textContent = user.name;
      break;
      case 2:
      C.textContent = user.username;
      break;
      case 3:
      C.textContent = user.email;
      break;
      case 4:
      C.textContent = user.phone;
      break;
      case 5:
      C.textContent = user.company.name;
      break;
      case 6:
      C.textContent = user.address.city;
      break;
      case 7:
      C.textContent = user.website;
      break;
      default:
      break;
    }
  } 
};

const getUser = async (url, id) => { 
  const response = await fetch(`${url}${id}`);
  const json = await response.json();
  return getData(json);
};

/*/ For debugging -- an IIFE variables are private. Parameters are required.
(async (u, i) => {
  const json = await getUser(u, i);
  console.log(json);
})(url, id);
/*/

const findUser = (e) => {
  e.preventDefault();
  const url = 'https://jsonplaceholder.typicode.com/users/';
  let id = Number(e.currentTarget.find.value);
  getUser(url, id);
};

main.addEventListener('submit', findUser);

</script>
</body>
</html>