# Waiting for DOM nodes to render [closed]

aUser
113 4

Hello,

i have a script in my .zul page like this:

function test(wgt) {
zk.afterMount(function() {
$(wgt.$n()).children(":first").zoomable();
});
});
}


and a imageMap that calls this function:

<imagemap  content="@load(vm.content)" children="@load(vm.children) template('childrenArea')"
w:onBind="test(this)" >
<template name="childrenArea" var="item">
</template>
</imagemap>


When i load the page though, sometimes the imageMap is not completely loaded, so the 3rd part script zoomable.js processes an image that has height = 0 and width = 0 (which i guess it means that the image is not loaded yet, right?)

As a proof, if i come back on a page that was not rendered before, it might be rendered this time

Is it possible that DOM nodes are still not loaded after zk.afterMount()?

Please notice that the test function is called from the attribute w:onBind, as suggested in this thread which should imply that the DOM node that represents the imagemap is already loaded..

delete retag edit

### The question has been closed for the following reason "the question is answered, right answer was accepted"by cor3000 close date 2021-01-14 12:01:45

Sort by » oldest newest most voted

cor3000
5673 2 7

(previous post)

yes that would explain your problems, a width with just a number without a unit can't be evaluated by a browser.

Also that's why we ask for runnable examples, this would have been easy to spot in a runnable case.

So yes you only need to append the unit "px" to the end, I wonder what's stopping you from doing so?

In case you didn't find the documentation on how to concatenate strings in an EL expression, here an example:

width="@load((vm.content.width += 'px'))" height="@load((vm.content.height += 'px'))"

My updated runnable example: https://zkfiddle.org/sample/2oc8s5v/4-initial-image-width-height

cor3000
5673 2 7

You're using w:onBind="test(this) which is already called after the DOM nodes are ready, so that's not the problem ... an additional wait for zk.afterMount is unnecessary. You can easily verify that by placing a breakpoint into your test(function) and when it stops inspect the DOM... all the DOM nodes will be there already.

The problem is more likely that the image content hasn't loaded yet - and the browser needs the image content in order to determine the width and height of a node. So in case you know the dimensions of your image in advance (which I assume, since you also have image map coords) simply set the width and height explicitly.

<imagemap width="@init(vm.yourWidth)" height="@init(vm.yourHeight)" content="@load(vm.content)" children="@load(vm.children) template('childrenArea')"
w:onBind="test(this)" >


That's the easiest way to give the browser a way to define the width/height, before loading the actual image data.

If you don't know the image width/height before rendering you'll have to wait for the image content to be loaded before initializing your script. For this you can use the preload image feature in combination with w:onAfterSize (which is called after the image content is loaded and the resulting image node size is determined by the browser)

Here an example demonstrating this, note if you toggle preload image to false the image size will be 0;

cor3000
5673 2 7

thanks for the additional info this will help to focus more on what you can do.

Since you know the width and height, we don't need to wait at all. We can continue using w:onBind - NO NEED for afterMount or even document ready. Please don't making your code more complicated than necessary.

However it seems we are still seeing different results:

When I set a width and height (as in this updated example on zkfiddle) ...

<window>
<imagemap width="500px" height="300px" src="IMAGE_URL">
</imagemap>
</window>


... the width and height are applied both to the surrounding <span> and the <img> element, immediately and are available in onBind even before the full image is loaded.

<span id="d36Q2" style="width:500px;height:300px;" class="z-imagemap">
<img id="d36Q2-real" src="IMAGE_URL"
style="width:500px;height:300px;" ismap="ismap">
<map name="d36Q2-map" id="d36Q2-map"></map>
</span>


Do you see a different result? If so PLEASE provide runnable code illustrating your problem. Feel free to adjust the zkfiddle I povided.

aUser
113 4

Yes, i know the width and height of the image, but setting the width and height properties of the imagemap component will result in applying those properties to a span which is wrapping the real content (the actual img ).. The only way to set the width and height of the real img component is by using javascript code?

The reason i'm using .children(":first").zoomable(..) is to reference the real img and not the span wrapping it.

I tried the w:onAfterSize method where i call the script (is it safe to assume that DOM is already loaded here and therefore there is no need to make a call to zk.afterMount(){} or even \$(document).ready(){} functions?) and 99% of the cases it works fine, but i found some random cases where the height and width of the img are still set to 0.

I also tried the renderdefer=1000 but didn't seem to have an impact in this case..

trying random things without reading/understanding the features won't help ... especially renderdefer has a different purpose, it will add the dom nodes later so it's the opposite of what you want.

( 2021-01-12 15:58:41 +0800 )edit

aUser
113 4

This is what i noticed..

So if i set width and height with an actual value like say 1500px it works fine.. But until now i used to load both width and height from the content like this:

<imagemap id="imageIMaps" content="@load(vm.content)"
w:onBind="initZoomable(this.getImageNode());"


From Chrome's developer tool i can see that the span wrapping the real img has width and height value set to (for example) 1500 and 1400 like this:

element.style {
width: 1500;
height: 1400;
}


giving me the warning invalid property value for both width and height. That is because it is missing px at the end of the values, and in fact if i modify it like this:

element.style {
width: 1500px;
height: 1400px;
}


i get no more warnings.

Of course setting width="1500px" height="1400px" on the imagemap component inside the zul page works just fine and i noticed that i can see all images.. But i need to use the width and height of the content since width and height can change for every image. It looks like i only need to append px at the end of

width="@load(vm.content.width)" height="@load(vm.content.height)"


Does this make sense?

aUser
113 4

Sorry for not uploading runnable code, i'll try to do it next time

Yes, i was searching for that, now images appear with no exceptions so far.

Thank you

( 2021-01-14 12:01:30 +0800 )edit