首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在选择它们时从select中删除选项,并将值添加到div。单击div时,将选项返回给select

在选择它们时从select中删除选项,并将值添加到div。单击div时,将选项返回给select
EN

Stack Overflow用户
提问于 2015-10-18 22:51:48
回答 4查看 1.3K关注 0票数 1

我有一个<select>,有一些选择。当选择一个选项时,我希望它从<select>中消失并出现在div中。然后,当选项在div中时,如果单击它,我希望它消失并返回选择。

我有这样的代码:

jQuery:

代码语言:javascript
复制
$(".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:

代码语言:javascript
复制
<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的新手,我不知道发生了什么。任何帮助都将不胜感激。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-10-19 00:13:57

没有真正的理由为此使用jQuery,除了语法糖和跨浏览器兼容性(尽管我认为大多数浏览器,包括IE9和更高版本应该与普通JavaScript一起工作)。所以,当我有时间的时候,我想我应该提供一个简单的JS方法:

代码语言:javascript
复制
// 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);

代码语言:javascript
复制
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);
代码语言:javascript
复制
.hey {
  position: relative;
  margin-right: 5px;
  padding: 3px;
  border-radius: 5px;
  border: 1px solid #c3c3c3;
  float: left;
  cursor: pointer;
}
代码语言:javascript
复制
<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)中的所有代码,这将提供以下代码(如前所述,因此未注释):

代码语言:javascript
复制
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);

代码语言:javascript
复制
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);
代码语言:javascript
复制
.hey {
  position: relative;
  margin-right: 5px;
  padding: 3px;
  border-radius: 5px;
  border: 1px solid #c3c3c3;
  float: left;
  cursor: pointer;
}
div.cars span {
  display: block;
}
代码语言:javascript
复制
<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>元素中:

代码语言:javascript
复制
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);

代码语言:javascript
复制
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);
代码语言:javascript
复制
.hey {
  position: relative;
  margin-right: 5px;
  padding: 3px;
  border-radius: 5px;
  border: 1px solid #c3c3c3;
  float: left;
  cursor: pointer;
}
div.cars span {
  display: block;
}
代码语言:javascript
复制
<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演示,用于实验和开发。

参考文献:

票数 1
EN

Stack Overflow用户

发布于 2015-10-18 23:43:45

我会使用select列表的change事件,而不是它中的每个选项。

不需要使用$("#selector optionvalue='“”+ $id + "'").remove();对于要删除的选择--您已经有了所选选项,因此$(‘选择器选项: selected’).remove()就足够了。

另外,在从列表中删除之前,我会将项添加到Div中,以防出现将其添加到Div的问题,您仍将在列表中拥有该项.

最后,在添加项目之前,只需检查一下列表中还没有该项目!

所以:

代码语言:javascript
复制
$("#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();
  });
});

稍微干净一点的是:

代码语言:javascript
复制
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函数,以调用单个函数来完成这项工作,而不是每次从列表中选择一个选项时,都会为“嘿嘿”类重复该函数。

票数 2
EN

Stack Overflow用户

发布于 2015-10-18 23:19:10

在我看来,这里有很多问题,还有一些效率低下的问题。我认为您将单击事件添加到.hey太多了。每次单击选项时,都会将其添加到带有.hey的所有元素中。见此:

代码语言:javascript
复制
$("#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>');
});

我所做的是:

  1. 在选择器单击事件中使用$(this)以提高效率。
  2. 获取.hey的单击事件,并将其移至.car单击事件之外。
  3. 我没有将单击事件应用于元素本身,而是使用jQuery所称的[context][1]将它们添加到他们的父母中。由于您在添加这些侦听器之后将DOM元素添加到堆栈中,所以每次都必须重新添加它们。像我这样提供上下文,你就不用再担心这个了。

还没经过测试,但我感觉很好。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33204138

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档