Javascript clone node is not copying all values fr

2019-01-29 00:04发布

问题:

<div class="container">
  <select class="btn" name="item">
    <option>Alpha</option>
    <option>Beta</option>
    <option>Gamma</option>
    <option>Theta</option>
  </select>
  <input type="text" class="desc" name="desc">
</div>

In this example, element selected by default in the "select" dropdown is "Alpha". I want to clone the complete node with values. If i select a different value in the dropdown and enter some text in the input box, and then clone the node, only the text box value is cloned. The value of "select" dropdown in the new object remains the default (Alpha).

Why is the behavior of cloning different for "select" vs "input"?

var parent = document.querySelector(".container");
var button = parent.querySelector(".btn");
var textbox = parent.querySelector(".desc");

  > textbox.value
  < "some random text"
  > button.value
  < "Gamma"

var cloned = parent.cloneNode(true);
var childButton = cloned.querySelector(".btn");
var childTextbox = cloned.querySelector(".desc");

  > childTextbox.value
  < "some random text"
  > childButton.value
  < "Alpha"

回答1:

When you change a selection, the state of the selection is stored in browser and the cloned node will never include the state of object/ element which is changed and/or stored by browser.

But for input, it is stored as a value of the attribute value and get cloned.

To clone a node with selected value,

You should detect the change event and add a selected attribute to it.

That is, add an event listener for select for change event.

Then in the callback function, set the attribute selected to that object by using

selectElement.options[selectElement.selectedIndex].setAttribute("selected","");

Run the snippet below.

Select any value from the list and type something in the text box and click clone button.

var parent = document.querySelector(".container");
var button = parent.querySelector(".btn");
var textbox = parent.querySelector(".desc");
console.log(button.value);
console.log(textbox.value);
function update(val){
  val.options[val.selectedIndex].setAttribute("selected","");
  
}


function clone(){
  var cloned = parent.cloneNode(true);
  document.querySelector(".container-2").appendChild(cloned);
  var childButton = cloned.querySelector(".btn");
  var childTextbox = cloned.querySelector(".desc");
  console.log(button.value);
  console.log(textbox.value);
}
<div class="container">
  <select class="btn" name="item" onchange="update(this);">
    <option>Alpha</option>
    <option>Beta</option>
    <option>Gamma</option>
    <option>Theta</option>
  </select>
  <input type="text" class="desc" name="desc">
</div>
<button onclick="clone();">Clone</button>
<div class="container-2"></div>



回答2:

I use the getElementsByClass() method to get the interesting elements.Then via for loop I add an onchange event to clone the container.Note the at the end of the function i assign the value pf the parent select element to the cloned select elm.

var parent = document.getElementsByClassName("container");
var button = document.getElementsByClassName("btn");


for(var i=0;i<button.length;i++){
button[i].onchange=function(){  
var cloned = parent[0].cloneNode(true);  
 console.log(cloned);
 document.body.appendChild(cloned);
  cloned.childNodes[1].value=this.value;
};
}
<div class="container">
  <select class="btn" name="item">
    <option>Alpha</option>
    <option>Beta</option>
    <option>Gamma</option>
    <option>Theta</option>
  </select>
  <input type="text" class="desc" name="desc">
</div>



回答3:

Cloning a <select> does not copy the value= property on <option>s.

This happens because changing the attribute changes the state of the form control, but does not change the value of the HTML selected attribute of the element.
You can read more about it in W3 specs.

In your example, if you check the value of the parent node you will see that only that element will have the correct selected value and none of its clones.