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

相关推荐
栖凤4 分钟前
Java 的 try-catch 在 Agent 里失效了,我用了 5 个模式才兜住
java·前端·python
粥里有勺糖5 分钟前
视野修炼第136期 | 前端小恐龙"Deno"被收购
前端·github·ai编程
修炼的dance9 分钟前
页面塞了13.88 MB字体,导出的PDF只有71 KB
前端
qq_3691736310 分钟前
如何将 AI 生成的 HTML 网页发布成在线链接?不用自己搭建服务器
前端·人工智能·html·效率工具·html 发布
风花一世月18 分钟前
⚡ 我把一座含氢能源园区搬进了浏览器(五类能流实时算守恒,在线直接玩)
前端·人工智能
羲云39 分钟前
Claude 越界事件之后:Agent 权限设计为什么不能只靠提示词
前端
行者全栈架构师1 小时前
【鸿蒙心迹】鸿蒙网络请求架构实战——@ohos.net.http 到 Axios 封装、拦截器与统一错误处理(HarmonyOS 7.x)
前端·算法·架构
全栈Agent 小李1 小时前
【无标题】
前端·后端·agent·ai编程·全栈·cursor·mcp
羲云1 小时前
别让 AI 凭记忆做调研:给 WorkBuddy 接上可核验的实时搜索
前端
deli0071 小时前
连接池到底配多大?QPS 和 RT 算一遍,再跑 1 万次请求实测超时率
前端