我有一个<select>,有一些选择。当选择一个选项时,我希望它从<select>中消失并出现在div中。然后,当选项在div中时,如果单击它,我希望它消失并返回选择。
我有这样的代码:
jQuery:
$(".car").click(function()
{
var $id = $('#selector option:selected').val();
var $text = $('#selector option:selected').text();
$("#selector option[value='" + $id + "']").remove();
$('.cars').append('<div class="hey" id="' + $id + '">' + $text + '</div>');
$(".hey").click(function () {
$(this).remove();
var $value = $(this).attr('id');
var $text1 = $(this).text();
$('#selector').append('<option class="car" value="' + $value +'">' + $text1 +'</option>');
});
});HTML:
<div id="myDiv">
<div class="cars">
</div>
</div>
<select id="selector">
<option class="car" value="alfaromeo">Alfa Romeo</option>
<option class="car" value="volvo">Volvo</option>
<option class="car" value="ford">Ford</option>
<option class="car" value="opel">Opel</option>
</select>https://jsfiddle.net/jqvtyt7f/
但也有一些巨大的问题。如果我同时选择多个汽车品牌,当单击某个品牌时,该品牌会返回重复2、3或4次的列表(取决于所选品牌的数量及其位置),我也不能多次重新选择一个选项.
我是一个使用javascript的新手,我不知道发生了什么。任何帮助都将不胜感激。
发布于 2015-10-19 00:13:57
没有真正的理由为此使用jQuery,除了语法糖和跨浏览器兼容性(尽管我认为大多数浏览器,包括IE9和更高版本应该与普通JavaScript一起工作)。所以,当我有时间的时候,我想我应该提供一个简单的JS方法:
// pairing both functions within a parent object:
var options = {
// defining the name of the function:
'optionToDiv' : function () {
// this is the changed-<select> element passed
// automagically from addEventListner() (later):
var select = this,
// retrieving the selected <option> from the <select>,
// by looking at the options collection of the <select>
// and using the selectedIndex property of the
// HTMLSelectElement which gives the index of the
// selected <option> in the collection of options:
selectedOption = select.options[select.selectedIndex],
// creating a <span> element for use:
span = document.createElement('span'),
// retrieving the <div> element we're adding the
// <span> to:
div = document.querySelector('#myDiv > div.cars');
// setting the data-value property to be equal to
// the value property of the <option> (for moving the
// 'option' back into the <select>):
span.dataset.value = selectedOption.value;
// setting the text of the <span> to the <option>
// element's text:
span.textContent = selectedOption.text;
// if we already have a <span> (or rather 'child') present
// in the <div>:
if (div.children.length) {
// we append a new Option to the <select> element,
// here we use the new Option(text, value, selected)
// constructor; passing in the text of the <span> as,
// the <option> text, and the data-value of the span as
// the value:
select.appendChild(new Option(div.firstChild.textContent, div.firstChild.dataset.value));
// then we replace the current first-child of the <div>
// with the newly-created <span>:
div.replaceChild(span, div.firstChild)
}
else {
// otherwise we simply append the newly-created
// <span> element to the <div>:
div.appendChild(span);
}
// and then remove the selected <option> from the <select>:
selectedOption.parentNode.removeChild(selectedOption);
},
// name of the function that handles moving the <span>
// back to the <select> element (as an <option>):
'optionToSelect' : function () {
// finding the <select> element:
var select = document.getElementById('selector');
// as above, appending a newly-created <option> element
// using the new Option(text, value, selected) constructor:
select.appendChild(new Option(this.firstChild.textContent, this.firstChild.dataset.value));
// removing the first-child of the clicked <div>
// (which is 'this' in this function):
this.removeChild(this.firstChild);
}
};
// retrieving the <select> element:
var select = document.getElementById('selector'),
// retrieving the (relevant) <div> element:
div = document.querySelector('#myDiv > div.cars');
// binding the named-function as the change event-handler
// of the <select> element:
select.addEventListener('change', options.optionToDiv);
// binding the named-function as the click event-handler
// of the <div> element:
div.addEventListener('click', options.optionToSelect);
var options = {
'optionToDiv': function() {
var select = this,
selectedOption = select.options[select.selectedIndex],
span = document.createElement('span'),
div = document.querySelector('#myDiv > div.cars');
span.dataset.value = selectedOption.value;
span.textContent = selectedOption.text;
if (div.children.length) {
select.appendChild(new Option(div.firstChild.textContent, div.firstChild.dataset.value));
div.replaceChild(span, div.firstChild)
} else {
div.appendChild(span);
}
selectedOption.parentNode.removeChild(selectedOption);
},
'optionToSelect': function() {
var select = document.getElementById('selector');
select.appendChild(new Option(this.firstChild.textContent, this.firstChild.dataset.value));
this.removeChild(this.firstChild);
}
};
var select = document.getElementById('selector'),
div = document.querySelector('#myDiv > div.cars');
select.addEventListener('change', options.optionToDiv);
div.addEventListener('click', options.optionToSelect);.hey {
position: relative;
margin-right: 5px;
padding: 3px;
border-radius: 5px;
border: 1px solid #c3c3c3;
float: left;
cursor: pointer;
}<div id="myDiv">
<div class="cars"></div>
</div>
<select id="selector">
<option class="car" value="alfaromeo">Alfa Romeo</option>
<option class="car" value="volvo">Volvo</option>
<option class="car" value="ford">Ford</option>
<option class="car" value="opel">Opel</option>
</select>
JS Fiddle演示,用于实验和开发。
正如Steve在下面的评论中所指出的,上述解决方案并不是预期的功能:
…逻辑是不正确的:它只会将第一个选择添加到div中,然后不会再添加更多内容。在要向div添加选项的代码中,您要向select添加一个选项(然后删除原始选项)。您正在用最新的选择替换div中的任何项&它应该添加它们为…。
要纠正这个不正确的逻辑,只需要删除if (div.children.length) / else块;并将其全部替换为包含在else - div.replaceChild(span, div.firstChild)中的所有代码,这将提供以下代码(如前所述,因此未注释):
var options = {
'optionToDiv': function () {
var select = this,
selectedOption = select.options[select.selectedIndex],
span = document.createElement('span'),
div = document.querySelector('#myDiv > div.cars');
span.dataset.value = selectedOption.value;
span.textContent = selectedOption.text;
// removed the surrounding if/else block,
// replacing it with this single line which
// always adds the selected <option> to the
// <div>:
div.appendChild(span);
selectedOption.parentNode.removeChild(selectedOption);
},
'optionToSelect': function () {
var select = document.getElementById('selector');
select.appendChild(new Option(this.firstChild.textContent, this.firstChild.dataset.value));
this.removeChild(this.firstChild);
}
};
var select = document.getElementById('selector'),
div = document.querySelector('#myDiv > div.cars');
select.addEventListener('change', options.optionToDiv);
div.addEventListener('click', options.optionToSelect);
var options = {
'optionToDiv': function() {
var select = this,
selectedOption = select.options[select.selectedIndex],
span = document.createElement('span'),
div = document.querySelector('#myDiv > div.cars');
span.dataset.value = selectedOption.value;
span.textContent = selectedOption.text;
div.appendChild(span);
selectedOption.parentNode.removeChild(selectedOption);
},
'optionToSelect': function() {
var select = document.getElementById('selector');
select.appendChild(new Option(this.firstChild.textContent, this.firstChild.dataset.value));
this.removeChild(this.firstChild);
}
};
var select = document.getElementById('selector'),
div = document.querySelector('#myDiv > div.cars');
select.addEventListener('change', options.optionToDiv);
div.addEventListener('click', options.optionToSelect);.hey {
position: relative;
margin-right: 5px;
padding: 3px;
border-radius: 5px;
border: 1px solid #c3c3c3;
float: left;
cursor: pointer;
}
div.cars span {
display: block;
}<div id="myDiv">
<div class="cars"></div>
</div>
<select id="selector">
<option class="car" value="alfaromeo">Alfa Romeo</option>
<option class="car" value="volvo">Volvo</option>
<option class="car" value="ford">Ford</option>
<option class="car" value="opel">Opel</option>
</select>
JS Fiddle演示,用于实验和开发。
当然,值得注意的是,现有答案的另一个明显缺陷是:由于<option>的移动是基于change事件的,这意味着第一个<option>永远不会出现在列表中--因为选择<option>会从<select>中删除它,所以第一个<option>再次被选中,从而防止<select>‘改变’。
因此,此更新使用一个简单的函数将'Please select' <option>添加到<select>元素中:
var options = {
// name of the 'initialisation' function:
'init': function () {
// getting the <select> element:
var select = document.getElementById('selector');
// inserting a new Option before the current firstChild
// of the <select> element, using the
// new Option(text, value, defaultSelected, selected)
// constructor:
select.insertBefore(new Option('Please select', '-1', true, true), select.firstChild);
},
'optionToDiv': function () {
var select = this,
selectedOption = select.options[select.selectedIndex],
span = document.createElement('span'),
div = document.querySelector('#myDiv > div.cars');
span.dataset.value = selectedOption.value;
span.textContent = selectedOption.text;
div.appendChild(span);
selectedOption.parentNode.removeChild(selectedOption);
},
'optionToSelect': function () {
var select = document.getElementById('selector');
select.appendChild(new Option(this.firstChild.textContent, this.firstChild.dataset.value));
this.removeChild(this.firstChild);
}
};
options.init();
var select = document.getElementById('selector'),
div = document.querySelector('#myDiv > div.cars');
select.addEventListener('change', options.optionToDiv);
div.addEventListener('click', options.optionToSelect);
var options = {
'init': function() {
var select = document.getElementById('selector');
select.insertBefore(new Option('Please select', '-1', true, true), select.firstChild);
},
'optionToDiv': function(e) {
var select = this,
selectedOption = select.options[select.selectedIndex],
span = document.createElement('span'),
div = document.querySelector('#myDiv > div.cars');
span.dataset.value = selectedOption.value;
span.textContent = selectedOption.text;
div.appendChild(span);
selectedOption.parentNode.removeChild(selectedOption);
},
'optionToSelect': function() {
var select = document.getElementById('selector');
select.appendChild(new Option(this.firstChild.textContent, this.firstChild.dataset.value));
this.removeChild(this.firstChild);
}
};
// calling the initialisation function:
options.init();
var select = document.getElementById('selector'),
div = document.querySelector('#myDiv > div.cars');
select.addEventListener('change', options.optionToDiv);
div.addEventListener('click', options.optionToSelect);.hey {
position: relative;
margin-right: 5px;
padding: 3px;
border-radius: 5px;
border: 1px solid #c3c3c3;
float: left;
cursor: pointer;
}
div.cars span {
display: block;
}<div id="myDiv">
<div class="cars"></div>
</div>
<select id="selector">
<option class="car" value="alfaromeo">Alfa Romeo</option>
<option class="car" value="volvo">Volvo</option>
<option class="car" value="ford">Ford</option>
<option class="car" value="opel">Opel</option>
</select>
外部JS Fiddle演示,用于实验和开发。
参考文献:
发布于 2015-10-18 23:43:45
我会使用select列表的change事件,而不是它中的每个选项。
不需要使用$("#selector optionvalue='“”+ $id + "'").remove();对于要删除的选择--您已经有了所选选项,因此$(‘选择器选项: selected’).remove()就足够了。
另外,在从列表中删除之前,我会将项添加到Div中,以防出现将其添加到Div的问题,您仍将在列表中拥有该项.
最后,在添加项目之前,只需检查一下列表中还没有该项目!
所以:
$("#selector").change(function() {
var $id = $('#selector option:selected').val();
var $text = $('#selector option:selected').text();
$('#selector option:selected').remove();
$('.cars').append('<div class="hey" id="' + $id + '">' + $text + '</div>');
$(".hey").click(function() {
var $value = $(this).attr('id');
var $text1 = $(this).text();
if ($("#selector option[value='" + $value + "']").val() === undefined) {
$('#selector').append('<option class="car" value="' + $value + '">' + $text1 + '</option>');
}
$(this).remove();
});
});
稍微干净一点的是:
var carDiv = document.getElementById('myDiv').querySelector('.cars');
$("#selector").change(function() {
var newDiv = document.createElement('div');
newDiv.id = $('#selector option:selected').val();
newDiv.innerHTML = $('#selector option:selected').text();
carDiv.appendChild(newDiv);
$(newDiv).click(function() {
putBackInList(this);
});
$('#selector option:selected').remove();
});
function putBackInList(item) {
if ($("#selector option[value='" + item.id + "']").val() === undefined) {
$('#selector').append(new Option(item.innerHTML, item.id));
}
$(item).remove();
}
这将向每个div元素添加一个click函数,以调用单个函数来完成这项工作,而不是每次从列表中选择一个选项时,都会为“嘿嘿”类重复该函数。
发布于 2015-10-18 23:19:10
在我看来,这里有很多问题,还有一些效率低下的问题。我认为您将单击事件添加到.hey太多了。每次单击选项时,都会将其添加到带有.hey的所有元素中。见此:
$("#selector").click('.car', function()
{
var $id = $(this).val(), //$(this) represents the element clicked
$text = $(this).text();
$(this).remove(); //again, $(this) represents the element
$('.cars').append('<div class="hey" id="' + $id + '">' + $text + '</div>');
});
$("#myDiv").click('.hey', function () {
$(this).remove();
var $value = $(this).attr('id');
var $text1 = $(this).text();
$('#selector').append('<option class="car" value="' + $value +'">' + $text1 +'</option>');
});我所做的是:
$(this)以提高效率。.hey的单击事件,并将其移至.car单击事件之外。[context][1]将它们添加到他们的父母中。由于您在添加这些侦听器之后将DOM元素添加到堆栈中,所以每次都必须重新添加它们。像我这样提供上下文,你就不用再担心这个了。还没经过测试,但我感觉很好。
https://stackoverflow.com/questions/33204138
复制相似问题