2015-10-28 2 views
1

Я начинаю с js, поэтому, пожалуйста, простите мне очевидные ошибки. Я пытаюсь воссоздать выбранный ввод с несколькими параметрами для масштабируемой разметки.Редактирование textContent или innerHTML убивает eventListener

Кратко, что я пытаюсь сделать:

  1. Скрыть выберите
  2. Создать родительский DIV с текстом первого варианта и добавить его вместо оригинального скрыт выбрать.
  3. Добавить eventListener при щелчке для переключения класса (он показывает и скрывает дочерние элементы)
  4. Создайте внутренние divs со значениями и текстом опций из оригинального скрытого выбора.
  5. Добавить eventListener для каждого из них, чтобы заменить значение select.

Эти несколько строк js и несколько строк css дают мне возможность выбора стиля.

// Define select and options 
 
var select = document.getElementById('select'); 
 
var children = select.children; 
 

 
// Recreate select via divs and keep same class 
 
select.style.display = 'none'; 
 
var selectNew = document.createElement('div'); 
 
selectNew.className = select.classList; 
 
selectNew.textContent = select.children[0].text; 
 
select.parentNode.insertBefore(selectNew, select); 
 
selectNew.addEventListener('click', function() { 
 
    toggleChildren(); 
 
}); 
 

 
function toggleChildren() { 
 
    selectNew.classList.toggle('active'); 
 
} 
 

 
// remap children 
 
var childArray = []; 
 
for (var i = 0; i < children.length; i++) { 
 
    var child = document.createElement('div'); 
 
    child.innerHTML = select.children[i].text; 
 
    child.dataset.value = select.children[i].value; 
 
    selectNew.appendChild(child); 
 
    childArray.push(child); 
 

 
    child.addEventListener("click", function() { 
 
    selectChoice(); 
 
    }); 
 
} 
 

 
function selectChoice() { 
 
    var which = childArray.indexOf(event.target || event.srcElement); 
 
    select.value = children[which].value; 
 
    // selectNew.textContent = children[which].text; 
 
}
.select { 
 
    position: relative; 
 
    width: 100%; 
 
    line-height: 3em; 
 
    background: #eee; 
 
} 
 
.select > div { 
 
    position: absolute; 
 
    display: none; 
 
    width: 100%; 
 
} 
 
.select > div:nth-child(1) { 
 
    top: 2em; 
 
} 
 
.select > div:nth-child(2) { 
 
    top: 4em; 
 
} 
 
.select > div:nth-child(3) { 
 
    top: 6em; 
 
} 
 
.select > div:nth-child(4) { 
 
    top: 8em; 
 
} 
 
.select > div:nth-child(5) { 
 
    top: 10em; 
 
} 
 
.select > div:hover { 
 
    background: #eee; 
 
} 
 
.select.active > div { 
 
    display: block; 
 
}
<select name="sortby" id="select" class="select"> 
 
    <option value="val1">Value 1</option> 
 
    <option value="val2">Value 2</option> 
 
    <option value="val3">Value 3</option> 
 
    <option value="val4">Value 4</option> 
 
    <option value="val5">Value 5</option> 
 
</select>

Всякий раз, когда я пытаюсь обновить текст внутри моего родительского элемента, чтобы показать текст выбранной опции через:

selectNew.textContent = children[which].text; 

Он убивает ранее добавил событие Listener для этого элемента. Может кто-нибудь помочь мне понять, что я делаю неправильно? Что мне не хватает в поведении eventListeners?

+0

Спасибо так много!Как я уже сказал, я смотрю сейчас, и это сложно с самого начала, но это весело. Это легко понять, почему этот человек не работает? 'select.addEventListener ('изменение', функция() { оповещения ('выберите изменен'); })' Спасибо так много раз –

ответ

1

Это не убивает ваше мероприятие, вы удаляете свои опционные элементы, установив TextContent поэтому при нажатии на div нет ничего, что можно было бы отобразить. Вам нужно установить textContent первого TextNode вашего div.

// Define select and options 
 
var select = document.getElementById('select'); 
 
var children = select.children; 
 

 
// Recreate select via divs and keep same class 
 
select.style.display = 'none'; 
 
var selectNew = document.createElement('div'); 
 
selectNew.className = select.classList; 
 
selectNew.textContent = select.children[0].text; 
 
select.parentNode.insertBefore(selectNew, select); 
 
selectNew.addEventListener('click', function(e) { 
 
    toggleChildren(e); 
 
}); 
 

 
function toggleChildren() { 
 
    selectNew.classList.toggle('active'); 
 
} 
 

 
// remap children 
 
var childArray = []; 
 
for (var i = 0; i < children.length; i++) { 
 
    var child = document.createElement('div'); 
 
    child.innerHTML = select.children[i].text; 
 
    child.dataset.value = select.children[i].value; 
 
    selectNew.appendChild(child); 
 
    childArray.push(child); 
 

 
    child.addEventListener("click", function() { 
 
    selectChoice(); 
 
    }); 
 
} 
 

 
function selectChoice() { 
 
    var which = childArray.indexOf(event.target || event.srcElement); 
 
    select.value = children[which].value; 
 

 
    //get the first textnode and set its textContent 
 
    selectNew.childNodes[0].textContent = children[which].text; 
 
}
.select { 
 
    position: relative; 
 
    width: 100%; 
 
    line-height: 3em; 
 
    background: #eee; 
 
} 
 
.select > div { 
 
    position: absolute; 
 
    display: none; 
 
    width: 100%; 
 
} 
 
.select > div:nth-child(1) { 
 
    top: 2em; 
 
} 
 
.select > div:nth-child(2) { 
 
    top: 4em; 
 
} 
 
.select > div:nth-child(3) { 
 
    top: 6em; 
 
} 
 
.select > div:nth-child(4) { 
 
    top: 8em; 
 
} 
 
.select > div:nth-child(5) { 
 
    top: 10em; 
 
} 
 
.select > div:hover { 
 
    background: #eee; 
 
} 
 
.select.active > div { 
 
    display: block; 
 
}
<select name="sortby" id="select" class="select"> 
 
    <option value="val1">Value 1</option> 
 
    <option value="val2">Value 2</option> 
 
    <option value="val3">Value 3</option> 
 
    <option value="val4">Value 4</option> 
 
    <option value="val5">Value 5</option> 
 
</select>

+0

Большое вам спасибо! Как я уже сказал, я смотрю сейчас, и это сложно с самого начала, но это весело. Это легко понять, почему этот человек не работает? 'select.addEventListener ('change', function() { alert ('select changed'); })' Еще раз спасибо –

1

Линия, на которую вы ссылаетесь, вызывает проблему, но не потому, что она убивает слушателя. Он фактически заменяет весь контент вашего selectNew текстом. Вы хотите заменить текст первого дочернего элемента, который является узлом textContent.

Если вы измените строку:

selectNew.firstChild.textContent = children[which].text; 

то все работает, как ожидалось.

JSFiddle here.

Bonus ответить Что касается дополнительного вопроса, чтобы добавить слушатель, чтобы изменить событие: Вы не можете использовать только для слушателя «изменений» событий на DIV, только на элементах формы, как вход.

Однако, вы можете обнаружить изменения внутри обработчика щелчка, например, так:

function selectChoice() { 
    var which = childArray.indexOf(event.target || event.srcElement); 
    select.value = children[which].value; 
    if (selectNew.firstChild.textContent != children[which].text) { 
     alert('select value has been changed'); 
     selectNew.firstChild.textContent = children[which].text; 
    } 
} 

Обновлено fiddle here

+0

Спасибо так много! Как я уже сказал, я смотрю сейчас, и это сложно с самого начала, но это весело. Чтобы не задавать следующий вопрос, могу ли я использовать ваш барин js, чтобы помочь мне со следующей небольшой проблемой? Почему этот не работает для меня? Большое спасибо! Не могу поблагодарить! 'select.addEventListener ('изменение', функция() { оповещения ('выберите изменен'); })' Спасибо так много снова –

+1

Добро пожаловать! Если вы хотите использовать мой JSFiddle и обновление: вы можете изменить все, что захотите, по ссылке, которую я предоставил (щелкните Run to test). Но вы не можете спасти. Если вы тоже этого захотите: вы можете создать свою собственную (бесплатную) учетную запись, а затем нажать кнопку «Вилка» на моей скрипке. Затем вы можете обновлять и сохранять, чтобы делать все, что вам нравится. – wintvelt

+0

Я могу верить, насколько ты полезен! Я должен вам пиво, когда вы приближаетесь к середине Великобритании! Там вы идете, я просто хотел бы обнаружить, когда значение select изменилось. Http://jsfiddle.net/pawelgrzybek/gym4wnLu/1/ Very (загрузочный вкладка js) –

Смежные вопросы