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
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.
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);
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.
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>