让OpenLayers的SelectFeature控件支持鼠标右键事件
如何让OpenLayers的SelectFeature控件支持鼠标右键事件,这篇文章说得比较清楚了。
http://www.cnblogs.com/lei3389/archive/2009/04/21/1440458.html
但是他是直接对OpenLayers底层进行修改,而且版本是2.7的。我依据最新稳定版2.10,对涉及的相关对象进行了修改,相对于原文增加了提供当前鼠标位置参数。
下列代码放在OpenLayers库文件引用之后
OpenLayers.Events.prototype.BROWSER_EVENTS.push("contextmenu");
OpenLayers.Handler.Feature.prototype.EVENTMAP['contextmenu'] = {'in': 'click', 'out': 'clickout'};
OpenLayers.Handler.Feature.prototype.contextmenu = function(evt) {
return this.handle(evt) ? !this.stopClick : true;
};
OpenLayers.Handler.Feature.prototype.handle = function(evt) {
if(this.feature && !this.feature.layer) {
// feature has been destroyed
this.feature = null;
}
var type = evt.type;
var handled = false;
var previouslyIn = !!(this.feature); // previously in a feature
var click = (type == "click" || type == "dblclick" || type == "contextmenu");
this.feature = this.layer.getFeatureFromEvent(evt);
if(this.feature && !this.feature.layer) {
// feature has been destroyed
this.feature = null;
}
if(this.lastFeature && !this.lastFeature.layer) {
// last feature has been destroyed
this.lastFeature = null;
}
if(this.feature) {
var inNew = (this.feature != this.lastFeature);
if(this.geometryTypeMatches(this.feature)) {
// in to a feature
if(previouslyIn && inNew) {
// out of last feature and in to another
if(this.lastFeature) {
this.triggerCallback(type, 'out', [this.lastFeature]);
}
this.triggerCallback(type, 'in', [this.feature,type,evt.xy]);
} else if(!previouslyIn || click) {
// in feature for the first time
this.triggerCallback(type, 'in', [this.feature,type,evt.xy]);
}
this.lastFeature = this.feature;
handled = true;
} else {
// not in to a feature
if(this.lastFeature && (previouslyIn && inNew || click)) {
// out of last feature for the first time
this.triggerCallback(type, 'out', [this.lastFeature]);
}
// next time the mouse goes in a feature whose geometry type
// doesn't match we don't want to call the 'out' callback
// again, so let's set this.feature to null so that
// previouslyIn will evaluate to false the next time
// we enter handle. Yes, a bit hackish...
this.feature = null;
}
} else {
if(this.lastFeature && (previouslyIn || click)) {
this.triggerCallback(type, 'out', [this.lastFeature]);
}
}
return handled;
};
OpenLayers.Control.SelectFeature.prototype.clickFeature = function(feature,triggerType,screenPixel) {
if(!this.hover) {
var selected = (OpenLayers.Util.indexOf(
feature.layer.selectedFeatures, feature) > -1);
if(selected) {
if(this.toggleSelect()) {
this.unselect(feature);
} else if(!this.multipleSelect()) {
this.unselectAll({except: feature});
}
} else {
if(!this.multipleSelect()) {
this.unselectAll({except: feature});
}
this.select(feature,triggerType,screenPixel);
}
}
}
OpenLayers.Control.SelectFeature.prototype.select = function(feature,triggerType,screenPixel) {
var cont = this.onBeforeSelect.call(this.scope, feature);
var layer = feature.layer;
if(cont !== false) {
cont = layer.events.triggerEvent("beforefeatureselected", {
feature: feature
});
if(cont !== false) {
layer.selectedFeatures.push(feature);
this.highlight(feature);
// if the feature handler isn't involved in the feature
// selection (because the box handler is used or the
// feature is selected programatically) we fake the
// feature handler to allow unselecting on click
if(!this.handlers.feature.lastFeature) {
this.handlers.feature.lastFeature = layer.selectedFeatures[0];
}
layer.events.triggerEvent("featureselected", {
feature: feature,
//添加右键事件标识
triggerType: triggerType,
screenPixel: screenPixel
});
if(triggerType == "contextmenu"){
this.onContextMenuSelect.call(this.scope, feature, screenPixel);
} else {
this.onSelect.call(this.scope, feature);
}
}
}
}
OpenLayers.Control.SelectFeature.prototype.onContextMenuSelect = function(feature,screen){};
右键选择要素后的响应方法:
//要素右键响应方法
var contextMenuHandler = function(feature,screen){
var menu = this._menuDiv;
if(!menu){
menu = document.createElement("div");
map.viewPortDiv.appendChild(menu);
this._menuDiv = menu;
menu.style.position = "absolute";
menu.style.background = "white";
menu.style.border = "1px solid gray";
menu.style.padding = "5px";
menu.style.zIndex = this.map.Z_INDEX_BASE['Control'] +
this.map.controls.length;
}
menu.innerHTML = feature.id;
menu.style.left = screen.x + "px";
menu.style.top = screen.y + "px";
};
控件的定义示例:
select: new OpenLayers.Control.SelectFeature(
vectors,
{
clickout: false, toggle: false,
multiple: false, hover: false,
toggleKey: "ctrlKey", // ctrl key removes from selection
multipleKey: "shiftKey", // shift key adds to selection
box: true,
//指定右键响应方法
onContextMenuSelect: contextMenuHandler
}
),
这里的右键菜单只是写了一个最简陋的形式,真正要达到实用标准需要单独封装一个独立的上下文菜单控件,供这个右键选择要素功能调用。以后再完善吧,先到这里。
转载自:https://blog.csdn.net/zhangjie617/article/details/6708608