gpt4 book ai didi

javascript - 在另一个事件监听器的函数中使用一个事件监听器是一种不好的做法吗?

转载 作者:行者123 更新时间:2023-12-02 23:58:13 25 4
gpt4 key购买 nike

我的代码按预期运行,我正在从数组创建一个下拉菜单。然后,我获取每个下拉列表的值,并根据下拉列表的选择将一个变量分配给一个数字。然后通过innerHTML 在p> 中显示变量结果。 (我尝试使用 appendChild(document.createTextNode) 而不是innerHTML,但它只会继续将结果添加到 p> 中。

我需要它根据下拉菜单进行更改(而不是添加)。此外,我需要变量结果(数字)和 event.target.value下拉列表的信息将传递到输入字段上的另一个事件监听器,该输入字段接受用户输入并将来自第一个事件监听器中的变量的输入相乘。然后将innerHTML注入(inject)第二个<p>

我得到了这个工作,但问题是,将一个事件监听器放入另一个事件监听器中是不好的做法吗?还有其他解决方案吗?我尝试拉出第一个回调函数并使用返回的变量创建自己的函数。我将其调用给第二个事件监听器,但项目最终未定义(特别是 event.target.value)。

这是我的代码库:

HTML

<select id='cameraMakes' class='cameraSelects'></select>
<p id='yourCrop'></p>
<input id="length" type="text" name="lens" placeholder="Enter lens mm a" /><br>
<p id='results'></p>

JS

const cameraMakeArray = ['Canon5DM2', 'PanasonicGH5', 'SonyA7CropMode']
const cameraMake = document.getElementById("cameraMakes")
const length = document.getElementById("length")
const yourCrop = document.querySelector("#yourCrop")
const results = document.querySelector("#results")

cameraMakeArray.forEach(camera => {
let opt = document.createElement('option');
opt.innerHTML = camera;
opt.value = camera;
document.createElement
cameraMake.appendChild(opt);
})

cameraMake.addEventListener('change', (event) => {
let crop = 0
if (event) {
results.innerHTML = '';
length.value = ''
}
if (event.target.value === 'Canon5DM2') {
crop = 1;
} else if (event.target.value === 'PanasonicGH5') {
crop = 2;
} else if (event.target.value === 'SonyA7CropMode') {
crop = 1.5
}
yourCrop.innerHTML = `The ${event.target.value} has a ${crop}x factor`;
length.addEventListener('input', () => {
if (length.value) {
results.innerHTML = `A ${length.value}mm lens is equivalent to a ${length.value * crop}mm lens on the ${event.target.value}`
} else {
results.innerHTML = ''
}
})
})

最佳答案

这取决于每个用例。但是,就您而言,这太过分了,因为每次 select 更改时您并不真正想要一个全新的函数,你只想改变输出。如果您只是扩大 crop 的范围,则只需设置一次输入处理程序即可。

此外,当涉及的字符串不包含任何 HTML 时,您不应使用 .innerHTML,因为 .innerHTML 会影响性能和安全性。请改用 .textContent

const cameraMakeArray = ['Canon5DM2', 'PanasonicGH5', 'SonyA7CropMode']
const cameraMake = document.getElementById("cameraMakes")
const length = document.getElementById("length")
const yourCrop = document.querySelector("#yourCrop")
const results = document.querySelector("#results")

// With the output variable stored at a higher scope than
// either callback function, one function can set it and the
// other can use it. This allows you to get rid of the nested
// event handler.
let crop = 0

cameraMakeArray.forEach(camera => {
let opt = document.createElement('option');
opt.textContent = camera;
opt.value = camera;
document.createElement
cameraMake.appendChild(opt);
});

cameraMake.addEventListener('change', (event) => {
if (event) {
results.textContent = '';
length.value = ''
}
if (event.target.value === 'Canon5DM2') {
crop = 1;
} else if (event.target.value === 'PanasonicGH5') {
crop = 2;
} else if (event.target.value === 'SonyA7CropMode') {
crop = 1.5
}
yourCrop.textContent = `The ${event.target.value} has a ${crop}x factor`;
});

length.addEventListener('input', (evt) => {
if (length.value) {
results.textContent = `A ${length.value}mm lens is equivalent to a ${length.value * crop}mm lens on the ${cameraMake.options[cameraMake.selectedIndex].textContent}`
} else {
results.textContent = '';
}
});
<select id='cameraMakes' class='cameraSelects'></select>
<p id='yourCrop'></p>
<input id="length" type="text" name="lens" placeholder="Enter lens mm a" /><br>
<p id='results'></p>

您可能还需要考虑将 select 数组值更改为对象。这样您就可以将键与值一起存储,并且无需执行任何 if/then 来根据选择设置变量。此外,如果将第二个回调分离到命名函数中,则可以在选择更改时调用它,以在输出区域中立即更新。

// Now, each camera can store a key along with a value:
const cameras = {
Canon5DM2: 1,
PanasonicGH5: 2,
SonyA7CropMode: 1.5
};

const cameraMakes = document.getElementById("cameraMakes")
const length = document.getElementById("length")
const yourCrop = document.querySelector("#yourCrop")
const results = document.querySelector("#results")

// Loop through the object:
for(camera in cameras){
let opt = document.createElement('option');
opt.textContent = camera;
opt.value = cameras[camera]; // Get the value that goes with the key
cameraMakes.appendChild(opt);
}

cameraMakes.addEventListener('change', (event) => {
yourCrop.textContent =
`The ${cameraMakes.options[cameraMakes.selectedIndex].textContent} has a ${cameraMakes.value}x factor`;
if(results.textContent !== ""){
displayResults(); // Update the output because the camera changed
}
});

// By making this a function declaration, you can call it manually
function displayResults() {
results.textContent =
`A ${length.value}mm lens is equivalent to a ${length.value * cameraMakes.value}mm lens on the ${cameraMakes.options[cameraMakes.selectedIndex].textContent}`;
}

length.addEventListener('input', displayResults);
<select id='cameraMakes' class='cameraSelects'></select>
<p id='yourCrop'></p>
<input id="length" type="text" name="lens" placeholder="Enter lens mm a" /><br>
<p id='results'></p>

关于javascript - 在另一个事件监听器的函数中使用一个事件监听器是一种不好的做法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55285612/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com