0

I have the following code which when embedded within a loaded html page works successfully:

<HEAD>
<script language="javascript" type="text/javascript">
document.addEventListener('DOMContentLoaded', function () 
{
    document.documentElement.addEventListener("touchstart", function (e) 
    {
            if (['A', 'BUTTON'].indexOf(e.target.tagName) === -1)
            {
                e.preventDefault();
                e.stopPropagation();
                invokeObjectiveC("ontouchstart:");
            }
            else
            {
                e.preventDefault();
                e.stopPropagation();
                invokeObjectiveC(e.target);
            }
    }, true);
}, false);


function invokeObjectiveC(action) {
    ...
}

However if I take it out of the html and try to load it separatly then it is not working. When loading it separately it looks like this:

alert('test');

function addListener()
{
    alert('adding listener');

    document.addEventListener('DOMContentLoaded', function () 
          {
          document.documentElement.addEventListener("touchstart", function (e) 
                        {
                        alert('touchstart');
                        if (['A', 'BUTTON'].indexOf(e.target.tagName) === -1)
                        {
                        e.preventDefault();
                        e.stopPropagation();
                        invokeObjectiveC("ontouchstart:");
                        }
                        else
                        {
                        e.preventDefault();
                        e.stopPropagation();
                        invokeObjectiveC(e.target);
                        }
                        }, true);
          }, false);


}

addListener();


function invokeObjectiveC(action) {
   ...
}

When added, a "test" and an "adding listener" alert dialog are displayed so I know this part is working. However the code then doesn't work - its supposed to detect touches (this is on iOS) in certain parts of the screen. With the code within the html everything works fine and it executes when the screen is touched, when its loaded separatly nothing happens when the screen is touched. Any ideas what the problem could be?

====== UPDATE I tried running the following during various stages of the lifecycle, including before the request to even load the page has been issued, but 'Dom content loaded' never appears:

var script = document.createElement('script');  
script.type = 'text/javascript';  
script.text = 
var Test =
{
f: function()
    {
        if (!event.originalTarget.defaultView.frameElement) 
        {
            alert('DOM content loaded');
        }
    }
}

function addTestListener()
{
    alert('adding listener');
    window.addEventListener("DOMContentLoaded", function(e) { Test.f(); }, false);
}



document.getElementsByTagName('head')[0].appendChild(script);
Gruntcakes
  • 37,738
  • 44
  • 184
  • 378
  • When you say "load it separately", what do you mean? Are you loading it manually after the DOM has loaded? If so, then the `DOMContentLoaded` event may have already fired so your handler never gets called. – jfriend00 Feb 18 '12 at 22:59
  • I'm using an iOS function called stringByEvaluatingJavaScriptFromString to execute the script. I've tried executing it before and after the page has loaded. – Gruntcakes Feb 18 '12 at 23:42

2 Answers2

1

From your comment about the iOS function, I suspect that the document is already loaded when you try to execute your javascript. If that's the case, then the DOMContentLoaded event has already happened so you code will never be initialized. You can fix that by checking to see if the document is already loaded by changing your code to this:

function addListener() {
    alert('adding listener');

    function init() {
        document.documentElement.addEventListener("touchstart", function (e) {
            alert('touchstart');
            if (['A', 'BUTTON'].indexOf(e.target.tagName) === -1) {
                e.preventDefault();
                e.stopPropagation();
                invokeObjectiveC("ims-ontouchstart:");
            } else {
                e.preventDefault();
                e.stopPropagation();
                invokeObjectiveC(e.target);
            }
        }, true);
    }

    if (document.readyState === "complete") {
        init();
    } else {
        document.addEventListener('DOMContentLoaded', init, false);
    }
}

addListener();

function invokeObjectiveC(action) {
   ...
}
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Thanks for the reply. There are several opportunities to run the javascript during various loading stages of the view housing the page and the page itself (callbacks such as viewWillLoad, webViewDidAppear, webViewDidStartLoad etc. are provided). I've tried my original code, your code, and some new code I've added as an update above at every stage possible but with no luck. – Gruntcakes Feb 19 '12 at 00:48
  • @Woofbeans - are you able to inspect any javascript errors? Are you able to set a breakpoint in your code and trace through it to see what is happening? This is perhaps a case for more advanced debugging to actually see what is happening rather than just try things. – jfriend00 Feb 19 '12 at 00:54
  • Its not possible afaik to set breakpoints, is there anything I can do using alerts to display relevant info? – Gruntcakes Feb 19 '12 at 01:14
  • @Woofbeans - sorry, but I don't know anything about the iOS environment you're in. A [google search](https://www.google.com/webhp?sourceid=chrome-instant&ix=sea&ie=UTF-8&ion=1#sclient=psy-ab&hl=en&site=webhp&source=hp&q=breakpoints%20in%20iOS%20webview&aq=&aqi=&aql=&oq=&pbx=1&fp=2d3c96065a2e28f1&ion=1&ion=1&bav=on.2,or.r_gc.r_pw.r_cp.,cf.osb&fp=2d3c96065a2e28f1&biw=1270&bih=1243&ion=1) shows some possibilities including [this one](http://stackoverflow.com/questions/2767902/what-are-some-methods-to-debug-javascript-inside-of-a-uiwebview). – jfriend00 Feb 19 '12 at 01:18
1

I changed the line

function addListener()

into

window.onload = function addListener()

and it seems to have done the trick

Gruntcakes
  • 37,738
  • 44
  • 184
  • 378