记录一个在鸿蒙网页中添加原生组件,并跟随滚动的效果实现

时间:2024-04-12 16:49:21

场景:
鸿蒙网页中,我们需要在某个位置添加一个原生的组件,比如视频或者音频
并且该组件要达到像是内嵌到网页中的效果一样,跟随网页滚动

思路,我们将网页放在一个stack组件上面,然后将 需要嵌入到网页的原生组件也放到网页上。这里面我们需要确定两个临界位置
第一: 当原生组件位置超出网页最底部,
第二:当原生组件已经被完全滑出网页顶部
第三:就是原生组件在网页中跟随网页滚动

第一中情况下,我们将原生组件放到网页组件的底部(超出网页)
第二中情况下,我们将原生组件放到网页顶部(完全滑出网页的位置)

第三中情况下,我们设置原生组件在stack中的position为(组件在网页中的位置y - 网页的偏移量)有了这个思路之后,我们就可以写代码了

 build() {
      Stack() {
        // 组件创建时,加载www.example.com
        Web({ src: '', controller: this.controller })
          .height(TPCommonConstants.FULL_LENGTH)
          .width(TPCommonConstants.FULL_LENGTH)
          .javaScriptProxy({
            object: this.messageHandler,
            name: "messageHandler",
            methodList: methodList,
            controller: this.controller
          })
          .onPageEnd(e => {
            this.messageHandler!.bindController(this.controller)
            this.controller.runJavaScript('webOnload(``)')
          })
          .onProgressChange(e => {
          })
          .onConsole(e => {
            Logger.info(e!.message.getMessage())
            return true;
          })
          .onControllerAttached(() => {
            this.loadHtmlData();
          })
          .overScrollMode(OverScrollMode.NEVER)
          .onScroll((e) => {

            this.audioList.forEach((item:TPJSEventModel,index:number)=>{
              let posty:number = item.pos_y
              if (e.yOffset < posty - this.screenHeight) {
                this.audioViewYArray[index] = this.screenHeight
              } else if (e.yOffset > posty + item.pos_h) {
                this.audioViewYArray[index] = -item.pos_h
              } else {
                this.audioViewYArray[index] = (posty - e.yOffset)
              }
            })


            if (this.messageHandler!.scroll) {
              this.messageHandler!.scroll(e.yOffset);
            }
            this.lastOffset = e.yOffset;
          })
          .layoutWeight(1)
        if (this.detailModel && this.detailModel.audioDTOList && this.detailModel.audioDTOList.length > 0 && this.audioList) {
          ForEach(this.audioList,(item:TPJSEventModel,index:number)=>{
            TPNewsDetailAudioView({
              audioModel: this.detailModel!.audioDTOList![index],
              audioController:this.audioController,
              audioIndex:this.audioIndex,
              viewIndex:index,
              audioClick:(isPlay:boolean)=>{
                this.audioPlay(isPlay,index)
              }
            })
              .position({ y: this.audioViewYArray[index] })// .backgroundColor(Color.Red)
              .width(TPCommonConstants.FULL_LENGTH)
              .height(item.pos_h)
              .padding({ left: item.pos_x, right: item.pos_x })
          })
        }
      }
     
  }