为什么 jquery-jcrop 在我使用 destroy() 函数时破坏了我的 Leaflet 地图?

Why jquery-jcrop is destroying my Leaflet map when I use the destroy() function?

我用 jcrop 创建了一个非常简单的功能示例,它在图像上创建了一个正方形:

$('#container').Jcrop({
    onSelect: function(c){
        alert(JSON.stringify(c));
        this.destroy()
    }
})
<meta charset="UTF-8">

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-jcrop/0.9.15/css/jquery.Jcrop.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-jcrop/0.9.15/js/jquery.Jcrop.js"></script>

<img src="https://d3o1694hluedf9.cloudfront.net/market-750.jpg" id="container">

在这个例子中,函数 this.destroy() 像我预期的那样工作,它破坏了 jcrop 在我的图像上创建的阴影层。到目前为止,一切都很好。但是,当我尝试用传单做同样的事情时,它根本不起作用。这是我尝试过的:

var mymap = L.map('container', {
    center:[-23.553670644165493, -46.648217439651496],
    zoom:18,
    maxZoom:19,
    zoomControl:false,
    attributionControl:false
});         
var lyrOSRHOT = L.tileLayer.provider('OpenStreetMap.HOT');
mymap.addLayer(lyrOSRHOT);

$('#container').Jcrop({
    onSelect: function(c){
        alert(JSON.stringify(c));
        this.destroy()
    }   
})
#container{
    height: 100%;
    position: absolute;
    z-index: 0;
}
<meta charset="UTF-8">

<!-- Leaflet -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet-src.min.js" integrity="sha512-XQr+/1RXvYozXiwrumwtu3lqQmVwZ8nkLUrC/mc3HBHw4Imh++RXjwtLQFuOz3i65j9CSfKt50x6w/uUY2ovOQ==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-providers/1.12.0/leaflet-providers.min.js" integrity="sha512-LixflAm9c0/qONbz9F1Ept+QJ6QBpb7wUlPuyv1EHloTVgwSK8j3yMV3elnElGQcv7Y5QTFlF/FqyeE/N4LnKQ==" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="anonymous" />

<!-- jQUERY JCROP-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-jcrop/0.9.15/css/jquery.Jcrop.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-jcrop/0.9.15/js/jquery.Jcrop.js"></script>

<div id="container" style="height:100vh; width: 100vw"></div>

我遵循了第一个示例中的相同逻辑,但是在选择了地图的一部分之后,函数 destroy() 也破坏了 Leaflet 地图(当它是一个图片)。有谁知道会发生什么?会不会是 jcropLeaflet 有冲突,如果不修改库,我想做的事情是不可能的?

您似乎将 Jcrop 和 Leaflet 附加到同一个 #container 元素。看起来调用 Jcrop.destroy() 正在删除与该元素关联的所有内容。

你能为这两个库使用两个单独的元素吗?也许将 Leaflet 附加到您用来调用 Jcrop 的包装器或父元素。

这是我对地图和 Jcrop 组件使用两个独立元素的版本。

<html>

<head>

<meta charset="UTF-8">

    <!-- Leaflet -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet-src.min.js" integrity="sha512-XQr+/1RXvYozXiwrumwtu3lqQmVwZ8nkLUrC/mc3HBHw4Imh++RXjwtLQFuOz3i65j9CSfKt50x6w/uUY2ovOQ==" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-providers/1.12.0/leaflet-providers.min.js" integrity="sha512-LixflAm9c0/qONbz9F1Ept+QJ6QBpb7wUlPuyv1EHloTVgwSK8j3yMV3elnElGQcv7Y5QTFlF/FqyeE/N4LnKQ==" crossorigin="anonymous"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="anonymous" />

    <!-- jQUERY JCROP-->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-jcrop/0.9.15/css/jquery.Jcrop.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-jcrop/0.9.15/js/jquery.Jcrop.js"></script>

    <style type="text/css">
        .wrapper {
            position: relative;
            height:100vh;
            width: 100vw;
        }

        #cropper {
            height:100%;
            width: 100%;
        }

        #map {
            height:100%;
            width: 100%;
            position: absolute;
            top: 0;
            left: 0;
        }

        .jcrop-holder {
            z-index: 600;
            background: transparent !important;
        }
    </style>

</head>

<body>

    <div class="wrapper">
        <div id="cropper"></div>
        <div id="map"></div>
    </div>

    <script>
        var mymap = L.map('map', {
            center:[-23.553670644165493, -46.648217439651496],
            zoom:18,
            maxZoom:19,
            zoomControl:false,
            attributionControl:false
        });
        var lyrOSRHOT = L.tileLayer.provider('OpenStreetMap.HOT');
        mymap.addLayer(lyrOSRHOT);

        $('#cropper').Jcrop({
            onSelect: function(c){
                console.log(c);
                console.log(c.x);
                console.log(c.y);
                console.log(c.w);
                console.log(c.h);
                this.destroy();
            }
        })
    </script>
</body>

</html>

我最终通过创建一个不同的 div 元素来解决它,该元素使用与 Leaflet 地图使用的 space 相同的元素...解决方案如下:

var mymap = L.map('container', {
    center:[-23.553670644165493, -46.648217439651496],
    zoom:18,
    maxZoom:19,
    zoomControl:false,
    attributionControl:false,
    renderer: L.canvas()
});         
var lyrOSRHOT = L.tileLayer.provider('OpenStreetMap.HOT');
mymap.addLayer(lyrOSRHOT);

const id = "aux-container"
createFakeMap(id)
$('#'+id).Jcrop({
    onSelect: function(c){
        alert(JSON.stringify(c));
        this.destroy()
    }   
}) 

// auxiliary function
function createFakeMap(id){
    const div = document.body.appendChild(document.createElement('div'));
    document.body.appendChild(div);
    div.setAttribute("id", id);
    div.style.height = '100vh';
    div.style.width = '100vw';
}
<meta charset="UTF-8">

<!-- Leaflet -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet-src.min.js" integrity="sha512-XQr+/1RXvYozXiwrumwtu3lqQmVwZ8nkLUrC/mc3HBHw4Imh++RXjwtLQFuOz3i65j9CSfKt50x6w/uUY2ovOQ==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-providers/1.12.0/leaflet-providers.min.js" integrity="sha512-LixflAm9c0/qONbz9F1Ept+QJ6QBpb7wUlPuyv1EHloTVgwSK8j3yMV3elnElGQcv7Y5QTFlF/FqyeE/N4LnKQ==" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="anonymous" />

<!-- jQUERY JCROP-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-jcrop/0.9.15/css/jquery.Jcrop.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-jcrop/0.9.15/js/jquery.Jcrop.js"></script>

<div id="container" style="height:100vh; width: 100vw; position: absolute; z-index:1"></div>

我使用 Javascript 而不是 HTML 创建了 div 元素,因为 destroy 函数将在我执行它的所有时候销毁该元素.使用 Javascript,我可以在需要时再次动态创建它,同时不会破坏我的地图及其状态。