WebHTMLViewer, Javascript: Server generated event

I am stuck trying to have some text fade down in a WebHTMLviewer. I am successful having the text fade up using JS:
$(document).ready(function (){
$( ‘#title’ ).hide().fadeIn( 1000 ); //This fades the text up in div element ‘title’ when document is ready.

Trying to get it to fade down, the beforeunload event does not wait for the .fadeOut animation to complete. After trying many approaches, I am now trying to have the server simulate a user mouse click in order to trigger the fade-down. (The fade-down does execute when i actually click, and I’d love to find another approach).

The fundamental problem seems to be about scope: I cannot use (Xojo) control.ExecuteJavascript("$( ‘#title’ ).fadeOut( 1000 );") to directly address the element named ‘title’ (because of session scope?) nor does control.ExecuteJavascript… to change a (client side) document or window property which is being “watched” by a JS loop in the original HTML. I can change the property’s value, but the script (which i can see is running in the console.log) does not see the variable change.

That is apparently because JS is single-threaded…? My code in .ExecuteJavascript (called from a Session) is reaching the browser, but cannot reference objects already loaded and running in the HTMLviewer.

Nor can i figure out how to use a WebSessionContext class to ‘point’ my .ExecuteJavascript to the right scope, if this is indeed a scope problem.

You can’t simulate a click on a web page. The browsers use them to determine if something was initiated by a user, for security reasons.

If I’m reading your questions correctly, and your problem is that you are trying to fade some text that is inside of a WebHtmlViewer, a WebSessionContext won’t help you. What you need access to is the Document Object Model (DOM) of the contents of the WebHTMLViewer, and you need to execute your JavaScript on that.

It would be helpful to know what it is you are trying to accomplish though. I know you want some text to fade out, but is it: user clicks, text fades and then Page Close, that you want? If it’s something else, please list the items and the sequence you are looking for.

That really is the whole sequence: The user’s experience is entirely passive, watching text fade up and down. So there is no actual user input. I have found lots of Javascript discussion of creating an eventObject, initializing it as a mouse click and passing that to simulate an event, but that’s beside the point. It also makes sense from a security standpoint that the server cannot block the document unload in the beforeunload event.

As i said, the .ExecuteJavascript code does seem to be reaching the browser, but references to existing objects are coming up undefined. When you say “you need to access the DOM of the contents of the WebHTMLViewer…” my code is attempting to do just that, but
document.getElementById(‘title’).fadeOut( 1000 );


$( ‘#title’ ).fadeOut( 1000 );

The error is undefined element.

And if I have a script running which watches a property: document.fadedown, I can watch the script run, but when the server sends .ExecuteJavascript(“document.fadeout = 1000;”) the running script does not see the property change. You put your finger on the problem: it’s probably a simple thing to correctly address the current DOM, I just don’t know how to do it…

Ok, so the problem still is that the javascript commands that you are sending are going to the DOM of the Xojo app, not the DOM that is inside of the WebHTMLViewer. You see, the underlying mechanism contains an entire html document, and it’s own distinct DOM.

May I ask why you are using he HTMLViewer? Do you actually need an entire web page or are you just using it to show an HTML fragment?

In this case all I need is a single div. for two lines of text. This will be a very simple app that displays opera supertitles “live” in performance. Generally it (the two lines of text) will be the only large sized text on the screen, running full screen when the user chooses. Timing is important, and i don’t know the “duration” (i.e. how long text will be on screen) in advance. I will need this for other passive things like digital signage that i want to run in a browser in full screen mode, again with no user input.

I was dimly aware of the AJAX activity in a Xojo web app. I’ve captured and looked at a little of Xojo’s code in the browser. I guess I need to look there for clues on how to address my HTML structure, as you explained. Thanks!

And as to why an HTMLviewer: I need to display styled text, and HTML is a reliable way of doing styled text. The fade-up part was so easy, I was fooled into thinking the fade-down (as a push) would be fast n’ easy.
I did see a thread that talked about using the WebSDK to create a custom control, much like the HTMLviewer in the SDK example, and I spent some time trying to make that work…

If you look in the docs for the WebSDK, the getting started app is all about creating a simple html control. I suspect that will fit your needs quite nicely. It’s in the Extras folder next to the IDE.

I did spend some time with that, but wasn’t able to make it work. That’s where i’ll pick up again. Thanks!

—OK— I am now using a custom control taken straight from the WebSDK example HTMLViewer. With this approach, instead of HTMLview.LoadPage(someHTML) I have to set the object’s HTML property, which in turn sets the inner HTML of the object.
However, I can’t (apparently) include a tag in that HTML since it is inside the body and the div. So I do not see where I can inject my javascript to execute the fade-up when the document is ready.

…and you know I’ll be back to ask about adding my custom fadedown event, which is where I got stuck on my first crack at this.

–continued: The control’s setupJavascriptFramework event looked promising, but returning my JS there again gives the error that $(‘title’) element is undefined, same as .getElementById(‘title’).

SetupJavascriptFramework is for delivering functions to the browser that you will execute later. You must still wait until the Shown event fires to access the item in the DOM.

I didn’t need to make a custom control after all. The clue to addressing the element I had created in my WebHTMLViewer did come from the WebSDK though: In the WebSDK HTMLviewer example, the html is prepared by adding a div tag with the control’s ID (WebHTMLViewer.ControlID). Xojo uses .ControlID to create unique div tags in the destination web pages.

So, when I call WebHTMLViewer.LoadPage, I build an HTML string that looks like this:

<html><body><div id="******">+MyHTML+</div>
<script language="javascript">
$(document).ready(function (){
$( '#******' ).hide().fadeIn( 1000 );  //This fades the text up in my div when document is ready.

I replace the string of asterisks with the control’s ID at the session level, just before LoadPage(). Then later I can address the HTML element to fade down using

ExecuteJavascript("$('#"+self.MyWebPage.HTMLViewer1.ControlID+"').fadeOut( 1000 );")

(also at the session level, which ‘self’ refers to there)

I thought there should be a simple solution to my problem, and that is to use .ControlID to address an existing element with JavaScript.