问题
You know when you're on a mobile device and you scroll down a web page which has a google map. The map goes dark and tells you "Use two fingers to move the map".
I want to implement exactly this in my Leaflet map. Leaflet doesn't currently offer this kind of functionality out the box.
Google refers to this functionality as Gesture Handling. If you set it to "Cooperative" you get the effect I just described. https://developers.google.com/maps/documentation/javascript/interaction
It's easy enough to detect the number of fingers being used and display the message as shown in my code example. (You'll need to run this on a mobile device or emulator to see it in effect)
If it's 1 finger I cancel the touchmove event and show my warning. Otherwise I allow the event to apply to the map. But I need to figure out some way of applying that one fingered touch event to the containing page after I've cancelled it on the map. So that the user scrolls the page instead.
Does anyone have any good ideas how to achieve this? I thought about using dispatchEvent to relay the received touchmove event object directly to the parent document. e.g: document.dispatchEvent(touchmoveevent); But no luck. Perhaps there's a better overall approach.
var myMap = L.map('mapid').setView([51.505, -0.09], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19
}).addTo(myMap);
$("#mapid").on("touchmove", function(e) {
if (e.touches.length !== 2) {
$('.mask').fadeIn();
return false;
}
});
$("#mapid").on("touchend", function(e) {
if ($('.mask').is(':visible')) {
$('.mask').fadeOut();
}
});
#mapid {
height: 600px;
}
.mask {
display: none;
position: absolute;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
top: 0;
left: 0;
z-index: 400;
}
.message {
color: #ffffff;
position: absolute;
width: 100%;
text-align: center;
top: 50%;
transform: translateY(-50%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js" integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw==" crossorigin=""></script>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<head>
<body>
<h1>Leaflet Map</h1>
<div id="mapid"></div>
<div class="scroll-shield"></div>
<div class="mask">
<div class="message">
<p>Use two fingers to move the map</p>
</div>
</div>
<h2>Stuff below</h2>
<ul>
<li>Here</li>
<li>is</li>
<li>some</li>
<li>stuff</li>
<li>below</li>
</ul>
</body>
回答1:
The key to this was ensuring that dragging, tap and scrollWheelZoom are disabled when intitializing the map.
Then temporarily re-enabling them when 2 fingered dragging, or scrolling with command or ctrl key is detected.
I've now packaged this solution into a leaflet plugin.
https://github.com/elmarquis/Leaflet.GestureHandling
来源:https://stackoverflow.com/questions/49095270/leaflet-js-implementing-gesture-handling-to-enforce-2-fingered-scrolling