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

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

效果图

用ionic做一个仿京东商品详情页的过程记录_第1张图片

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>

用ionic做一个仿京东商品详情页的过程记录_第2张图片
调起来有点麻烦,这个有空再看怎么改。

2.导航栏

于是改用另外一个ionic的组件

<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>

然后效果是
用ionic做一个仿京东商品详情页的过程记录_第3张图片
然后再重写一下的样式。

3.单个segment的页面处理

导航(可能影响了后边的滑动,待解决)

<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.页面跳转问题

遇到一个页面跳转的问题:
用ionic做一个仿京东商品详情页的过程记录_第4张图片
用ionic做一个仿京东商品详情页的过程记录_第5张图片
产生的原因
推荐这个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. 商品页滑上去,导航栏渐变的效果

外层的ionScroll没有效果,可能是因为嵌入了的原因,所以滚动的是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)
在这里插入图片描述
用ionic做一个仿京东商品详情页的过程记录_第6张图片

//更新导航栏样式
  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>

效果:

在这里插入图片描述
用ionic做一个仿京东商品详情页的过程记录_第7张图片
在这里插入图片描述

你可能感兴趣的:(angular,ionic)