[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