03/03/2011

Using SWFLoader and tracking click events

 

Today I was asked to look into how we could load a third party swf and track when a user clicks on the swf. Tracking user clicks is an important part of web marketing and analytics, which is the field my company specialise in.

So in order to do this I created a small Flex application that uses the SWFLoader component to load the external swf. I had thought that there would be a onClick event, which the SWFLoader fires if clicked upon, unfortunately it doesn't.

This is what I came up with:

<?xml version="1.0" encoding="utf-8"?>
<s:Application name="SWFLoaderWrapper"
               xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               width="300"
               height="250"
               backgroundColor="0xFFFFFF"
               creationComplete="application1_creationCompleteHandler(event)">
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
   
    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import mx.controls.Button;
            import mx.events.FlexEvent;
            import mx.managers.SystemManager;
        
            protected function application1_creationCompleteHandler(event:FlexEvent):void
            {
                // TODO Auto-generated method stub
                swfLoader.autoLoad = true;
                swfLoader.height = 250;
                swfLoader.width = 300;
            }

            public function onSWFLoadComplete():void {
                Alert.show("onSWFLoadComplete");
                swfLoader.addEventListener(MouseEvent.CLICK, onClick);
            }

            private function onClick(event:MouseEvent):void
            {
                trace("clicked");
                Alert.show("clicked");
            }
      ]]>
    </fx:Script>
   
    <mx:SWFLoader id="swfLoader"
                  source="../assets/externalSWF.swf"
                  complete="onSWFLoadComplete()">
       
    </mx:SWFLoader>
</s:Application>

Its a simple Flex application that starts the SWFLoader, then fires a onSWFLoadComplete when the source swf has loaded. In this complete handler I'm attaching a event listener to listen for click events.
If a click event is fired then my onClick handler is called, which shows a Alert.

This is all fine, but a couple of things I learnt doing this, first the onComplete handler is not called if the external swf is loaded by embedding the SWF, using this syntax @Embed(source='externalSWF.swf').

The reason that the complete handler isn't called when embedding like this, I found out, is because it 'isn't an external asychronous load' (this is according to Alex Harui in a response to a FlexCoders post ).

When the external SWF is loaded as I have in this example the complete handler is called.

The next issue I found was that if the external SWF has a click event, for example it loads a new webpage when a user clicks on the swf. The onClick event of the SWFLoader is not called instead the external SWF takes over and fires its own click event.

I was able to fire MouseEvent.MOUSE_DOWN, MOUSE_UP, MOUSE_OUT events, but I'm sure if the external swf uses these events it would over these too.

So another option we decided to use to overcome this proble was to use JavaScript and capture click events from the loading DIV layer in the HTML, which loads the external SWF.

I think SWFLoader is a great component, but not for all occasions.

No comments: