对mapbox的popup弹窗添加事件,实现其编辑保存功能
思路:
创建添加popup
添加事件监听器,监听dom是否已被创建
并添加事件监听器,监听click事件
如果单击在button上面,则执行逻辑

需要实现 -> 当我点击编辑的时候,显示输入框
js
async createPopup(obj, shapeType, info) {
// 删除marker
this.markers.forEach((item) => {
item.remove();
});
let center = null;
if (shapeType === "polygon") {
let polygonGeometry = WKT.parse(obj);
center = polygonGeometry.coordinates[0][0][0];
} else if (shapeType === "line") {
let lineGeometry = WKT.parse(obj);
center = lineGeometry.coordinates[0][0];
} else if (shapeType === "point") {
let pointGeometry = WKT.parse(obj);
center = pointGeometry.coordinates[0];
}
this.isEditMode = false; // 添加编辑状态标识
this.currentEditingInfo = null; // 存储当前编辑的数据
// 创建Popup内容的函数
function createPopupContent(info, _this) {
return `
<div class="custom-popup">
<div class="popup-title">${_this.isEditMode ? "编辑模式" : info.dd}</div>
<div class="popup-body">
<div class="custom-tool-bar">
<button class="edit-btn">${_this.isEditMode ? "取消" : "编辑"}</button>
${_this.isEditMode ? '<button class="save-btn">保存</button>' : ""}
</div>
<div class="custom-row">
<div><div class="row-label">地点:</div>${info.dd}</div>
<div><div class="row-label">组名:</div>${
_this.isEditMode
? `<input type="text" value="${info.zm}" class="edit-field" data-field="zm" />`
: info.zm
}</div>
</div>
<div class="custom-row">
<div><div class="row-label">项目名称:</div>${
_this.isEditMode
? `<input type="text" value="${info.xmmc}" class="edit-field" data-field="xmmc" />`
: info.xmmc
}</div>
<div><div class="row-label">系统面积(m²):</div>${parseFloat(
info.jsmj
).toFixed(2)}</div>
</div>
<div class="custom-row">
<div><div class="row-label">编号:</div>${
_this.isEditMode
? `<input type="text" value="${info.bh}" class="edit-field" data-field="bh" />`
: info.bh
}</div>
<div><div class="row-label">原产权人:</div>${
_this.isEditMode
? `<input type="text" value="${info.ycqr}" class="edit-field" data-field="ycqr" />`
: info.ycqr
}</div>
</div>
<div class="custom-row">
<div><div class="row-label">面积(m²):</div>${
_this.isEditMode
? `<input type="number" value="${
info.mj || ""
}" class="edit-field" data-field="mj" step="0.01" />`
: info.mj
? parseFloat(info.mj).toFixed(2)
: ""
}</div>
<div><div class="row-label">折合亩数:</div>${
_this.isEditMode
? `<input type="number" value="${
info.zhms || ""
}" class="edit-field" data-field="zhms" step="0.01" />`
: info.zhms
? parseFloat(info.zhms).toFixed(2)
: ""
}</div>
</div>
<div class="custom-row">
<div><div class="row-label">村落:</div>${
_this.isEditMode
? `<input type="text" value="${info.cl}" class="edit-field" data-field="cl" />`
: info.cl
}</div>
<div><div class="row-label">类别:</div>${
_this.isEditMode
? `<select class="edit-field" data-field="lb" name="lb" id="lb">
<option value="流转" ${info.lb === "流转" ? "selected" : ""}>流转</option>
<option value="征用" ${info.lb === "征用" ? "selected" : ""}>征用</option>
</select>`
: info.lb
}</div>
</div>
<div class="custom-row">
<div><div class="row-label">备用:</div>${
_this.isEditMode
? `<input type="text" value="${info.by}" class="edit-field" data-field="by" />`
: info.by
}</div>
<div><div class="row-label">说明:</div>${
_this.isEditMode
? `<input type="text" value="${info.sm}" class="edit-field" data-field="sm" />`
: info.sm
}</div>
</div>
<div class="custom-row">
<div><div class="row-label">备注:</div>${
_this.isEditMode
? `<textarea class="edit-field" data-field="bz">${
info.bz || ""
}</textarea>`
: info.bz || ""
}</div>
</div>
</div>
</div>`;
}
// 创建Popup
this.currentEditingInfo = { ...info }; // 复制当前信息用于编辑
const description = createPopupContent(this.currentEditingInfo, this);
let popup = new mapboxgl.Popup().setLngLat(center).setHTML(description);
// 添加事件监听
popup.on("open", () => {
console.log("初始化popup完成");
const popupContent = document.querySelector(".mapboxgl-popup-content");
popupContent.addEventListener("click", (e) => {
if (e.target.classList.contains("edit-btn")) {
// 切换编辑模式
this.isEditMode = !this.isEditMode;
// 重新设置Popup内容
popup.setHTML(createPopupContent(this.currentEditingInfo, this));
}
if (e.target.classList.contains("save-btn")) {
// 收集所有编辑字段的值
const inputs = popupContent.querySelectorAll(".edit-field");
inputs.forEach((input) => {
const field = input.dataset.field;
const value =
input.tagName === "TEXTAREA" ? input.value : input.value;
this.currentEditingInfo[field] = value;
});
// 调用保存方法
const res = this.saveData(this.currentEditingInfo, popup);
if (res) {
// 切换查看模式
this.isEditMode = !this.isEditMode;
// 重新设置Popup内容
popup.setHTML(createPopupContent(this.currentEditingInfo, this));
}
}
});
});
popup.addTo(this.map);
popup.on("close", () => {
console.log("弹窗关闭");
});
this.markers.push(popup);
},
// 保存的方法 - api调用
async saveData(updatedInfo, popup) {
// 这里实现你的保存逻辑,可以是API调用或其他存储方式
try {
await editZylzApi(updatedInfo);
this.$message.success("保存成功");
//初始化列表
return true;
} catch (error) {
return false;
}
},
解释:
主要利用变量isEditMode
来控制显示输入框还是内容,每次修改时利用popup.setHTML
方法来重新渲染popup弹窗,遍历dom元素,添加监听器确认点击的是button按钮,才会触发执行保存或取消逻辑。