Клик правой кнопки
Здравствуйте. Немного получается показать всплывающее меню с 1 раза, когда щелкаешь правой кнопкой на feature. Подскажите пожалуйста.
<!DOCTYPE html> <html lang='en'> <head> <meta charset='utf-8' /> <title>map</title> <script type='text/javascript' src='../lib/OpenLayers.js'></script> <script src="jquery.js"></script> <script src="jquery.contextmenu.js"></script> <link rel="stylesheet" href="jquery.contextmenu.css"> <script type='text/javascript'> var map; var vectorLayer; $(function() { $('#mythingy').contextPopup({ title: 'My Popup Menu', items: [ {label:'Some Item', icon:'icons/shopping-basket.png', action:function() { alert('clicked 1') } }, {label:'Another Thing', icon:'icons/receipt-text.png', action:function() { alert('clicked 2') } }, {label:'Blah Blah', icon:'icons/book-open-list.png', action:function() { alert('clicked 3') } }, null, // divider {label:'Sheep', icon:'icons/application-monitor.png', action:function() { alert('clicked 4') } }, {label:'Cheese', icon:'icons/bin-metal.png', action:function() { alert('clicked 5') } }, {label:'Bacon', icon:'icons/magnifier-zoom-actual-equal.png', action:function() { alert('clicked 6') } }, null, // divider {label:'Onwards', icon:'icons/application-table.png', action:function() { alert('clicked 7') } }, {label:'Flutters', icon:'icons/cassette.png', action:function() { alert('clicked 8') } } ] }); }); function DoYearReport(k) { } function init() { map = new OpenLayers.Map('map_element', {}); var wms = new OpenLayers.Layer.WMS( 'OpenLayers WMS', 'http://vmap0.tiles.osgeo.org/wms/vmap0', {layers: 'basic'}, {} ); map.addLayer(wms); // allow testing of specific renderers via "?renderer=Canvas", etc var renderer = OpenLayers.Util.getParameters(window.location.href).renderer; renderer = (renderer) ? [renderer] : OpenLayers.Layer.Vector.prototype.renderers; var vectorLayer = new OpenLayers.Layer.Vector("Simple Geometry", { styleMap: new OpenLayers.StyleMap({'default':{ strokeColor: "#00FF00", strokeOpacity: 1, strokeWidth: 3, fillColor: "#FF5500", fillOpacity: 0.5, pointRadius: 6, pointerEvents: "visiblePainted", // label with \n linebreaks label : "name: ${name}\n\nage: ${age}", fontColor: "${favColor}", fontSize: "12px", fontFamily: "Courier New, monospace", fontWeight: "bold", labelAlign: "${align}", labelXOffset: "${xOffset}", labelYOffset: "${yOffset}", labelOutlineColor: "white", labelOutlineWidth: 3 }}), renderers: renderer }); // Create a point feature to show the label offset options var labelOffsetPoint = new OpenLayers.Geometry.Point(-101.04, 35.68); var labelOffsetFeature = new OpenLayers.Feature.Vector(labelOffsetPoint); labelOffsetFeature.attributes = { name: "offset", age: 22, favColor: 'blue', align: "cm", // positive value moves the label to the right xOffset: 50, // negative value moves the label down yOffset: -15 }; // create a point feature var point = new OpenLayers.Geometry.Point(-111.04, 45.68); var pointFeature = new OpenLayers.Feature.Vector(point); pointFeature.attributes = { name: "toto", age: 20, favColor: 'red', align: "cm" }; var nullFeature = new OpenLayers.Feature.Vector(null); nullFeature.attributes = { name: "toto is some text about the world", age: 20, favColor: 'red', align: "cm" }; map.addLayer(vectorLayer); map.setCenter(new OpenLayers.LonLat(-109.370078125, 43.39484375), 4); vectorLayer.addFeatures([pointFeature, labelOffsetFeature, nullFeature ]); if(!map.getCenter()) { map.zoomToMaxExtent(); } // Get control of the right-click event: document.getElementById('map_element').oncontextmenu = function(e) { e = e?e:window.event; if (e.preventDefault) e.preventDefault(); // For non-IE browsers. else return false; // For IE browsers. }; // A control class for capturing click events... OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, { defaultHandlerOptions: { 'single': true, 'double': true, 'pixelTolerance': 0, 'stopSingle': false, 'stopDouble': false }, handleRightClicks:true, initialize: function(options) { this.handlerOptions = OpenLayers.Util.extend( {}, this.defaultHandlerOptions ); OpenLayers.Control.prototype.initialize.apply( this, arguments ); this.handler = new OpenLayers.Handler.Click( this, this.eventMethods, this.handlerOptions ); }, CLASS_NAME: "OpenLayers.Control.Click" }); // Add an instance of the Click control that listens to various click events: var oClick = new OpenLayers.Control.Click({eventMethods:{ 'rightclick': function(e) { var po = vectorLayer.getFeatureFromEvent(e); if (po) { var lonlat = map.getLonLatFromViewPortPx(e.xy); if (lonlat) { var temp = document.getElementById("mythingy"); if (temp) { temp.style.left = (e.x-5)+'px'; temp.style.top = (e.y-5)+'px'; } //не хочет с 1 раза показывать меню $('#mythingy').trigger({ type: 'mousedown', which: 3 }).trigger({ type: 'mouseup', which: 3 }); } } }, 'click': function(e) { console.log('click at '+e.xy.x+','+e.xy.y); }, 'dblclick': function(e) { console.log('dblclick at '+e.xy.x+','+e.xy.y); }, 'dblrightclick': function(e) { console.log('dblrightclick at '+e.xy.x+','+e.xy.y); } }}); map.addControl(oClick); oClick.activate(); } </script> </head> <body onload='init();'> <div id='map_element' style='width: 800px; height: 600px;'></div> <div id="mythingy" style="position:absolute;width:5px; height: 5px; margin: 0px; border:0px dashed #666666; padding:6px;z-index:999999999"> </div> </body> </html> |
diprom,
Попробуйте заменить это: var oClick = new OpenLayers.Control.Click({eventMethods:{ 'rightclick': function(e) { var po = vectorLayer.getFeatureFromEvent(e); if (po) На это: var oClick = new OpenLayers.Control.Click({eventMethods:{ 'contextmenu': function(e) { e.preventDefault(); var po = vectorLayer.getFeatureFromEvent(e); if (po) |
Так, вообще меню не всплывает
|
Вроде сделал. Нужны проверки.
<!DOCTYPE html> <html lang='en'> <head> <meta charset='utf-8' /> <title>map</title> <script type='text/javascript' src='../lib/OpenLayers.js'></script> <script src="jquery.js"></script> <script src="jquery.contextmenu.js"></script> <link rel="stylesheet" href="jquery.contextmenu.css"> <script type='text/javascript'> var map; var vectorLayer; function DoYearReport(k) { } function init() { map = new OpenLayers.Map('map_element', {}); var wms = new OpenLayers.Layer.WMS( 'OpenLayers WMS', 'http://vmap0.tiles.osgeo.org/wms/vmap0', {layers: 'basic'}, {} ); map.addLayer(wms); // allow testing of specific renderers via "?renderer=Canvas", etc var renderer = OpenLayers.Util.getParameters(window.location.href ).renderer; renderer = (renderer) ? [renderer] : OpenLayers.Layer.Vector.prototype.renderers; var vectorLayer = new OpenLayers.Layer.Vector("Simple Geometry", { styleMap: new OpenLayers.StyleMap({'default':{ strokeColor: "#00FF00", strokeOpacity: 1, strokeWidth: 3, fillColor: "#FF5500", fillOpacity: 0.5, pointRadius: 6, pointerEvents: "visiblePainted", // label with \n linebreaks label : "name: ${name}\n\nage: ${age}", fontColor: "${favColor}", fontSize: "12px", fontFamily: "Courier New, monospace", fontWeight: "bold", labelAlign: "${align}", labelXOffset: "${xOffset}", labelYOffset: "${yOffset}", labelOutlineColor: "white", labelOutlineWidth: 3 }}), renderers: renderer }); // Create a point feature to show the label offset options var labelOffsetPoint = new OpenLayers.Geometry.Point(-101.04, 35.68); var labelOffsetFeature = new OpenLayers.Feature.Vector(labelOffsetPoint); labelOffsetFeature.attributes = { name: "offset", age: 22, favColor: 'blue', align: "cm", // positive value moves the label to the right xOffset: 50, // negative value moves the label down yOffset: -15 }; // create a point feature var point = new OpenLayers.Geometry.Point(-111.04, 45.68); var pointFeature = new OpenLayers.Feature.Vector(point); pointFeature.attributes = { name: "toto", age: 20, favColor: 'red', align: "cm" }; var nullFeature = new OpenLayers.Feature.Vector(null); nullFeature.attributes = { name: "toto is some text about the world", age: 20, favColor: 'red', align: "cm" }; map.addLayer(vectorLayer); map.setCenter(new OpenLayers.LonLat(-109.370078125, 43.39484375), 4); vectorLayer.addFeatures([pointFeature, labelOffsetFeature, nullFeature ]); if(!map.getCenter()) { map.zoomToMaxExtent(); } // Get control of the right-click event: document.getElementById('map_element').oncontextme nu = function(e) { e = e?e:window.event; if (e.preventDefault) e.preventDefault(); // For non-IE browsers. else return false; // For IE browsers. }; // A control class for capturing click events... OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, { defaultHandlerOptions: { 'single': true, 'double': true, 'pixelTolerance': 0, 'stopSingle': false, 'stopDouble': false }, handleRightClicks:true, initialize: function(options) { this.handlerOptions = OpenLayers.Util.extend( {}, this.defaultHandlerOptions ); OpenLayers.Control.prototype.initialize.apply( this, arguments ); this.handler = new OpenLayers.Handler.Click( this, this.eventMethods, this.handlerOptions ); }, CLASS_NAME: "OpenLayers.Control.Click" }); // Add an instance of the Click control that listens to various click events: var oClick = new OpenLayers.Control.Click({eventMethods:{ 'rightclick': function(e) { var po = vectorLayer.getFeatureFromEvent(e); if (po) { var lonlat = map.getLonLatFromViewPortPx(e.xy); if (lonlat) { var temp = document.getElementById("mythingy"); if (temp) { temp.style.left = (e.x-5)+'px'; temp.style.top = (e.y-5)+'px'; $('#mythingy').contextPopup({ title: 'My Popup Menu', items: [ {label:'Some Item', icon:'icons/shopping-basket.png', action:function() { alert('clicked 1') } }, {label:'Another Thing', icon:'icons/receipt-text.png', action:function() { alert('clicked 2') } }, {label:'Blah Blah', icon:'icons/book-open-list.png', action:function() { alert('clicked 3') } }, null, // divider {label:'Sheep', icon:'icons/application-monitor.png', action:function() { alert('clicked 4') } }, {label:'Cheese', icon:'icons/bin-metal.png', action:function() { alert('clicked 5') } }, {label:'Bacon', icon:'icons/magnifier-zoom-actual-equal.png', action:function() { alert('clicked 6') } }, null, // divider {label:'Onwards', icon:'icons/application-table.png', action:function() { alert('clicked 7') } }, {label:'Flutters', icon:'icons/cassette.png', action:function() { alert('clicked 8') } } ], posleft:e.x, postop:e.y }); $("#mythingy").contextmenu(); } } } }, 'click': function(e) { console.log('click at '+e.xy.x+','+e.xy.y); }, 'contextmenu': function(e) { console.log('contextmenu '+e.xy.x+','+e.xy.y); }, 'dblclick': function(e) { console.log('dblclick at '+e.xy.x+','+e.xy.y); }, 'dblrightclick': function(e) { console.log('dblrightclick at '+e.xy.x+','+e.xy.y); } }}); map.addControl(oClick); oClick.activate(); } </script> </head> <body onload='init();'> <div id='map_element' style='width: 800px; height: 600px;'></div> <div id="mythingy" style="position:absolute;width:5px; height: 5px; margin: 0px; border:0px dashed #666666; padding:6px;z-index:999999999"></div> </body> </html> //jquery.contextmenu.js jQuery.fn.contextPopup = function(menuData) { var amenu = null; var bg = null; // Define default settings var settings = { contextMenuClass: 'contextMenuPlugin', linkClickerClass: 'contextMenuLink', gutterLineClass: 'gutterLine', headerClass: 'header', seperatorClass: 'divider', posleft:0, postop:0, title: '', items: [], }; // merge them $.extend(settings, menuData); // Build popup menu HTML function createMenu(e) { if (amenu) return amenu; var menu = $('<ul class="' + settings.contextMenuClass + '"><div class="' + settings.gutterLineClass + '"></div></ul>') .appendTo(document.body); if (settings.title) { $('<li class="' + settings.headerClass + '"></li>').text(settings.title).appendTo(menu); } settings.items.forEach(function(item) { if (item) { var rowCode = '<li><a href="#" class="'+settings.linkClickerClass+'"><span class="itemTitle"></span></a></li>'; // if(item.icon) // rowCode += '<img>'; // rowCode += '<span></span></a></li>'; var row = $(rowCode).appendTo(menu); if(item.icon){ var icon = $('<img>'); icon.attr('src', item.icon); icon.insertBefore(row.find('.itemTitle')); } row.find('.itemTitle').text(item.label); if (item.isEnabled != undefined && !item.isEnabled()) { row.addClass('disabled'); } else if (item.action) { row.find('.'+settings.linkClickerClass).click(func tion () { item.action(e); }); } } else { $('<li class="' + settings.seperatorClass + '"></li>').appendTo(menu); } }); menu.find('.' + settings.headerClass ).text(settings.title); return menu; } // On contextmenu event (right click) this.on('contextmenu', function(e) { if (!amenu) {amenu = createMenu(e).show(); } else return false; var left = e.pageX + 5, /* nudge to the right, so the pointer is covering the title */ top = e.pageY; if (top + amenu.height() >= $(window).height()) { top -= amenu.height(); } if (left + amenu.width() >= $(window).width()) { left -= amenu.width(); } if (settings.posleft > 0) left = settings.posleft; if (settings.postop>0) top = settings.postop; // Create and show menu amenu.css({zIndex:1000001, left:left, top:top}) .on('contextmenu', function() { return false; }); // Cover rest of page with invisible div that when clicked will cancel the popup. if (!bg) bg = $('<div></div>') .css({left:0, top:0, width:'100%', height:'100%', position:'absolute', zIndex:1000000}) .appendTo(document.body) .on('contextmenu click', function() { // If click or right click anywhere else on page: remove clean up. bg.remove(); amenu.remove(); return false; }); // When clicking on a link in menu: clean up (in addition to handlers on link already) amenu.find('a').click(function() { bg.remove(); amenu.remove(); bg = null; amenu = null; }); // Cancel event, so real browser popup doesn't appear. return false; }); return this; }; |
Баг возникает, когда щелкаешь по одной точке правой кнопкой, нажимаешь любое меню , затем правой по другой точке и возникает
2 меню. Не знаю пока, как убрать. |
Вроде так работает.
jQuery.fn.contextPopup = function(menuData) { var amenu = null; var bg = null; // Define default settings var settings = { contextMenuClass: 'contextMenuPlugin', linkClickerClass: 'contextMenuLink', gutterLineClass: 'gutterLine', headerClass: 'header', seperatorClass: 'divider', posleft:0, postop:0, title: '', items: [], }; // merge them $.extend(settings, menuData); // Build popup menu HTML function createMenu(e) { if (amenu) return amenu; var menu = $('<ul class="' + settings.contextMenuClass + '"><div class="' + settings.gutterLineClass + '"></div></ul>') .appendTo(document.body); if (settings.title) { $('<li class="' + settings.headerClass + '"></li>').text(settings.title).appendTo(menu); } settings.items.forEach(function(item) { if (item) { var rowCode = '<li><a href="#" class="'+settings.linkClickerClass+'"><span class="itemTitle"></span></a></li>'; // if(item.icon) // rowCode += '<img>'; // rowCode += '<span></span></a></li>'; var row = $(rowCode).appendTo(menu); if(item.icon){ var icon = $('<img>'); icon.attr('src', item.icon); icon.insertBefore(row.find('.itemTitle')); } row.find('.itemTitle').text(item.label); if (item.isEnabled != undefined && !item.isEnabled()) { row.addClass('disabled'); } else if (item.action) { row.find('.'+settings.linkClickerClass).click(function () { item.action(e); }); } } else { $('<li class="' + settings.seperatorClass + '"></li>').appendTo(menu); } }); menu.find('.' + settings.headerClass ).text(settings.title); return menu; } // On contextmenu event (right click) this.on('contextmenu', function(e) { if (bg) bg.remove(); if (amenu) amenu.remove(); if (!amenu) {amenu = createMenu(e).show(); } else return false; var left = e.pageX + 5, /* nudge to the right, so the pointer is covering the title */ top = e.pageY; if (top + amenu.height() >= $(window).height()) { top -= amenu.height(); } if (left + amenu.width() >= $(window).width()) { left -= amenu.width(); } if (settings.posleft > 0) left = settings.posleft; if (settings.postop>0) top = settings.postop; // Create and show menu amenu.css({zIndex:1000001, left:left, top:top}) .on('contextmenu', function() { return false; }); // Cover rest of page with invisible div that when clicked will cancel the popup. if (!bg) bg = $('<div></div>') .css({left:0, top:0, width:'100%', height:'100%', position:'absolute', zIndex:1000000}) .appendTo(document.body) .on('contextmenu click', function() { // If click or right click anywhere else on page: remove clean up. if (bg) bg.remove(); if (amenu) amenu.remove(); return false; }); // When clicking on a link in menu: clean up (in addition to handlers on link already) amenu.find('a').click(function() { bg.remove(); amenu.remove(); // bg = null; // amenu = null; } ); // Cancel event, so real browser popup doesn't appear. return false; }); return this; }; |
Часовой пояс GMT +3, время: 09:27. |