Bits & Babble

A blog in development.

Appcelerator Webview Link Click Event Listener

December 3, 2013  

The other day I was doing some mobile app development using Appcelerator’s Titanium Studio, when I ran into an issue of wanting to have links from a WebView open up in a new window. I needed an Appcelerator WebView link click event listener, but there is currently no such thing. I did some googling, but the solutions seemed excessive. Many required loading jQuery, or looping through the DOM after the page had loaded.

In my specific scenario, I have HTML content which is a small part of an object, not part of a full-blown HTML page. I didn’t need to worry about needing access to the page after the document had loaded. I also know the rules for the HTML content in question. I could work with the existing object’s HTML before giving it to the WebView.

Faking an Appcelerator WebView Link Click Event Listener

Since there is no event listener just for link clicks, we need to fake one. Given that my requirements are self-contained HTML, it’s a pretty simple search and replace task. If you’re doing this with HTML from an unknown source, your results may not be as useful. I’ll explain more later. First, to the code!

Below is an  app.js file you can dump into a new Titanium project to see the approach in action. The bulk of it is setup. We create some usable HTML, a WebView, and a Window. The guts start on line 17.

app.js
raw download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
var html = 'Lorem ipsum <a href="http://bitsandbabble.com/">dolor</a> sit amet, consectetur <a href="http://studio27indy.com/">adipisicing</a> elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.';
 
var web1 = Ti.UI.createWebView( {
	backgroundColor: '#fff',
	top: '20dp',
	bottom: '20dp',
	left: '20dp',
	right: '20dp',
} );
 
var win = Ti.UI.createWindow( {
	backgroundColor: '#eee'
} );
 
win.add( web1 );
 
Ti.App.addEventListener( 'webViewClick', function( e ) {
 
	var web2 = Ti.UI.createWebView( {
		backgroundColor: '#000',
		top: '20dp',
		bottom: 0,
		left: 0,
		right: 0,
		url: e.URL
	} );
 
	win.add( web2 );
 
} );
 
html = html.replace( /<a /gi, '<a onClick="Ti.App.fireEvent( \'webViewClick\', { URL: this.href } ); return false;" ' );
 
html = '<html><body>' + html + '</body></html>';
 
web1.html = html;
 
win.open();

var html = 'Lorem ipsum <a href="http://bitsandbabble.com/">dolor</a> sit amet, consectetur <a href="http://studio27indy.com/">adipisicing</a> elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'; var web1 = Ti.UI.createWebView( { backgroundColor: '#fff', top: '20dp', bottom: '20dp', left: '20dp', right: '20dp', } ); var win = Ti.UI.createWindow( { backgroundColor: '#eee' } ); win.add( web1 ); Ti.App.addEventListener( 'webViewClick', function( e ) { var web2 = Ti.UI.createWebView( { backgroundColor: '#000', top: '20dp', bottom: 0, left: 0, right: 0, url: e.URL } ); win.add( web2 ); } ); html = html.replace( /<a /gi, '<a onClick="Ti.App.fireEvent( \'webViewClick\', { URL: this.href } ); return false;" ' ); html = '<html><body>' + html + '</body></html>'; web1.html = html; win.open();

The idea is to fire an application level event any time a link is clicked. We accomplish this by the replace done on line 32. We’re just doing a regex match on any links, and using some JavaScript to fire a Titanium event. The important parts of this are passing along the href of the link, and returning false to prevent the current WebView from loading the new page. I did run into a slight snag when testing this approach. When setting the WebView.html property, you have to give it a complete document for any JavaScript to be executed. I simply wrapped the HTML content in minimal tags (see line 34).

We setup our event listener on line 17. In the example, it simply loads a new WebView in the current window. Since you have the URL from the fired event, you can do virtually anything you want here. In my app, the initial HTML content is contained in a small area of the UI. So when the user clicks a link, I save the current window state, and open up a new window with a full screen WebView.

This approach is by no meals a foolproof solution. It works for limited cases where you know the type of content of the incoming HTML. If you’re unsure of the type of content, it would be best to try another approach, adding exceptions for links to other parts of the current page, etc.

If you’re in control of the HTML content, this is by far the easiest method I’ve seen to capture Appcelerator WebView link click events.

2 Comments

By SPENCER SOKOL
  • About
  • Twitter
  • Studio 27

Categories

  • Alloy
  • Android
  • Appcelerator Titanium
  • Babble
  • Debugging
  • Genesis
  • iOS
  • s2Member
  • Woocommerce
  • Wordpress

About Spencer Sokol

Spencer co-founded Studio 27, a small web and application design and development company in Indianapolis. He has spent many years in both the development and testing side of the software industry, and generally avoids talking to people face to face.

Comments

  1. Patrick Mounteney says

    March 11, 2016 at 3:20 am

    Brilliant Spencer, thanks for this. I’d previously use JQuery to loop through and add click events, which means loading JQuery and is messy. This is a lot neater!

    Reply
  2. José Luna says

    January 2, 2017 at 9:12 pm

    Nice post. Thank you !!!

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

  • About
  • Indianapolis Design & Development
Copyright © 2022 Spencer Sokol

Copyright © 2022 · Bits and Babble on Genesis Framework · WordPress · Log in