Как изменять элемент в зависимости от значения input с помощью js?

185
29 января 2020, 12:00

Возможно в заголовке не получилось передать суть вопроса. Дело вот в чем. Есть текстовые input

<input class="goods-item" type="text" id="goods_1">
<input class="goods-item" type="text" id="goods_2">

и есть блок, в который хочу добавлять элементы span со значениями этих input,

<div id="categories"></div>

а потом при изменении значения input заменять значение элемента, не добавляя новый. Вот js

var category1, category2;
var goodsItem = document.getElementsByClassName('goods-item'); //получаю input
var categOutput = document.getElementById('categories'); //получаю div, куда буду выводить значения input
for ( let i = 0; i < goodsItem.length; i++) {
    goodsItem[i].addEventListener( "change", getCategory);
} //добавляю событие, при котором пользователь вводит что-то в input
function getCategory(event) {
    let target = event.target;
    var span = document.createElement('span'); 
    if (target == goodsItem[0]) {
        category1 = target.value;
        categOutput.appendChild(span);
        span.className = 'class';
        span.innerHTML = category1;
    }
    if (target == goodsItem[1]) {
        category2 = target.value;
        categOutput.appendChild(span);
        span.className = 'class';
        span.innerHTML = category2;
    }
    } 

в функции пытаюсь, чтобы при срабатывании события на каком-то из input, создавался в div некий span, получающий класс class и показывающий значение, введенное в input это не важно, но вот стили нового span

.class {
  display: inline-block;
  background: #C2185B;
  min-width: 100px;
  height: 26px;
}

По-началу все работает хорошо, но когда я пытаюсь поменять значение, введенное в input, срабатывает функция и добавляет новый span. Я понимаю, почему так происходит, но не могу догнать, как это изменить. Может кто из тех, кто дочитал до этого места, подскажет?)

Answer 1

Вы по каждому изменению создаете новый элемент, вместо этого можно создать элемент по одному разу для каждого инпута, в этом примере я сохранил ссылки на элементы прямо в инпуте this.span = ..., и при следующем вызове проверяю наличие этого поля

var goodsItem = document.getElementsByClassName('goods-item');  
var categOutput = document.getElementById('categories');  
 
for ( let i = 0; i < goodsItem.length; i++) { 
    goodsItem[i].addEventListener( "change", getCategory); 
}  
 
function getCategory(event) { 
    if (event.target.value === ''){ 
      this.span.remove(); 
      delete this.span 
      return; 
    }  
 
    if (!this.span) { 
      this.span = document.createElement('span');  
      this.span.className = 'class'; 
      categOutput.appendChild(this.span); 
    } 
    this.span.innerHTML = event.target.value; 
}
.class { 
  display: inline-block; 
  background: #C2185B; 
  min-width: 100px; 
  height: 26px; 
}
<input class="goods-item" type="text" id="goods_1"> 
<input class="goods-item" type="text" id="goods_2"> 
<div id="categories"></div>

Answer 2

var goodsItem = document.getElementsByClassName('goods-item'); 
var categOutput = document.getElementById('categories'); 
 
var span1 = document.createElement('span'); 
span1.className = 'class'; 
span1.style.display = 'none'; 
categOutput.appendChild(span1); 
 
var span2 = document.createElement('span'); 
span2.className = 'class'; 
span2.style.display = 'none'; 
categOutput.appendChild(span2); 
 
for (let i = 0; i < goodsItem.length; i++) { 
  goodsItem[i].addEventListener("change", getCategory); 
} 
 
function getCategory(event) { 
  let target = event.target; 
  var span = document.createElement('span'); 
 
  if (target == goodsItem[0]) { 
    span1.textContent = target.value; 
    span1.style.display = span1.textContent == ""? 'none' : ''; 
  } 
  if (target == goodsItem[1]) { 
    span2.textContent = target.value; 
    span2.style.display = span2.textContent == ""? 'none' : ''; 
  } 
}
.class { 
  display: inline-block; 
  background: #C2185B; 
  min-width: 100px; 
  height: 26px; 
}
<input class="goods-item" type="text" id="goods_1"> 
<input class="goods-item" type="text" id="goods_2"> 
 
<div id="categories"></div>

READ ALSO
Рекурсия с условиями, на основе массива данных

Рекурсия с условиями, на основе массива данных

У меня формируется некая схема, по которой я хочу пройтись циклом и выполнить опеределённые условия для определённых операторов

144
как изменить строку в объекте через setState? [закрыт]

как изменить строку в объекте через setState? [закрыт]

Хотите улучшить этот вопрос? Переформулируйте вопрос, чтобы он соответствовал тематике «Stack Overflow на русском»

182
Не работает слайдер в js/jquery

Не работает слайдер в js/jquery

У меня есть две функции, которые показывают / скрывают элементы за счет манипуляции классами и css переходами:

129