动态插入元素后,如何重新计算Materialize行内元素的宽度?
Hey there! Let's work through this problem where Materialize doesn't automatically recalculate element widths after you dynamically insert elements into a .row. First, let's recap your existing jQuery code (formatted for clarity) that handles moving the clear button inputs and their labels:
<!-- Required jQuery dependency --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!-- Materialize CSS (truncated in your original code) --> <link rel="stylesheet" href="path/to/materialize.css">
// Your existing code to wrap and move clear button elements $("input[id*='-clear_id']") .add("label[for*='-clear_id']") .wrapAll("<div class='clear-button-wrapper'/>"); $('.clear-button-wrapper').parent().after($('.clear-button-wrapper'));
The Core Issue
Materialize initializes components and calculates layout widths on page load. When you dynamically add elements to a .row, the framework doesn't detect these new elements automatically—so it doesn't update their widths or apply proper styling.
Solution: Manually Trigger Materialize Updates
After inserting elements (and running your wrap/move logic), you need to tell Materialize to reinitialize or update the relevant components. Here's how to do it:
1. Update Text Fields (For Input Elements)
If your dynamic elements are text inputs (like the clear buttons you're handling), use Materialize's built-in M.updateTextFields() method. This recalculates label positions and input widths:
// Run your existing element manipulation code first $("input[id*='-clear_id']") .add("label[for*='-clear_id']") .wrapAll("<div class='clear-button-wrapper'/>"); $('.clear-button-wrapper').parent().after($('.clear-button-wrapper')); // Trigger Materialize to update text fields M.updateTextFields();
2. Targeted Initialization (For Newly Added Components)
If you're adding more complex components (like selects, date pickers, or custom elements), initialize only the new elements to avoid reinitializing existing ones:
// After inserting dynamic elements and running your wrap logic $('.row').find('.input-field:not(.initialized)').each(function() { // Initialize the Materialize TextField component for each new input M.TextField.init(this); // Mark as initialized to prevent duplicate init $(this).addClass('initialized'); });
3. Improve Your Wrap/Move Logic (Optional)
Your current batch wrap might cause issues if there are multiple clear button pairs. To handle each pair individually (safer for dynamic content), use .each():
$("input[id*='-clear_id']").each(function() { const $clearInput = $(this); const $matchingLabel = $(`label[for="${$clearInput.attr('id')}"]`); // Wrap the input and its label together $clearInput.add($matchingLabel).wrapAll("<div class='clear-button-wrapper'/>"); // Move the wrapper after its original parent $clearInput.closest('.clear-button-wrapper').parent().after($clearInput.closest('.clear-button-wrapper')); }); // Don't forget to trigger the Materialize update after this! M.updateTextFields();
Why This Works
By calling these update/init methods, you're telling Materialize to scan the DOM again for new elements, calculate their proper widths based on the .row and .col structure, and apply all the necessary styling and component behavior.
内容的提问来源于stack exchange,提问作者Kurt Peek

