I’m loading html pages on iOS and want to intercept the user touching the screen anywhere that isn’t an anchor/link/button etc. and perform some action, however if the touch on a link etc. I want the action/behaviour associated with that to be performed as usual.
In order to intercept the touches I am executing the following script:
var script = document.createElement('script');
script.type = 'text/javascript';
script.text = window.onload = function addListener() {
alert('adding listener');
function init() {
document.documentElement.addEventListener("touchstart", function (e)
{
if (['A', 'BUTTON', 'AREA'].indexOf(e.target.tagName) === -1)
{
e.preventDefault();
e.stopPropagation();
invokeObjectiveC("ontouchstart:");
}
}, false);
}
if (document.readyState === "complete") {
init();
} else {
document.addEventListener('DOMContentLoaded', init, false);
}
}
function invokeObjectiveC(action) {
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", action);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
}
document.getElementsByTagName('head')[0].appendChild(script);
This works up to a point, InvokeObjectiveC() is being called when I want it to, but if the html contains a section such as this:
<div id="B145" class="abutton w80xh42" >
<map name="B145_map" id="B145_map" >
<area shape="rect" coords="0,0,80,42" href="XYZ:Action_Test45id" alt="" />
</map>
<img id="B145_img" src="transparent_80x42.png" usemap="B145_map" alt="" />
</div>
then when the button is touched nothing happens – but it would if my script wasn’t executed. So my script code is interfering with the normal behaviour if the user clicks on a button or link etc. How can I get my script to intercept if the user touches somewhere which isn’t a button/link etc. but not affect other things when the user touches/clicks a button/link etc.?
I used delegation in this example: http://jsfiddle.net/DdcJJ/6/ to achieve the result, using the YUI JavaScript library. Pretty easy stuff, you’ll see when you click the AREA element that a JavaScript is run, from that element’s href value.
I did try to use YUI’s selector utility to make all elements except the AREA tag a delegation target, which is maybe cleaner but as you can see here: http://jsfiddle.net/tAt4m/1/ we capture both the delegation event (because MAP wraps AREA) and the default event.
I guess you could achieve the same result without a JavaScript library, but there’s a proof of concept to work with anyhow!