У меня есть раскрывающийся список выбора, который при изменении я хочу, чтобы он запускал функцию и передавал значение выбора в эту функцию. Однако функция ожидает переменную, удерживающую массив, и то, что передается, является строкой (значение выбора).
Вы можете увидеть, как он работает (или не работает) в коде ниже. Выбранное значение должно представлять соответствующую переменную.
Как я могу это сделать?
var str = ["Paul", "John", "Melissa", "Mike"];
var int = [8, 4, 55, 7];
var mix = ["Paul", 9, "John", 5, "Melissa", 67, "Mike", 2];
var main = document.querySelector('#main');
var sel = document.querySelector('select');
function testFunc(arr){
arr.forEach((i) => {
var p = document.createElement('p');
p.innerHTML = i;
main.appendChild(p);
});
}
testFunc(mix);
sel.addEventListener('change', testFunc(sel.value));
<select>
<option value="str">String</option>
<option value="int">Integer</option>
<option value="mix">Mixed</option>
</select>
<div id="main"></div>
РЕДАКТИРОВАТЬ:
Я должен отметить, что массивы данных поступают динамически, и я действительно хотел бы избежать манипулирования ими, чтобы не вызывать дополнительный код и путаницу в будущих изменениях.
В вашем коде есть две проблемы:
В функции обработчика события, указав скобки после функции, вызываемой функцией при загрузке страницы. Просто вызовите функцию внутри тела функции. Это заставит функцию вызываться только при срабатывании события.
sel.value
- это строка, но функция ожидает массив. Для оценки массива динамически меняйте testFunc(mix)
на testFunc('mix')
(оберните значение параметра кавычками) и используйте объект window
например:
arr = window[arr]
Заменить:
sel.addEventListener('change', testFunc(sel.value));
С
sel.addEventListener('change', function (){testFunc([sel.value])});
var str = ["Paul", "John", "Melissa", "Mike"];
var int = [8, 4, 55, 7];
var mix = ["Paul", 9, "John", 5, "Melissa", 67, "Mike", 2];
var main = document.querySelector('#main');
var sel = document.querySelector('select');
function testFunc(arr){
arr = window[arr]
arr.forEach((i) => {
var p = document.createElement('p');
p.innerHTML = i;
main.appendChild(p);
});
}
testFunc('mix');
sel.addEventListener('change', function (){testFunc(sel.value)});
<select>
<option value="str">String</option>
<option value="int">Integer</option>
<option value="mix">Mixed</option>
</select>
<div id="main"></div>
[sel.value]
определенно не строка ........
как я понимаю, вы хотите сделать это:
let model = {
str : ["Paul", "John", "Melissa", "Mike"];
int : [8, 4, 55, 7];
mix : ["Paul", 9, "John", 5, "Melissa", 67, "Mike", 2];
}
function testFunc(key){
var arr = []
if(model[key]){
arr = model[key]
}
//TODO: clear parent node...
arr.forEach((i) => {
var p = document.createElement('p');
p.innerHTML = i;
main.appendChild(p);
});
}
arr = eval(arr);
var str = ["Paul", "John", "Melissa", "Mike"];
var int = [8, 4, 55, 7];
var mix = ["Paul", 9, "John", 5, "Melissa", 67, "Mike", 2];
var main = document.querySelector('#main');
var sel = document.querySelector('select');
function testFunc(arr){
arr = eval(arr);
arr.forEach((i) => {
var p = document.createElement('p');
p.innerHTML = i;
main.appendChild(p);
});
}
testFunc(mix);
sel.addEventListener('change', function(){testFunc(this.value)});
<select>
<option value="str">String</option>
<option value="int">Integer</option>
<option value="mix">Mixed</option>
</select>
<div id="main"></div>
eval
следует избегать. Это действительно не обязательно, чтобы сделать эту работу.
Несколько вещей, которые нужно изменить:
Не вызывайте функцию, которую вы передаете методу addEventListener
. Вместо этого передайте ссылку на функцию. Это может быть встроенное выражение функции. Но не называйте это.
Сделайте свои разные свойства массивов одной переменной объекта, поэтому вы можете легко ссылаться на них на основе выбранного значения.
Удаляйте вывод при каждом изменении выбора.
Запустите исходное изменение на основе элемента, выбранного при загрузке страницы.
Вот рабочая версия:
var arr = {
str: ["Paul", "John", "Melissa", "Mike"],
int: [8, 4, 55, 7],
mix: ["Paul", 9, "John", 5, "Melissa", 67, "Mike", 2]
};
var main = document.querySelector('#main');
var sel = document.querySelector('select');
function testFunc(arr){
main.innerHTML = ""; // clear the previous result
arr.forEach((i) => {
var p = document.createElement('p');
p.innerHTML = i;
main.appendChild(p);
});
}
sel.addEventListener('change', () => testFunc(arr[sel.value]));
testFunc(arr[sel.value]); // initial load
<select>
<option value="str">String</option>
<option value="int">Integer</option>
<option value="mix">Mixed</option>
</select>
<div id="main"></div>
Если ваши массивы определены в глобальной области действия, и вы ничего не можете с этим поделать, просто скопируйте ссылки на них в новом объекте:
// Defined beforehand: you cannot change this:
var str = ["Paul", "John", "Melissa", "Mike"],
var int = [8, 4, 55, 7],
var mix = ["Paul", 9, "John", 5, "Melissa", 67, "Mike", 2]
// In your part of the code, still create array as in above solution:
var arr = {str: str, int: int, mix: mix};
// If you have ES6 support you can shorten the above to:
var arr = {str, int, mix};
Если я не неправильно понял ваше требование, вы должны внести небольшие изменения в свои текущие переменные JS и перейти к Object
. После этого попробуйте этот способ добавить новые элементы абзаца в каждое event
изменения выпадающего меню, удалив существующий с помощью main.innerHTML=''
addEventListener: https://developer.mozilla.org/en-US/docs/Web/Events/change
Структура объекта: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics
var data_types = {
str: ["Paul", "John", "Melissa", "Mike"],
int: [8, 4, 55, 7],
mix: ["Paul", 9, "John", 5, "Melissa", 67, "Mike", 2]
}
var main = document.querySelector('#main');
var sel = document.querySelector('select');
function testFunc(event) {
main.innerHTML = '';
// You can use "this" to refer to the selected element.
if (!event.target.value) alert('Please Select One');
var arr = data_types[event.target.value];
arr.forEach((i) => {
var p = document.createElement('p');
p.innerHTML = i;
main.appendChild(p);
});
}
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('select[name="data-types"]').onchange = testFunc;
}, false);
<select name="data-types">
<option value="str">String</option>
<option value="int">Integer</option>
<option value="mix">Mixed</option>
</select>
<div id="main"></div>