ArcGISDynamicMapServiceLayer地图悬停延迟Tooltip显示问题
Hey Sarah, let's tackle those tooltip problems you're having with your ArcGISDynamicMapServiceLayer! I’ve got step-by-step fixes for both the empty content and the instant pop-up issues.
1. Add Delay to Tooltip Display
The immediate pop-up happens because we’re showing the tooltip right when the mouse hovers. We’ll use a timer to add a configurable delay (e.g., 500ms) and cancel it if the mouse leaves before the delay ends.
- First, declare a timer variable outside your event handlers to track it:
let tooltipTimer; - On
mouse-over, clear any existing timer then set a new one to trigger the tooltip after the delay:map.on("mouse-over", (evt) => { // Cancel any pending tooltip display clearTimeout(tooltipTimer); // Set timer to show tooltip after 500ms tooltipTimer = setTimeout(() => { // Tooltip display logic goes here }, 500); }); - On
mouse-out, clear the timer and hide the tooltip immediately:map.on("mouse-out", () => { clearTimeout(tooltipTimer); document.getElementById("tooltip").style.display = "none"; });
2. Populate Tooltip with Attribute Data (State Name)
Unlike FeatureLayer, ArcGISDynamicMapServiceLayer doesn’t let you access feature attributes directly. We’ll use the IdentifyTask to fetch the state name from the service when the user hovers over a feature.
Step 2.1: Set Up IdentifyTask
Initialize the task with your dynamic layer URL and configure parameters to target your state layer:
const identifyTask = new IdentifyTask("YOUR_DYNAMIC_SERVICE_URL"); const identifyParams = new IdentifyParameters(); identifyParams.tolerance = 3; // Small tolerance for precise selection identifyParams.returnGeometry = false; // We don't need geometry here identifyParams.layerIds = [0]; // Replace with your state layer's ID identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_TOP; // Only check the top layer
Step 2.2: Fetch and Display Attributes
Inside the timer callback from Step 1, use the mouse event’s map point to run the identify task and populate the tooltip:
tooltipTimer = setTimeout(() => { identifyParams.geometry = evt.mapPoint; identifyParams.mapExtent = map.extent; identifyTask.execute(identifyParams).then((results) => { const tooltip = document.getElementById("tooltip"); if (results.length > 0) { // Extract state name from the first result's attributes const stateName = results[0].feature.attributes.STATE_NAME; // Replace with your field name tooltip.textContent = `State: ${stateName}`; // Position tooltip near the mouse cursor tooltip.style.left = `${evt.screenPoint.x + 10}px`; tooltip.style.top = `${evt.screenPoint.y + 10}px`; tooltip.style.display = "block"; } else { // Hide tooltip if no feature is found tooltip.style.display = "none"; } }).catch((err) => { console.error("Failed to fetch feature attributes:", err); document.getElementById("tooltip").style.display = "none"; }); }, 500);
3. Full Working Code Example
Here’s the complete HTML, CSS, and JavaScript to implement the fixed tooltip:
HTML
<div id="map"></div> <div id="tooltip" class="tooltip"></div>
CSS
#map { height: 500px; width: 100%; } .tooltip { position: absolute; background: #fff; padding: 8px 12px; border: 1px solid #ddd; border-radius: 4px; display: none; pointer-events: none; z-index: 1000; font-size: 14px; }
JavaScript
require([ "esri/map", "esri/layers/ArcGISDynamicMapServiceLayer", "esri/tasks/IdentifyTask", "esri/tasks/IdentifyParameters", "dojo/domReady!" ], function(Map, ArcGISDynamicMapServiceLayer, IdentifyTask, IdentifyParameters) { // Initialize map const map = new Map("map", { center: [-98.5795, 39.8283], zoom: 4, basemap: "gray" }); // Add dynamic layer const dynamicLayer = new ArcGISDynamicMapServiceLayer("YOUR_DYNAMIC_SERVICE_URL"); map.addLayer(dynamicLayer); let tooltipTimer; const identifyTask = new IdentifyTask("YOUR_DYNAMIC_SERVICE_URL"); const identifyParams = new IdentifyParameters(); identifyParams.tolerance = 3; identifyParams.returnGeometry = false; identifyParams.layerIds = [0]; // Adjust to your layer ID identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_TOP; // Mouse-over handler with delay map.on("mouse-over", (evt) => { clearTimeout(tooltipTimer); tooltipTimer = setTimeout(() => { identifyParams.geometry = evt.mapPoint; identifyParams.mapExtent = map.extent; identifyTask.execute(identifyParams).then((results) => { const tooltip = document.getElementById("tooltip"); if (results.length > 0) { const stateName = results[0].feature.attributes.STATE_NAME; // Replace with your field tooltip.textContent = `State: ${stateName}`; tooltip.style.left = `${evt.screenPoint.x + 10}px`; tooltip.style.top = `${evt.screenPoint.y + 10}px`; tooltip.style.display = "block"; } else { tooltip.style.display = "none"; } }).catch((err) => { console.error("Identify task error:", err); document.getElementById("tooltip").style.display = "none"; }); }, 500); // Adjust delay here (ms) }); // Mouse-out handler to cancel tooltip map.on("mouse-out", () => { clearTimeout(tooltipTimer); document.getElementById("tooltip").style.display = "none"; }); // Optional: Update tooltip position as mouse moves map.on("mouse-move", (evt) => { const tooltip = document.getElementById("tooltip"); if (tooltip.style.display === "block") { tooltip.style.left = `${evt.screenPoint.x + 10}px`; tooltip.style.top = `${evt.screenPoint.y + 10}px`; } }); });
Key Reminders
- Replace
YOUR_DYNAMIC_SERVICE_URLwith your actual ArcGIS dynamic service URL. - Update
layerIdsto match the ID of your state layer in the service. - Swap
STATE_NAMEwith the exact field name for state names in your layer’s attribute table. - Adjust the 500ms delay to your preferred hover timing.
内容的提问来源于stack exchange,提问作者Sarah

