2

I use a value binding (<dot:HtmlLiteral Html="{value: BannerHTML}" class="mainBanner"/>) to generate some of my page content based on a number of variables.

I also need to run some javascript on the generated HTML to fix a few minor niggles, like matching font size for unusual scaling scenarios and the like. As standard, I place executable javascript at the end of an HTML document.

Generated HTML in one of these scenarios:

<div class="mainBanner" data-bind="html: BannerHTML">
    <div class="mainBanner-upper">some text</div>
    <div class="mainBanner-face" id="mainTitle">some other text</div>
    <div class="mainBanner-lower">some more text</div>
</div>

JS to operate on that HTML:
(requires https://github.com/adactio/FitText.js)

window.fitText(document.getElementById("mainTitle"));

As far as I can see, the javascript executes before the HTML is generated, and javascript that is executed on the element returns Cannot read property 'xyz' of null. How do I tell it to wait? I tried both binding the javascript file to a resource, and simply writing it in with <script> tags at the end of the body element without success.

1 Answers1

0

As your problem seems to be DOM related, I can propose you two approches.

  1. Your javascript must check and wait for DOM. On which I strongly suggest you to read this answer to ...how to call a function when the page/DOM is ready...

  2. Add your script dynamically after your data is binded (I'm not really sure about this)

Good luck.

EDIT

So I went and took a look to the dotvvm documentation to look for events calls and noticed something interesting :

Every DotVVM page includes Dotvvm.js which defines dotvvm in the global scope. This object can be used to access viewmodel and react to various page events.

This allows you to access specifics events fired by DOTVVM, you only have to find the one you need in your case. I provided you with an example below.

You could try something like this (the event may no be the one you need) :

<script>
    //By subscribing to the event, your code will only be executed 
    // if "init" event is fired by dotvvvm
    dotvvm.events.init.subscribe(()=>{ 
        window.fitText(document.getElementById("mainTitle"));  
        //basically enclose the content of your script tag with this.
    });
</script>

Please do read the documentation as I may have omitted something ? DOTVVM Javascript Events

CrazyYoshi
  • 1,003
  • 1
  • 8
  • 19
  • The first example in that answer demonstrates placing executable JS in the page *after* any HTML. That's my standard approach - which indicates to me that DotVVM is doing something *after* the DOM is loaded using KnockoutJS. I think what I need to do is listen for a certain call to be made, then execute my JS afterwards. My problem now is that I don't quite know how to find calls in the first place... I'm not that familiar with JS. –  Nov 04 '20 at 17:46
  • Okay, so on my end, I'm not familiar with DotVVM or even the interpolation of JS with asp.net. I looked a bit on the DotVVM documentation and found this page : https://www.dotvvm.com/docs/tutorials/advanced-javascript-events-and-client-side-viewmodel/2.0 – CrazyYoshi Nov 04 '20 at 19:49
  • I updated my answer to try and provide you with an example using DOTVVM javascript events. – CrazyYoshi Nov 04 '20 at 20:02
  • You hit the nail on the head! I'm making a slight edit as the actual syntax is a little different, but your premise is exactly what I was looking for. Just took a while to see it. –  Nov 04 '20 at 20:06
  • Happy to read it, If you have a question don't hesitate. Happy coding :) – CrazyYoshi Nov 04 '20 at 20:07
  • Actually I can't seem to edit, so here's the working jsfiddle: https://jsfiddle.net/fyt48vp6/ –  Nov 04 '20 at 20:08
  • To make sure the – Tomáš Herceg Nov 05 '20 at 12:35