javascript - 未捕获的类型错误:无法读取 null 的属性“样式”。在同一页面中使用两个 Javascript 函数
问题描述
我有两个试图实现的 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 函数。<td>
此函数将元素中的文本提交到表单字段。这是我的函数。
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 还很陌生。我想我可以明白为什么它不起作用,但我不知道如何开发替代方案。如果您阅读此内容,请提前致谢。
解决方案
With document.querySelectorAll('button')
one 确实以 any 为目标<button/>
,这也意味着那些不提供属性[data-page]
的对象,例如<tbody/>
.
如果单击这样的按钮,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]
属性明确说明其类型的按钮都将触发包含它的表单的提交。
因此,为了防止这种行为,可能会编写这样的按钮代码......或者通过在此按钮的单击处理程序中<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)
);
});
推荐阅读
- regex - 正则表达式 - 匹配主题标签之外的子字符串(#)
- python - 单击用户名并重定向到个人资料
- javascript - 为什么在 JavaScript 中 (super.__proto__ === this.__proto__) 是真的?
- reactjs - 状态没有更新正确的信息
- jsf - 通过 ace:fileUpload 上传文件后更新 ice:inputRichText 字段
- node.js - NodeJS - HTTP 请求不会将句柄返回给 REPL
- python - 绘制的图像显示为灰色
- sql - 列出 msi 文件中的表?
- javascript - 单击文本框文本弹出菜单应打开文本框
- android - 滑动期间无法更新 ViewPager 中的菜单项状态