未捕获的类型错误:无法读取 null 的属性“样式”。在同一页面中使用两个 Javascript 函数

Posted

技术标签:

【中文标题】未捕获的类型错误:无法读取 null 的属性“样式”。在同一页面中使用两个 Javascript 函数【英文标题】:Uncaught TypeError: Cannot read property 'style' of null. Using two Javascript functions in the same page 【发布时间】:2021-03-29 18:47:05 【问题描述】:

我尝试实现两个 javascript 函数,但它们似乎相互冲突。

当单击页面的按钮时,一个名为“showPage”的函数会显示/阻止选定的页面。像这样。

 function showPage(page) 
        document.querySelectorAll('tbody').forEach(tbody => tbody.style.display = 'none';)

        document.querySelector(`#$page`).style.display = 'table-row-group'; ---(This line in error message)
    

    document.addEventListener('DOMContentLoaded', function() 
        document.querySelectorAll('button').forEach(button => 
            button.onclick = function() 
                showPage(this.dataset.page); ---(This line in error message)
                       
        );
    );

以下是 showPage 所针对的按钮的一个示例,以及它将显示或阻止的页面示例。

<button class="posbutton" data-page="page1">QB</button>


<tbody id="page1">
               
         % for q in QBpage %
              <tr>
                <th scope="row">
                      
                </th>
                    
                <td><h6> q.player_name </h6></td>
                <td><button> class="btn btn-outline-primary btn-sm m-0 waves-effect" onclick="myFunction(' player_data.player_name   player_data.position ')">Add</button></td>
                <td><h6>  q.team  </h6></td>
                <td><h6>  q.position   </h6></td>
                <td><h6> q.points </h6></td>
                </tr>
                  
         % endfor %
</tbody>
               <!--several more pages like the above-->

总共有 5 个页面可以切换。当页面切换为显示时,页面上有一个按钮,该按钮链接到另一个名为 myFunction 的 JavaScript 函数。此函数将&lt;td&gt; 元素中的文本提交到表单字段。这是我的函数。

function myFunction(txt) 
        var myTxt = txt;
    
        
        if (txt.includes('QB')) 
            document.getElementById("QB_name").value = myTxt;
        

        else if (txt.includes('RB')) 
            document.getElementById("RB_name").value = myTxt;
        

        else if (txt.includes('WR')) 
            document.getElementById("WR_name").value = myTxt;
        

        else if (txt.includes('TE')) 
            document.getElementById("TE_name").value = myTxt;
        

        else if (txt.includes('K')) 
            document.getElementById("K_name").value = myTxt;
        
        
    

但是,当我加载页面然后单击按钮提交行中的数据时,此 onclick 会导致整个页面消失。控制台错误消息指向 showPage showPage(this.dataset.page); 中的行,我认为问题是因为 showPage 以 document.querySelectorAll('button') 行的所有按钮为目标。单击按钮以使用 myFunction 提交数据实际上是在调用 showPage,因为 showPage 的目标是所有页面上的按钮元素。那么,如何阻止这两个功能发生冲突呢?这是我的知识耗尽的地方,因为我对 JavaScript 还很陌生。我想我可以明白为什么它不起作用,但我不知道如何开发替代方案。如果您仔细阅读此内容,请提前致谢。

【问题讨论】:

你说的是错误。错误信息是什么? @trincot main2.js:4 Uncaught TypeError: Cannot read property 'style' of null 但是,尝试脚本的定位并没有改变任何东西。 使用document.querySelectorAll('button') 可以定位任何&lt;button/&gt;,这意味着也没有提供 [data-page] 属性,就像&lt;table/&gt; 中的属性一样。如果点击了这样的按钮,this.dataset.page 会将undefined 值传递给showPage 函数,然后该查询部分会失败...document.querySelector(#$page).style.display @PeterSeliger 谢谢。这听起来合乎逻辑。我还在想办法让this.dataset.page 传递正确的值。 我会改变你的问题。 “冲突函数”在 JavaScript 中不是一回事。关注错误消息。 【参考方案1】:

对于document.querySelectorAll('button'),一个确实针对任何&lt;button/&gt;,这意味着也没有提供 [data-page] 属性,就像&lt;tbody/&gt; 中的属性一样。

如果点击此类按钮,this.dataset.page 会将undefined 值传递给showPage 函数,然后该函数在访问.style.display 以获取document.querySelector(``#$page``) 的查询结果时会失败。

为了首先正确初始化事件处理,可以尝试通过仅定位[data-page] 按钮来相应地更改代码...

function handleShowPage(evt) 
  // showPage(this.dataset.page);
  showPage(evt.currentTarget.dataset.page);

document.addEventListener('DOMContentLoaded', function() 
  document
    .querySelectorAll('button[data-page]')
    .forEach(button =>
      button.addEventListener('click', handleShowPage)
    );
);

编辑

但是,当我加载一个页面,然后单击一个按钮提交行中的数据时,这个 onclick 会导致整个页面消失。

任何未通过其[type] 属性明确说明其类型的按钮都将触发其包含它的表单的提交。

因此,为了防止这种行为,可能会编写这样的按钮代码 ...&lt;button type='button' ... 或者通过调用 evt.preventDefault() 主动抑制触发此类按钮的单击事件的提交默认值在此按钮的点击处理程序中。

编辑/总结

说了以上所有内容后,我会将 OP 的代码更改为这种方法...

标记

<button type="button" data-page="page1" class="posbutton">QB</button>

<tbody id="page1">
  % for q in QBpage %
    <tr>
      <th scope="row"></th>
      <td><h6> q.player_name </h6></td>
      <td>
        <button
          type="button"
          data-player-name=" q.player_name "
          data-position=" q.position "
          class="btn btn-outline-primary btn-sm m-0 waves-effect"
        >Add</button>
      </td>
      <td><h6> q.team </h6></td>
      <td><h6> q.position </h6></td>
      <td><h6> q.points </h6></td>
    </tr>
  % endfor %
</tbody>

脚本

function showPage(pageId) 
  document
    .querySelectorAll('tbody')
    .forEach(tbody => tbody.style.display = 'none');
  document
    .querySelector(`#$ pageId `)
    .style.display = 'table-row-group';

function updatePosition(name, position) 
  document
    .querySelector(`#$ position _name`)
    .value = [name, position].join(' ');


function handleShowPage(evt) 
  showPage(evt.currentTarget.dataset.page);

function handleUpdatePosition(evt) 
  const  playerName, position  = evt.currentTarge.dataset;
  updatePosition(playerName, position);


document.addEventListener('DOMContentLoaded', function() 
  document
    .querySelectorAll('button[data-page]')
    .forEach(button =>
      button.addEventListener('click', handleShowPage)
    );
  document
    .querySelectorAll('button[data-position][data-player-name]')
    .forEach(button =>
      button.addEventListener('click', handleUpdatePosition)
    );
);

【讨论】:

再次感谢。有点工作,它的工作原理!但是我的 myFunction 现在没有收到任何东西。需要进行一些调整,但现在 90% 都在工作,这很棒。 @user14593966 ... btw ... "... 但它现在 90% 都在工作,这很棒。..." 不是一个人应该接受的。如果有错误,可以调试。 再次感谢您提供的所有有用建议。我对你的编辑有点困惑。我现在了解如何正确处理 showPage。现在只需让 myFunction 再次工作即可。我尝试将&lt;td&gt;&lt;button&gt; class="btn btn-outline-primary btn-sm m-0 waves-effect" onclick="myFunction(' player_data.player_name player_data.position ')"&gt;Add&lt;/button&gt;&lt;/td&gt; 更改为&lt;button&gt; type="button" class= etc etc..&gt;,但没有任何改变。 标记生成代码状态...&lt;td&gt;&lt;button&gt; class="btn btn-outline-primary ... 与预期结果不符...看看我的最后一个编辑/摘要 ...看起来像那样...&lt;td&gt;&lt;button type="button" ... class="..." &gt;确实会生成语法正确/有效的标记。 谢谢你!我从您的建议和此处显示的示例中学到了很多东西。

以上是关于未捕获的类型错误:无法读取 null 的属性“样式”。在同一页面中使用两个 Javascript 函数的主要内容,如果未能解决你的问题,请参考以下文章

未捕获的类型错误:无法读取 null 的属性“样式”。在同一页面中使用两个 Javascript 函数

未捕获的类型错误无法读取 null 的属性(读取“查询选择器”)

未捕获的类型错误:无法读取 null 的属性(读取“添加”)

无法读取未定义的属性“样式”——未捕获的类型错误

未捕获的类型错误:无法读取 null 的属性“getContext”

为啥我会收到此错误:未捕获的类型错误:无法读取 null 的属性 'classList'