HTML元素btn为null,怎么了?

时间:2018-07-14 13:19:58

标签: javascript html dom

这是我的JavaScript代码,其作用是将数字转换为数字(该功能有效):

function convertToRoman(num) {
  const numbers = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
  const numeral = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];
  const arr = [];
  let renum = num;
  while (arr.reduce((before, after) => before + after, 0) < num) {
    const EL = numbers.findIndex(element => renum - element >= 0);
    arr.push(numbers[EL]);
    renum -= numbers[EL];
  }
  return arr.map(element => numeral[numbers.indexOf(element)]).join('');
}

let btn = document.querySelector('.btn');
btn.addEventListener('click', () => alert(convertToRoman(document.querySelector('input').value)), false);

这是我的html页面:

<html>
  <head>
  <title> Sumbit </title>
  </head>
  <body>       
  <script src="NBC.js"></script>
    <button class="btn"> Convert </button>
    <input type="number" class="inpu">
  </body>
</html>

因此,如您所见,我想创建一个按钮和一个输入字段,当用户输入数字并单击按钮时,.value将值作为函数的参数提供,因此单击该函数时,点击事件)显示为alert,并带有罗马数字。

问题是它在控制台中给我“ btn为null”错误,执行代码时出了什么问题?

我尝试了document.getElementById(id),尝试了删除“。”在课堂上,我竭尽所能。

有解决方案吗?

3 个答案:

答案 0 :(得分:1)

为了防止在DOM完全加载之前对其进行访问,请在DOMContentLoaded事件下添加一个事件侦听器:

document.addEventListener('DOMContentLoaded', () => {...});

...并在该事件监听器中执行代码

<html>
<head>
  <title>Sumbit</title>
</head>
<body>
  <button class="btn"> Convert </button>
  <input type="number" class="input" placeholder="Enter some numbers">
  <script>
    document.addEventListener('DOMContentLoaded', () => {
      function convertToRoman(num) {
        const numbers = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
        const numeral = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];
        const arr = [];
        let renum = num;
        while (arr.reduce((before, after) => before + after, 0) < num) {
          const EL = numbers.findIndex(element => renum - element >= 0);
          arr.push(numbers[EL]);
          renum -= numbers[EL];
        }
        return arr.map(element => numeral[numbers.indexOf(element)]).join('');
      }

      let btn = document.querySelector('.btn');
      btn.addEventListener('click', () => alert(convertToRoman(document.querySelector('input').value)), false);
    });
  </script>
</body>
</html>

此外,如果您希望DOM在用户请求页面后尽快解析(例如,加快速度),


您的HTML(class="inpu")中也有一个错字

<input type="number" class="inpu">

确保对其进行修复:

<input type="number" class="input">

答案 1 :(得分:1)

这可能是defer的工作,它只会告诉浏览器在执行脚本之前先等待HTML解析器完成。

属性说明:

  

<script defer>

     

defer在HTML解析期间下载文件并将仅执行它   解析器完成后。延迟脚本也可以保证   按它们在文档中出现的顺序执行。

Source

答案 2 :(得分:1)

您可以通过多种方法来执行此操作,第一种是在DOMContentLoaded对象上监听document事件监听器。

document.addEventListener("DOMContentLoaded", () => {
    let btn = document.querySelector('.btn');  
    btn.addEventListener('click', () => alert(convertToRoman(document.querySelector('input').value)), false);
});

第二种方法是在脚本元素上使用asyncdefer属性。如果使用脚本的async属性,加载脚本不会阻止DOM的加载;如果使用defer属性,脚本元素必须先加载其src的值DOM将被加载

<html>
    <head>
        <title> Sumbit </title>
    </head>
    <body>       
        <script src="NBC.js" async></script>
        <button class="btn"> Convert </button>
        <input type="number" class="inpu">
    </body>
</html>

这只是一个注释,是将script元素作为body元素的最后一个子元素,还是将其放在head元素之内