0

Ideal would be a CSS solution. jquery is an option though.

There is a selection elts of jquery elements. They have just been created (let elt = $('<div ..>some content</div>')) and not yet been rendered.

What I would like to achieve, is to determine the maximum width among these elements and set it to every single one of them. The usual CSS jazz of width: n%_of_some_common_parent; or width: some_fixed_value em is not an option in my case.

Finding no CSS answer, I tried JavaScript. However, being yet unrendered, the following code fails:

let max_width = 0;
elts.each(function() { max_width = Math.max(max_width, $(this).width()); });
console.log(`Maximum width: ${max_width}`);
elts.each(function() { $(this).width(max_width); } );  // << Fail, due to width == 0px.

Yields one big 0.

What actually works, is using a timeout:

setTimeout(function()
{
    elts = $('._common_cls');
    query_common_maximum_width_and_set_it_to_all(elts);
}, 500);  // << 500ms suffice. Edit: Actually 0 does, too. See below.

Nice, jumpy, fragile solution. However, what I really want is either

  • elts.on('render', function() { i_am_called_after_all_new_elements_are_rendered(..); }) or, best,
  • CSS: .common_cls { width: calc('max_known_width_in_group')px; }

How to achieve that?

Edit - JavaScript solution.

At least in JavaScript the setTimeout approach is a valid solution. Turns out setTimeout(.., 0) is only evaluated after the current function/rendering stack has completed. This ensures that the timeout callback is triggered only after width > 0 is available. Thx to CBroe in the comments below.

Markus-Hermann
  • 789
  • 11
  • 24
  • There is no "render" event, and CSS has no way of "querying" the widths of unrelated elements. – CBroe Apr 21 '23 at 08:50
  • Can you elaborate on the "unrelated"? Are they just added in arbitrary positions all over the DOM, or what? Where does the need for a _common_ width come from then, if they are supposed to be "unrelated"? – CBroe Apr 21 '23 at 08:52
  • [Is there 'element rendered' event?](https://stackoverflow.com/q/15875128/1427878) – CBroe Apr 21 '23 at 08:57
  • CBroe: It is a Bootstrap "table". A common parent is a 'col' holding multiple rows. Within these rows is (among other things) a button. These buttons should receive as width the broadest button's width. I have a function that generates such a row. So the logic is `
    ....
    .. ..
    ..
    `
    – Markus-Hermann Apr 21 '23 at 09:03
  • Then I think you will really have to loop over them in JS and determine the maximum width. – CBroe Apr 21 '23 at 09:09
  • Yes, boiling that path down, I would need a trigger that is fired when all these elements have finished rendering. My problem is, that this is just one layout of many that I support, and I do not easily want to soften up the approach of having a function that generates such a row, returning it as a new jquery block element. – Markus-Hermann Apr 21 '23 at 09:12
  • The thread I mentioned above discusses some approaches. But I think the setTimeout/ requestAnimationFrame thing should work fine for you here already. With those, it isn't even about trying to anticipate how much time rendering the elements might take (a timeout of 0 should basically also work) - but about creating a "break" in the JavaScript execution, so that control gets handed back to the rendering engine. – CBroe Apr 21 '23 at 09:23
  • Timeout of 0? Lol! Never thought of that. But yes, it seems to trigger after "the current round of rendering has finished", which is in fact what I want. Thx. Why don't you hack that into an answer. I would accept it, giving you the praise you deserve. – Markus-Hermann Apr 21 '23 at 09:30
  • 1
    The zero-second timeout was mentioned in that answer https://stackoverflow.com/a/21043017/1427878 over there already, so I think closing this as a duplicate makes more sense here. – CBroe Apr 21 '23 at 09:32
  • Setting the width of the top-level column element to `width: fit-content;` in CSS and then `.col .row button { width: 100%; }` stretches each button to the width of the largest button in the column. – Dave B Apr 21 '23 at 09:39

0 Answers0