temporarily removing and later reinserting a DOM e

2020-06-30 12:20发布

问题:

Is there some jquery magic that will let me do the following:

[0- define some element in HTML (eg, a unchecked checkbox)]

1- update its DOM element by setting one of its attributes using .attr() (eg, by setting its "checked" attribute using .attr('checked', true) )

2- temporarily remove that element from the DOM

3- reinsert the original element into the DOM, while preserving all its properties (ie, so that it is checked as it was at the end of step 1-- NOT like it was when initially defined in the HTML)

The reason why I am interested in removing these elements from the DOM (rather than hiding them) is that I have noticed that it seems to improve performance a good bit. My page has three different "states" and only a third of the total number of DOM elements is needed in any given state. [I wish to keep it as a single page with different states rather than breaking it into three separate pages.]

Until now I had been removing and reinserting elements into the DOM by storing in a var the value of

$("#myElement").html()

and then removing it, but now I noticed that upon reinsertion of that HTML into the DOM the changes made [in step 1] had been "undone".

Is there a way to do this -- to temporarily remove unneeded stuff from the DOM in a way that preserves all its properties for later reinsertion?

thanks for any insight,

lara

回答1:

You may use the clone method:

var els = $('.els'), saved = els.clone (true);
els.remove ();
// .... do other stuff
saved.appendTo ($('.wherever-you-want-to'));

That said, though, it's better to show & hide them (via display: none, for example), than to manipulate the DOM as it's very expensive. If you have to, use DOM insertion & removal (as above), rather than .html (), which recreated a node from the given string every time.



回答2:

Six days after the question was answered jQuery released 1.4 which contains the detach method. Which does exactly what you're looking for.

var detached = $('#element').detach();
$('body').append(detached);


回答3:

Just remove the element from the document and keep a reference to it. There's no need to clone it.

var el;

function removeEl() {
    el = $("#myElement")[0]; // Get the element itself
    el.parentNode.removeChild(el);
}

function reinsertEl(node) {
    node.appendChild(el);
}

As an aside since you mentioned it in your example, it's much simpler, clearer and faster to set the checked property of a checkbox directly rather than use attr(). There's no need to involve attributes at all and indeed jQuery's attr() usually doesn't. Just do $("#myElement")[0].checked = true;. It works in all mainstream browsers.



回答4:

This is not entirely relevant but may be helpful to someone else sometime later on. I found with a small form of checkboxes it's easier to prevent checking them altogether. This may come in handy in situations where you may have a questionnaire or a series of options of a product with varying values. you could even look at changing the attributes on an input on change of another element or the element in questions, This can potentially create a lot of cool things, here is a good link i found on stack overflow for this Set new id with jQuery.

$("#ch1").change(function() {
$("#ch1").prop('disabled', true);
});
$("#ch2").change(function() {
$("#ch2").prop('disabled', true);
});
$("#ch3").change(function() {
$("#ch3").prop('disabled', true);
$("#ch4").prop('disabled', false);
});
$("#ch4").change(function() {
$("#ch4").prop('disabled', true);
$("#ch3").prop('disabled', false);
});
// ----> using Name selector :
//$('input[name="checkbox5"]').click(function(){
//$('input[name="checkbox6"]').prop('checked', false);			 
//    });
//$('input[name="checkbox6"]').click(function(){
//$('input[name="checkbox5"]').prop('checked', false);			 
//    });
// ----> using ID selector :
//$('input[id="ch5"]').click(function(){
//$('input[id="ch6"]').prop('checked', false);			 
//    });
// OR
//$("#ch5").click(function(){
//$("#ch6").prop('checked', false);
// });
//$("#ch6").click(function(){
//$("#ch5").prop('checked', false);			 
//    });
// ----> Using Class Selector :
$("input.checklast").change(function() {
    $("input.checklast").not(this).prop("checked", false);
  });
// which is shorter but requires that classes must be separated individually or grouped.
$("#ch5").change(function() {
$("#ch5").prop('disabled', true);
$("#ch6").prop('disabled', false);
});
$("#ch6").change(function() {
$("#ch6").prop('disabled', true);
$("#ch5").prop('disabled', false);
});
input[type=checkbox] {
  transform: scale(1.5);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1> Disabled checkboxes once checked</h1>
<form name="form1" id="form1">
<label for="ch1">Checkbox1:</label>
<input type="checkbox" name="checkbox1" id="ch1">
<br><br>
<label for="ch2">Checkbox2</label>
<input type="checkbox" name="checkbox2" id="ch2">
<br><br>
<input type="reset" name="resform1" id="resetf1">
</form>
<form name="form2" id="form2">
<h1> Checkboxes disabled if either is selected</h1>
<label for="ch3">Checkbox3:</label>
<input type="checkbox" name="checkbox3" id="ch3">
<br><br>
<label for="ch4">Checkbox4</label>
<input type="checkbox" name="checkbox4" id="ch4">
</form>
<h1> Combine Second Example with uncheck if checked and you get:</h1>
<form name="form3" id="form3">
<label for="ch5">Checkbox3:</label>
<input type="checkbox" class="checklast" name="checkbox5" id="ch5">
<br><br>

<label for="ch6">Checkbox4</label>
<input type="checkbox" class="checklast" name="checkbox6" id="ch6">
</form>