mapboxgl中对popup弹窗添加事件

对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按钮,才会触发执行保存或取消逻辑。

相关推荐
augenstern4161 小时前
HTML面试题
前端·html
张可1 小时前
一个KMP/CMP项目的组织结构和集成方式
android·前端·kotlin
G等你下课2 小时前
React 路由懒加载入门:提升首屏性能的第一步
前端·react.js·前端框架
蓝婷儿3 小时前
每天一个前端小知识 Day 27 - WebGL / WebGPU 数据可视化引擎设计与实践
前端·信息可视化·webgl
然我3 小时前
面试官:如何判断元素是否出现过?我:三种哈希方法任你选
前端·javascript·算法
OpenTiny社区3 小时前
告别代码焦虑,单元测试让你代码自信力一路飙升!
前端·github
pe7er3 小时前
HTTPS:本地开发绕不开的设置指南
前端
晨枫阳4 小时前
前端VUE项目-day1
前端·javascript·vue.js
江山如画,佳人北望4 小时前
SLAM 前端
前端
患得患失9494 小时前
【前端】【Iconify图标库】【vben3】createIconifyIcon 实现图标组件的自动封装
前端