HTML Logo by World Wide Web Consortium (www.w3.org). Click to learn more about our commitment to accessibility and standards.

Moving forward with Composr

ocPortal has been relaunched as Composr CMS, which is now in beta. ocPortal 9 will be superseded by Composr 10.

Head over to compo.sr for our new site, and to our migration roadmap. Existing ocPortal member accounts have been mirrored.


Change to ocPortal Javascript

Change to ocPortal Javascript In the next patch release for ocPortal 6 there's going to be some slight Javascript changes.

Situation X

It is worth noting that ocPortal's setInnerHTML does run Javascript, whilst setting the normal Javascript .innerHTML property (the non-standard one that Microsoft invented, but all browsers support) does not. There is no change, ocPortal has done this for some time and it is very useful, so that we can code ocPortal in a modular way and the programmer does not need to worry about behavioural differences between their DHTML components running directly in the HTML file and being embedded after an AJAX call. Originally setInnerHTML was devised for us to support XHTML properly (setting .innerHTML is not XHTML-compatible) but it has other advantages.

This behaviour is now documented so if it breaks at any point we know it is a bug.

Situation 1

Here is some example code, of a convoluted situation…

Code

<div id="test"></div>

<script type="text/javascript">// <![CDATA[
   window.setTimeout(function() {
      var script='<script>addEventListenerAbstract(window,\'load\',function () { window.alert(\'passes\'); } );<'+'/script>';
      setInnerHTML(document.getElementById('test'),script);
   } , 1000);
//]]></script>

What it does is after 1000 milliseconds, it adds a script tag to the div.
In previous versions of ocPortal the alert would not always show because the alert is embedded in a 'load' event, but the page has already loaded. Now ocPortal will detect this situation and run it immediately.
This is useful because AJAX might load up ocPortal templates (particularly pieces of Comcode, like the carousel) that were correctly designed to use onload events like this to ensure they don't trip up by running too early before the DOM is ready.

Situation 2

You're supposed to not run any inline Javascript in a component that depends on the DOM being ready (i.e. that references DOM elements in your template) without wrapping in an onload check (as discussed above).

Bad example:

Code

<div id="test"></div>

<script type="text/javascript">// <![CDATA[
document.getElementById('test').appendChild(document.createElement('img'));
//]]></script>
Good example:

Code

<div id="test"></div>

<script type="text/javascript">// <![CDATA[
addEventListenerAbstract(window,'load',function () {
   document.getElementById('test').appendChild(document.createElement('img'));
} );
//]]></script>

However in reality people modifying ocPortal will often do the bad example because it statistically rarely fails and is more natural to write, and lots of code examples out there do it. However if you did this in something that then went through setInnerHTML then in ocPortal it would definitely run before the DOM was ready and fail. For this reason now ocPortal will defer running script code inside setInnerHTML until after it finishes.

View all

Trackbacks

There have been no trackbacks yet