[OpenLayers-Dev] feature events

Tim Schaub tschaub at opengeo.org
Fri Oct 16 20:46:34 EDT 2009


Hey-

We've wrestled for some time with browser events being blocked by 
svg/vml elements.  This originally meant that you could only use a 
select feature control with one layer at a time.  Andreas contributed a 
nice solution for selecting features on multiple layers for the last 
release.

I got a number of things wrong in the select feature control (layer gets 
selectedFeatures array [ack] and control maintains it [ug], control has 
select method but layer doesn't, you can't easily deal with 
feature/mouse interaction without getting all the select feature control 
behavior, etc.)  I've long wanted to just have vector layers trigger 
feature related events.

I put together what seems like a potential solution:
http://dev.openlayers.org/sandbox/tschaub/select/examples/feature-events.html

This introduces a "FeatureAgent" constructor.  If a map has the 
"featureEvents" property set to true, it gets a feature agent that 
manages feature related events (from click and mousemove).  This gives 
us featureclick, nofeatureclick, featureover, and featureout event on 
vector layers.

As described in the example, these events are fired for visible vector 
layers.  The over/out events are similar to mouseover/mouseout for other 
doc elements - except that all features on all layers are essentially 
treated as if they share the same z-index.  This means you get over/out 
for every feature on every layer as you pass over and out.  Similarly, 
the featureclick event "drills" through all features on all layers.  You 
get the event once for each of multiple overlapping features on a single 
layer or the same on multiple layers.  Listeners are triggered for 
features in reverse draw order (top first).  Any listener can return 
false to stop remaining listeners from getting called.

The whole thing relies on document.elementFromPoint [1].  This is a 
handy method that accounts for the currently computed style of all 
elements.  The trick is to set the display style to none for each target 
and call the method again, until all targets on all layers have been 
accounted for.  All this happens in a single browser event listener 
sequence.  Since style display is getting set and reset for all targets 
during the same sequence, we don't trigger a reflow with each display 
change.  It appears that there also isn't a reflow at the end of the 
listener sequence either (though I need some heavier examples to test with).

I've played with the example on Firefox 3.5 and IE 6.  Haven't tested 
other browsers yet.

There are a number of ways this could be implemented:

a) As a control.  Traditional, but we don't need the dom element or 
events object - and this may be a more awkward way in practice.

b) As it is now.  The agent is added/activated if a map property is set. 
  Could also be added/activated after map construction.

c) Crammed into Map.js.  I'd rather not do this.

d) Other (handler, plugin, more).

Thanks for any feedback.
Tim

[1] https://developer.mozilla.org/en/DOM/document.elementFromPoint

-- 
Tim Schaub
OpenGeo - http://opengeo.org
Expert service straight from the developers.



More information about the Dev mailing list