Loading...

文章背景图

uni-app WGT应用如何插入DOM节点并配置事件

2026-02-12
6
-
- 分钟
|

在开发uni-app的wgt应用时,遇到一个需求,需要调用方法,并插入一个自定义弹窗,弹窗内容需要动态展示一个网页;在遇到这个需求的第一时间,想到的是“WGT应用不是一个传统的HTML应用,没有DOM节点的概念的呀,这可咋实现呢”

调研

在使用了无数的JS方法,进行DOM节点查询/插入皆无法达到预期的时候,突然灵光一闪,咦,好像有个API - $getAppWebview,可以获取到当前实例的上下文,它本身也是一个HTML应用编译过来的,按理来说,是有法子的,说干就干!

探索

先行定义一段DOM节点(最基础的),使用uni-app的官方API - $getAppwebview 进行插入DOM节点试试

let jsCode = `
let dialogInfo = document.createElement("div");
dialogInfo.style.cssText = "width:100vw;height:200px;background:#000000;position:fixed;top:0;left:0";
document.body.appendChild(dialogInfo)
`
let pages = getCurrentPages()
if (pages.length > 0) {
  let pageInstance = pages[pages.length - 1]
  let viewInfo = pageInstance.$getAppWebview()
  if (viewInfo) {
    viewInfo.evalJS(jsCode);
  }
}
  • 效果图:

进阶

在确定方案可行后,开始去实现需求了,把DOM插入、样式处理进行升级&优化

const jsCode = `
        function insertDialogDOM() {
          var dialogInfo = document.createElement('div');
          dialogInfo.className = 'xyb-agent-dialog';
          var dialogContent = \`
           <div class="xyb-agent-dialog-main">
             <div class="xyb-agent-dialog-body">
              <iframe src="https://www.baidu.com" frameborder="0"></iframe>
             </div>
             <div class="xyb-agent-dialog-footer">
              <div class="xyb-agent-dialog-btn cancel">取消</div>
              <div class="xyb-agent-dialog-btn confirm">确定</div>
             </div>
           </div>
          \`;
          dialogInfo.innerHTML = dialogContent;
          document.body.appendChild(dialogInfo);
        }

        function insertStyleInfo() {
          var style = document.createElement('style');
          style.innerHTML = \`
            .xyb-agent-dialog {
              top: 0;
              left: 0;
              z-index: 100;
              width: 100vw;
              height: 100vh;
              position: fixed;
              background-color: rgba(0,0,0,0.35);
              &.is-hide {
                z-index: -1;
                opacity: 0;
                .xyb-agent-dialog-main {
                  z-index: -2;
                  opacity: 0;
                }
              }
            }
            .xyb-agent-dialog-main {
              left: 0;
              z-index: 101;
              width: 100vw;
              height: 200px;
              bottom: -200px;
              position: fixed;
              background: #FFFFFF;
              border-radius: 8px 8px 0 0;
              transition: bottom 0.2s ease-out;
              &.is-show {
                bottom: 0;
              }
            }
            .xyb-agent-dialog-body {
              width: 100vw;
              height: 159px;
              overflow-y: auto;
              overflow-x: hidden;
              border-bottom: 1px solid #DEDEDE;
            }
            .xyb-agent-dialog-footer {
              width: 100vw;
              height: 40px;
              display: flex;
              align-items: center;
              justify-content: center;
            }
            .xyb-agent-dialog-btn {
              height: 28px;
              font-size: 12px;
              padding: 0 10px;
              margin: 0 10px 0;
              line-height: 28px;
              background: #FFFFFF;
              border: 1px solid #DEDEDE;
              border-radius: 4px 4px 4px;
              &.confirm {
                 border-color: #1890ff;
              }
            }
          \`
          document.head.appendChild(style);
        }

        function closeBtnClick() {
          const cancelBtn = document.querySelector('.xyb-agent-dialog-btn.cancel');
          const main = document.querySelector('.xyb-agent-dialog')
          cancelBtn.addEventListener('click', () => {
            moveDialogIntoBottom();
            setTimeout(()=>{
              main.classList.add('is-hide');
            }, 100);
          })
        }

        function setDialogIntoBottom() {
          setTimeout(()=>{
            var targetElement = document.querySelector('.xyb-agent-dialog-main');
            if (targetElement) {
              targetElement.classList.add('is-show'); // 替换为你想要添加的类名
            }
          }, 100);
        }

        function moveDialogIntoBottom() {
          var targetElement = document.querySelector('.xyb-agent-dialog-main');
          if (targetElement) {
            targetElement.classList.remove('is-show'); // 替换为你想要添加的类名
          }
        }

        function checkDialogInfo() {
          console.log("🚀执行弹窗信息检测")
          var dialog = document.querySelector('.xyb-agent-dialog');
          if (!Boolean(dialog)){
            insertStyleInfo();
            insertDialogDOM();
            closeBtnClick();
            console.log("🚀弹窗信息不存在,执行DOM插入&样式插入")
          } else {
            console.log("🚀弹窗信息已存在,执行is-hide样式类移除")
            moveDialogIntoBottom();
            dialog.classList.remove('is-hide');
          }
          setDialogIntoBottom();
        }
        checkDialogInfo();
    `
    var pages = getCurrentPages()
    if (pages.length > 0) {
      let pageInstance = pages[pages.length - 1]
      let webView = pageInstance.$getAppWebview()
      if (webView) {
        webView.evalJS(jsCode);
      }
    }
  • 效果图

结语

遇到难搞的需求,先不要慌,透过现象看本质,问题在哪,有没有解决方式,找到解决方式后,想一想,是不是可以更优雅的去实现

评论交流

文章目录