用ionic做一个仿京东商品详情页的过程记录

之前只有一个详情页,老板说改成和京东一样的0.o

效果图

在这里插入图片描述

1.导航栏 ionic2-super-tabs

原本打算导航用“ionic2-super-tabs”做,但是这个super-tabs是一个整体 ,tab和内容页连在一起, 不能同时满足在tab上加东西和让内容页占满屏幕。

<ion-row style="height:100%;background:#fff;">
  <ion-col col-3>
    
  </ion-col>
  <ion-col col-6 no-padding>
    <super-tabs *ngIf="categoryList.length>0" id="storeTabs" [config]="{ sideMenu: 'left' }">
      <super-tab *ngFor="let item of categoryList;" [root]="item.page" [title]="item.titel" id="item.id"></super-tab>
    </super-tabs>
  </ion-col>
  <ion-col col-3>
    2 3
  </ion-col>
</ion-row>

在这里插入图片描述
调起来有点麻烦,这个有空再看怎么改。

2.导航栏 <ion-segment>

于是改用另外一个ionic的组件<ion-segment>

<ion-header>
  <ion-navbar>
        <ion-segment [(ngModel)]="detailtype">
          <ion-segment-button value="detailgoods">
            商品
          </ion-segment-button>
          <ion-segment-button value="detailinfo">
            详情
          </ion-segment-button>
          <ion-segment-button value="detailevaluate">
            评价
          </ion-segment-button>
          <ion-segment-button value="detailrecommend">
            推荐
          </ion-segment-button>
        </ion-segment>
      
      <ion-buttons end>
        <button ion-button>
          <i class="iconfont iconfont_small icon-fenxiang1 list-item-ic"></i>
        </button>
        <button ion-button>
          <i class="iconfont iconfont_small icon-more list-item-ic"></i>
        </button>
      </ion-buttons>
  </ion-navbar>
</ion-header>

<ion-content> 
  <div [ngSwitch]="detailtype">
    <ng-container *ngSwitchCase="'detailgoods'">
      detailgoods
    </ng-container>

    <ng-container *ngSwitchCase="'detailinfo'">
      详情
    </ng-container>

    <ng-container *ngSwitchCase="'detailevaluate'">
      评价
    </ng-container>

    <ng-container *ngSwitchCase="'detailrecommend'">
      推荐
    </ng-container>
  </div>
</ion-content>

然后效果是
2018121203.png
然后再重写一下<ion-segment>的样式。

3.单个segment的页面处理

<ion-nav>导航(可能影响了后边的滑动,待解决)

<ion-content> 
  <div [ngSwitch]="detailtype">
    <ng-container *ngSwitchCase="'detailgoods'" >
      <ion-nav [root]="DetailgoodsPage" [rootParams]="rootParams"></ion-nav>
    </ng-container>

    <ng-container *ngSwitchCase="'detailinfo'">
      <ion-nav [root]="DetailinfoPage" [rootParams]="goodsdetail"></ion-nav>
    </ng-container>

    <ng-container *ngSwitchCase="'detailevaluate'">
      <ion-nav [root]="DetailevaluatePage"></ion-nav>
    </ng-container>

    <ng-container *ngSwitchCase="'detailrecommend'">
      <ion-nav [root]="DetailrecommendPage" [rootParams]="role"></ion-nav>
    </ng-container>
  </div>
</ion-content>
4.页面跳转问题

遇到一个页面跳转的问题:
在这里插入图片描述
在这里插入图片描述
产生的原因
推荐这个segment内是一个商品列表,push进去后也是和当前一样的商品详情页,但是是在segment内跳转的,所以页面会嵌在segment内
解决:从当前segment的父级push

gotodetail(brand) {
    //this.navCtrl.push('GoodsdetailPage',{goods_id: brand.goods_id,role: this.role});
    this.navCtrl.parent.push('GoodsdetailPage',{goods_id: brand.goods_id,role: this.role});
  }

参考官方文档:NavController的实例成员parent

5. 商品页滑上去,导航栏渐变的效果

外层<ion-content>的ionScroll没有效果,可能是因为嵌入了<ion-segment>的原因,所以滚动的是ion-segment内的页面,触发的也是ion-segmention-content的scroll事件;

于是去掉了第3步的导航,将四个sgement的内容都拿出来放到当前页面,这样的话第4步也不必了;

渐变效果分析

  1. 一开始在商品页导航栏透明度是0,页面滚动时透明度渐变,头部内的内容也随着变化,往上滚动到一定距离会变成固定值
  2. 切换到其它页时,透明度一直是那个固定值不会变化;
  3. 切回到商品页时,透明度还是之前在商品页时的透明度。

导航栏变化时机:1.商品页滑动时2.切换segment页面时。
实现

  1. 设置3个全局的变量
//导航栏
scrolltop: any;//商品页上滑的高度
opacity: any;//透明度
headerheight: any;//header高度
  1. 商品页绑定scroll事件,得到往上滚动的距离,计算透明度值,改变导航栏样式
scrollToTop(evt) {
    if(this.detailtype=="detailgoods") {
      console.log('detailgoods_scrollToTop');
      console.log(evt);
      this.scrolltop = evt.scrollTop;
      this.opacity = this.scrolltop/this.headerheight;
      this.updatestyle('detailgoods');
    }
  }
  1. 切换segment时改变导航栏样式

这里计算margin-top原本是设置给外层的但是设置不了,才设置在了里一层的div,效果一样

  segmentChanged(evt) {
    //margin高度
    //
    if(evt.value=="detailgoods") {
      this.renderer.setStyle(this.goodsdetailContent.nativeElement,'margin-top','0');
    }else {
      this.renderer.setStyle(this.goodsdetailContent.nativeElement,'margin-top',String.raw`${this.headerheight}px`);
    }

    //导航栏
    this.updatestyle(evt.value);
  }
  1. 根据透明度改变导航栏的样式

这里在取被点击的那个segment时总是取不到,最先用的是直接取包含.segment-activated的dom元素,但是一直取的都是上一次点击的segment,明明那个状态已经改变了;后来改成在被点击的大segment里取包含.segment-activated的dom元素,和上种情况一样;然后根据当前被点击的那个segment-button终于取到了当前被点击的segment,但是没有nativeElement不能操作dom;于是继续采用第一种方法,不过加了个定时器延迟了取dom的时间终于取到了对的,但是加了一个有固定时间的定时器不太好。
于是求助了头儿后的最终的方法是,给每个segment加固定的id,切换时取当前id的dom元素就可以了,不用管什么.segment-activated啦!(感觉自已好死脑筋,有变化的class不好取,取id不就行了?0.o)
在这里插入图片描述
在这里插入图片描述

//更新导航栏样式
  updatestyle(detailtype) {
    //segment按钮
    let objel = this.element.nativeElement.querySelectorAll('.segment-button');
    // let objelact = this.element.nativeElement.querySelectorAll('.segment-activated')[0];
    let objelact = this.element.nativeElement.querySelectorAll('#'+detailtype)[0];

    //两边按钮
    let headerbtn = this.element.nativeElement.querySelectorAll('ion-header .bar-button-ios');
    //右边的按钮
    let rightbtn = this.element.nativeElement.querySelectorAll('.endbtn .bar-button-ios');
    //左边的按钮
    let leftbtn = this.element.nativeElement.querySelectorAll('.back-button .button-inner')[0];

    if(detailtype=="detailgoods") {
      // console.log(true);
      if(this.opacity>=0.9) {
        this.opacity = 0.9;
        headerbtn.forEach((element)=>{
          this.renderer.setStyle(element,'color',String.raw`rgba(136,136,136, 1)`);
        })
        rightbtn.forEach((element)=>{
          this.renderer.setStyle(element,'background',String.raw`rgba(136,136,136, 0)`);
        })
        this.renderer.setStyle(leftbtn,'background',String.raw`rgba(136,136,136, 0)`);
      }else if(this.opacity>=0.3 && this.opacity<1){
        headerbtn.forEach((element)=>{
          this.renderer.setStyle(element,'color',String.raw`rgba(136,136,136, ${this.opacity})`);
        })
        rightbtn.forEach((element)=>{
          this.renderer.setStyle(element,'background',String.raw`rgba(136,136,136, 0`);
        })
        this.renderer.setStyle(leftbtn,'background',String.raw`rgba(136,136,136, 0`);
      }else {
        headerbtn.forEach((element)=>{
          this.renderer.setStyle(element,'color',String.raw`rgba(255, 255, 255, ${1-this.opacity})`);
        })
        rightbtn.forEach((element)=>{
          this.renderer.setStyle(element,'background',String.raw`rgba(136,136,136, ${0.3-this.opacity})`);
        })
        this.renderer.setStyle(leftbtn,'background',String.raw`rgba(136,136,136, ${0.3-this.opacity})`);
        
      }

      objel.forEach((element)=>{
        this.renderer.setStyle(element,'color',String.raw`rgba(136,136,136, ${this.opacity})`);
      })
      this.renderer.setStyle(objelact,'color',String.raw`rgba(211, 71, 44, ${this.opacity})`);
      this.renderer.setStyle(objelact,'border-color',String.raw`rgba(211, 71, 44, ${this.opacity})`);
     
      //header背景
      this.renderer.setStyle(this.goodsheader.nativeElement,'background',String.raw`rgba(255, 255, 255, ${this.opacity})`);
    }else {
      // console.log(false);
      objel.forEach((element)=>{
        this.renderer.setStyle(element,'color',String.raw`rgba(136,136,136, 1)`);
      })
      this.renderer.setStyle(objelact,'color',String.raw`rgba(211, 71, 44, 1)`);
      this.renderer.setStyle(objelact,'border-color',String.raw`rgba(211, 71, 44, 1)`);

      //header背景
      this.renderer.setStyle(this.goodsheader.nativeElement,'background',String.raw`rgba(255, 255, 255, 1)`);
      headerbtn.forEach((element)=>{
        this.renderer.setStyle(element,'color',String.raw`rgba(136,136,136, 1)`);
        
      })
      rightbtn.forEach((element)=>{
        this.renderer.setStyle(element,'background',String.raw`rgba((136,136,136, 0)`);
      })
      this.renderer.setStyle(leftbtn,'background',String.raw`rgba((136,136,136, 0)`);
    }
  }
  1. html:
<ion-header #goodsheader no-border>
  <ion-navbar class="seachr-panel">
    <ion-segment (ionChange)="segmentChanged($event)" [(ngModel)]="detailtype">
      <ion-segment-button id="detailgoods" value="detailgoods">
        商品
      </ion-segment-button>
      <ion-segment-button id="detailinfo" value="detailinfo">
        详情
      </ion-segment-button>
      <ion-segment-button id="detailevaluate" value="detailevaluate">
        评价
      </ion-segment-button>
      <ion-segment-button id="detailrecommend" value="detailrecommend">                         
        推荐
      </ion-segment-button>
    </ion-segment>

    <ion-buttons class="endbtn" end>
      <button ion-button>
        <i class="iconfont icon-fenxiang1 list-item-ic"></i>
      </button>
      <button ion-button>
        <i class="iconfont icon-more list-item-ic"></i>
      </button>
    </ion-buttons>
  </ion-navbar>
</ion-header>


<ion-content (ionScroll)="scrollToTop($event)">
  <div #goodsdetailContent [ngSwitch]="detailtype">
    <ng-container *ngSwitchCase="'detailgoods'">
    	...
    </ng-container>
    <ng-container *ngSwitchCase="'detailinfo'">
    	...
    </ng-container>
    <ng-container *ngSwitchCase="'detailevaluate'">
    	...
    </ng-container>
    <ng-container *ngSwitchCase="'detailrecommend'">
    	...
    </ng-container>
   </div>
</ion-content>

效果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值