检查元素是否存在于点击事件
Check if element exists on click event
如何检查一个元素是否存在于父元素中?我在我的项目中为产品数量实现了一个 increase/decrease 按钮。当用户单击这些按钮时,我可以增加和减少数量。我有一个 _parentElement,它呈现一个元素和数据以及错误消息(这只会在出现错误时呈现)。我已将点击事件附加到该 _parentElement(这在 DOM 中可见)并执行事件委托。
仅当在 _parentElement 中呈现错误消息以及当我单击 _parentElement 时才会记录此错误。
错误:Cannot read properties of null (reading 'innerHTML') at DetailView._handlerQuantity
这是我所做的:
View.js
import icons from 'url:../../icons/icons.svg';
export default class View {
_data;
renderError(message = this._errorMessage) {
const html = /*html*/ `
<div class="flex flex-col items-center justify-center gap-4 min-h-[inherit]">
<svg class="h-6 w-6 sm:h-10 sm:w-10 fill-red-600">
<use xlink:href="${icons}#icon-warning"></use>
</svg>
<span class="text-xl text-neutral-600 font-medium sm:text-xl xs:text-lg">${message}</span>
</div>
`;
const markup = this._parseStringtoHTML(html);
this._parentElement.innerHTML = '';
this._parentElement.insertAdjacentElement('afterbegin', markup.body.firstElementChild);
}
}
详情View.js
class DetailView extends View {
_parentElement = document.querySelector(".product__details");
_errorMessage = "We could'nt find the product. Please try another one!";
constructor() {
super();
this._addHandlerProductQuanity();
}
_handlerQuantity(e) {
const increase = e.target.closest(".btn__control--add");
const decrease = e.target.closest(".btn__control--minus");
let quantity = document.querySelector(".product__quantity");
const currentValue = Number(quantity.innerHTML) || 0;
if (increase)
Number(quantity.innerHTML) < this._data.stocks
? (quantity.innerHTML = currentValue + 1)
: 1;
if (decrease)
Number(quantity.innerHTML > 1)
? (quantity.innerHTML = currentValue - 1)
: 1;
}
_addHandlerProductQuanity() {
this._parentElement.addEventListener(
"click",
this._handlerQuantity.bind(this)
);
}
}
HTML:
<main class="main min-h-[calc(100vh-5rem)] sm:min-h-[calc(100vh-8rem)]">
<section class="product__details min-h-[inherit]">
<!-- PRODUCTS DETAILS WILL GO HERE... -->
</section>
</main>
而不是这个:
const currentValue = Number(quantity.innerHTML) || 0;
你可以这样做:
const currentValue = Number(quantity?.innerHTML ?? 0);
?.
基本上会在尝试获取右侧的 属性 之前检查左侧的对象是否存在(在本例中为 quantity
)(innerHTML
).如果它不存在,那么它将 returned undefined
。然后 ??
将启动,而 return 0
将代替。
这解决了获取当前值的问题。
但是,您正在尝试设置一个可能不存在的事物的值。这是个坏消息。有几种方法可以解决这个问题,但最好的方法可能就是检查它是否是错误的,如果是,请继续创建它:
if (!quantity) {
// code to create quantity and apparent it to its parent here
// don't forget to set its default value to 0.
// and assign it to quantity
}
或者,更好的是:
const quantity = document.querySelector('.product__quantity') ?? createQuantity();
// createQuantity() being the function that creates and returns the element.
如果将该块放在 const currentValue
行之前,则无需执行处理 null 的操作,只需执行以下操作即可:
const currentValue = Number(quantity.innerHTML);
另外,我不确定你想要这个位做什么:
Number(quantity.innerHTML) < this._data.stocks
? (quantity.innerHTML = currentValue + 1)
: 1;
但是它是如何写的,最后一个 1
只是被扔掉并且什么都不做,所以,假设您只想增加数量,如果它少于当前库存,您应该将它重写为是:
currentValue < this._data.stocks && (quantity.innerHTML = currentValue + 1);
(还有,只小于,不小于等于?)
旁注:您可能应该使用 .textContent
或 .innerText
而不是 .innerHTML
来获取数量,因为您不想要任何 HTML挂在那里,只有文本值。更好的是,根本不解析文本,只将值存储为 属性 ,当它发生变化时写出来:
// initialize
quantity.value = 0;
// increment
quantity.value++;
quantity.innerText = quantity.value;
要创建 quantity
元素,您可以这样做:
function createQuantity() {
// Use whatever element it should be
const quantity = document.createElement('span');
quantity.classList.add('product__quantity');
// You'll probably need to tweak this to get it in the right spot
__parentElement.appendChild(quantity);
return quantity;
}
如何检查一个元素是否存在于父元素中?我在我的项目中为产品数量实现了一个 increase/decrease 按钮。当用户单击这些按钮时,我可以增加和减少数量。我有一个 _parentElement,它呈现一个元素和数据以及错误消息(这只会在出现错误时呈现)。我已将点击事件附加到该 _parentElement(这在 DOM 中可见)并执行事件委托。
仅当在 _parentElement 中呈现错误消息以及当我单击 _parentElement 时才会记录此错误。
错误:Cannot read properties of null (reading 'innerHTML') at DetailView._handlerQuantity
这是我所做的:
View.js
import icons from 'url:../../icons/icons.svg';
export default class View {
_data;
renderError(message = this._errorMessage) {
const html = /*html*/ `
<div class="flex flex-col items-center justify-center gap-4 min-h-[inherit]">
<svg class="h-6 w-6 sm:h-10 sm:w-10 fill-red-600">
<use xlink:href="${icons}#icon-warning"></use>
</svg>
<span class="text-xl text-neutral-600 font-medium sm:text-xl xs:text-lg">${message}</span>
</div>
`;
const markup = this._parseStringtoHTML(html);
this._parentElement.innerHTML = '';
this._parentElement.insertAdjacentElement('afterbegin', markup.body.firstElementChild);
}
}
详情View.js
class DetailView extends View {
_parentElement = document.querySelector(".product__details");
_errorMessage = "We could'nt find the product. Please try another one!";
constructor() {
super();
this._addHandlerProductQuanity();
}
_handlerQuantity(e) {
const increase = e.target.closest(".btn__control--add");
const decrease = e.target.closest(".btn__control--minus");
let quantity = document.querySelector(".product__quantity");
const currentValue = Number(quantity.innerHTML) || 0;
if (increase)
Number(quantity.innerHTML) < this._data.stocks
? (quantity.innerHTML = currentValue + 1)
: 1;
if (decrease)
Number(quantity.innerHTML > 1)
? (quantity.innerHTML = currentValue - 1)
: 1;
}
_addHandlerProductQuanity() {
this._parentElement.addEventListener(
"click",
this._handlerQuantity.bind(this)
);
}
}
HTML:
<main class="main min-h-[calc(100vh-5rem)] sm:min-h-[calc(100vh-8rem)]">
<section class="product__details min-h-[inherit]">
<!-- PRODUCTS DETAILS WILL GO HERE... -->
</section>
</main>
而不是这个:
const currentValue = Number(quantity.innerHTML) || 0;
你可以这样做:
const currentValue = Number(quantity?.innerHTML ?? 0);
?.
基本上会在尝试获取右侧的 属性 之前检查左侧的对象是否存在(在本例中为 quantity
)(innerHTML
).如果它不存在,那么它将 returned undefined
。然后 ??
将启动,而 return 0
将代替。
这解决了获取当前值的问题。
但是,您正在尝试设置一个可能不存在的事物的值。这是个坏消息。有几种方法可以解决这个问题,但最好的方法可能就是检查它是否是错误的,如果是,请继续创建它:
if (!quantity) {
// code to create quantity and apparent it to its parent here
// don't forget to set its default value to 0.
// and assign it to quantity
}
或者,更好的是:
const quantity = document.querySelector('.product__quantity') ?? createQuantity();
// createQuantity() being the function that creates and returns the element.
如果将该块放在 const currentValue
行之前,则无需执行处理 null 的操作,只需执行以下操作即可:
const currentValue = Number(quantity.innerHTML);
另外,我不确定你想要这个位做什么:
Number(quantity.innerHTML) < this._data.stocks
? (quantity.innerHTML = currentValue + 1)
: 1;
但是它是如何写的,最后一个 1
只是被扔掉并且什么都不做,所以,假设您只想增加数量,如果它少于当前库存,您应该将它重写为是:
currentValue < this._data.stocks && (quantity.innerHTML = currentValue + 1);
(还有,只小于,不小于等于?)
旁注:您可能应该使用 .textContent
或 .innerText
而不是 .innerHTML
来获取数量,因为您不想要任何 HTML挂在那里,只有文本值。更好的是,根本不解析文本,只将值存储为 属性 ,当它发生变化时写出来:
// initialize
quantity.value = 0;
// increment
quantity.value++;
quantity.innerText = quantity.value;
要创建 quantity
元素,您可以这样做:
function createQuantity() {
// Use whatever element it should be
const quantity = document.createElement('span');
quantity.classList.add('product__quantity');
// You'll probably need to tweak this to get it in the right spot
__parentElement.appendChild(quantity);
return quantity;
}