360SDN.COM

首页/Ionic/列表

Ionic2中使用iframe制作一个页面“浏览器”

来源:  2017-06-25 07:34:15    评论:0点击:

来源:http://blog.csdn.net/qq_15096707/article/details/55194781

前言

  我们会遇到这样的一个需求:像是在 Ionic2 中加载一个网页,如:在Ionic2中加载一个H5页面,页面的内容可以为资讯的详情或者活动详情等等。那么在Ionic2中就需要有这样一个东西,用来加载H5页面。在Android原生中有WebView。那在Ionic2中有什么呢?

ionic-native

  在Ionic2中,ionic-native包中提供了,如 InAppBrowser 和 ThemeableBrowser 等这两个cordova插件用来打开一个“WebView”类似的窗口,用来加载页面。

ThemeableBrowser的使用

  如使用ThemeableBrowser插件,打开一个新的窗口加载页面,效果如下:
ThemeableBrowser在Android下的效果 ThemeableBrowser在iOS下的效果
  使用ThemeableBrowser可以参考,我写过的一篇文章《 ionic2中ThemeableBrowser插件的使用——App内嵌浏览器》。

ThemeableBrowser的缺点

  1. 使用ThemeableBrowser时,在定义顶部标题栏样式的时候显得繁琐,不容易定义与当前APP主题一致de样式;
  2. 浏览器调试时无法调用cordova插件,需要真机运行。
  3. 在标题栏添加一些自定义的菜单项也显得不那么容易。

使用iframe仿浏览器加载页面

  为了让这个iframe变得更加通用,同时更像一个“浏览器”。在这里,在Ionic2中定义一个BrowserPage页面,我们在打开该页面的时候需要传递browser的配置参数,配置如:页面标题、访问的页面链接、定义分享配置等。
  在这个浏览器中定义了一个popover菜单,默认只拥有 “刷新”(刷新页面)、“关闭”(关闭当前页面)的功能。

browser.html

  这里定义了“浏览器”的页面,其中包含了加载页面时显示的进度条(可以说是伪进度条,没有计算真正访问页面时候的进度。)

<ion-header no-shadow>
  <ion-navbar class="page-navbar">
    <ion-title>{{browser.title}}</ion-title>

    <ion-buttons end>
      <button ion-button icon-only (click)="presentPopover($event)">
        <ion-icon name="more"></ion-icon>
      </button>
    </ion-buttons>
  </ion-navbar>
</ion-header>

<ion-content class="content"> <!--scroll="true" overflow-scroll="true"-->
  <div class="progress" [hidden]="browser.isLoaded">
    <div class="progress-inner" id="progress"></div>
  </div>

    <iframe id="iframe" class="iframe"
            sandbox="allow-scripts allow-top-navigation allow-pointer-lock allow-same-origin allow-popups allow-forms"
            [src]="browser.secUrl"
            (load)="loaded()">
    </iframe>
</ion-content>
<panel-share [(isShow)]="shareConfig.isShow" [share]="browser.share"></panel-share>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

  注:这里定义了一个 panel-share 组件,用于显示分享功能(如:微信分享、朋友圈分享、QQ分享等)。用户可以自己定义 点击菜单栏上“分享”后显示的分享组件。这里只是举个栗子。

browser.scss

  定义browser的样式,进度条样式。

page-browser {
  $progress-height: 0.2rem;
  //$progress-bg: #d43f3a;
  //$progress-bg: linear-gradient(-45deg, #333 100%, #324512 60%,rgba(255,255,255,0.5) 0%);
  //$progress-bg: linear-gradient(left, #5bd8ff, #ff0000);
  //$progress-bg: linear-gradient(-45deg, rgba(255,255,255,0.5)0%, #324512 60%,#333 100%);
  $progress-bg: #77b6ff;

  /*.scroll-content {
    overflow: hidden;
  }*/

  .content {
    height: 100%;
  }

  .progress{
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    height: $progress-height;
    background: #f5f5f5;
    z-index: 200;

    .progress-inner{
      width: 0;
      background: $progress-bg;
      position: absolute;
      top: 0;
      left: 0;
      bottom: 0;

      box-shadow: 0 0 10px rgba(119,182,255,0.7);
      -webkit-transition: width 0.4s ease;
      transition: width 0.4s ease;
    }
  }

  .iframe {
    width: 100%;
    height: 100%;
    position: absolute;
    overflow: auto;
    border: none;
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 4

browser.ts定义浏览器功能

  主要是加载页面时显示进度条、刷新页面、分享回调(如果打开browser页面时,传入的分享的配置参数)等功能。

/**
 * Created by DreamBoy on 2016/11/21.
 */
import { Component } from '@angular/core';
import { NavController, NavParams, PopoverController } from 'ionic-angular';
import { DomSanitizer } from "@angular/platform-browser";
import { BrowserPopoverPage } from "./browser-popover";

@Component({
  selector: 'page-browser',
  templateUrl: 'browser.html'
})
export class BrowserPage {
  browser: any = {
    isLoaded: false, // 网页是否被加载
    proObj: null, // 进度条对象
    progress: 0, // 网页访问的进度条
    secUrl: '', // 安全链接

    title: '加载中',
    url: '',
    share: null // 是否具有分享功能(传递一个分享对象ShareModel过来)
  };

  shareConfig: any = {
    isShow: false
  }; // 分享控制的配置

  constructor(public navCtrl: NavController,
              private params: NavParams,
              private sanitizer: DomSanitizer,
              private popoverCtrl: PopoverController) {
    let browser = this.params.get('browser');
    if(browser) {
      this.browser.title = browser.title;
      this.browser.url = browser.url;
      this.browser.secUrl = this.sanitizer.bypassSecurityTrustResourceUrl(browser.url);

      if(browser.share) {
        this.browser.share = browser.share;
      }

    } else {
      this.browser.secUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.browser.url);
    }
    this.reload();
  }

  ionViewDidLoad() {
    if(!this.browser.proObj) {
      this.browser.proObj = document.getElementById('progress');
    }
    this.onprogress();
  }

  // 生成随机数
  private random(min: number, max: number): number {
    return Math.floor(Math.random() * (max - min + 1) + min);
  }

  // 网页访问进度
  private onprogress() {
    // 随机时间
    let timeout = this.random(10, 30);

    let timer = setTimeout(() => {
      if(this.browser.isLoaded) {
        this.browser.proObj.style.width = '100%';
        clearTimeout(timer);
        return;
      }

      // 随机进度
      this.browser.progress += this.random(1, 5);

      // 随机进度不能超过 90%,以免页面还没加载完毕,进度已经 100% 了
      if(this.browser.progress > 90){
        this.browser.progress = 90;
      }

      this.browser.proObj.style.width = this.browser.progress + '%';
      this.onprogress();
    }, timeout);
  }

  // 如果iframe页面加载成功后
  loaded() {
    this.browser.isLoaded = true;
  }

  // 显示Popver选项
  presentPopover(myEvent) {
    let cb = {
      refresh: () => {
        this.reload();
      },
      close: () => {
        this.navCtrl.pop();
      },
      share: null
    };

    if(this.browser.share) {
      cb.share = () => {
        this.share();
      }
    }

    let popover = this.popoverCtrl.create(BrowserPopoverPage, {
      callback: cb
    });
    popover.present({
      ev: myEvent
    });
  }

  // 重新加载页面
  reload() {
    let title = this.browser.title;
    let url = this.browser.secUrl;
    this.browser.title = '加载中';
    this.browser.secUrl = this.sanitizer.bypassSecurityTrustResourceUrl('');

    setTimeout(() => {
      this.browser.isLoaded = false;
      this.browser.progress = 0;
      if(!this.browser.proObj) {
        this.browser.proObj = document.getElementById('progress');
      }
      this.onprogress();
      this.browser.title = title;
      this.browser.secUrl = url;
    }, 10);
  }

  // 分享页面(作为popover的回调)
  share() {
    this.shareConfig.isShow = true;
    /*if(this.browser.share) {
      SocialSharing.share(this.browser.share.title, this.browser.share.content, '', this.browser.share.url).then(() => {

      }, (err) => {
        // Error!
        alert('错误:分享失败!' + err);
      });
    }*/
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

browser-popover.ts菜单项

  点击对应的功能,调用 browser.ts 中的方法。

/**
 * Created by admin on 2016/11/22.
 */
import { Component } from '@angular/core';
import { ViewController, NavParams } from "ionic-angular";

@Component({
  template: `
    <ion-list>
      <button ion-item detail-none (click)="refresh()">刷新</button>
      <button ion-item detail-none (click)="share()" *ngIf="parentCallback.share">分享</button>
      <button ion-item detail-none (click)="close()">关闭</button>
    </ion-list>
  `
})
export class BrowserPopoverPage {
  parentCallback: {refresh: () => void, share?: () => void, close: () => void};

  constructor(public viewCtrl: ViewController,
              private navParams: NavParams) {
    this.parentCallback = this.navParams.data.callback;
  }

  // 刷新
  refresh() {
    this.parentCallback.refresh();
    this.viewCtrl.dismiss();
  }

  // 分享
  share() {
    this.parentCallback.share();
    this.viewCtrl.dismiss();
  }

  close() {
    this.viewCtrl.dismiss();
    this.parentCallback.close();
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

定义 ShareModel 模型

  这里的share模型主要用于调用分享时作为传入browser的参数的类型。

/**
 * Created by admin on 2017/1/18.
 */

export class ShareModel { // 分享
  title: string; // 标题
  banner: string; // 标语提示
  descr: string; // 描述
  thumb: string; // 显示的缩略图
  url: string; // 链接
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

BrowserPage的使用示例

  基本使用:

this.navCtrl.push(this.browserPage, {
                browser: {
                    title: '页面名称',
                    url: '这里放置访问的页面链接'
                }
            });
  • 1
  • 2
  • 3
  • 4
  • 5

  添加“分享”功能:

let share: ShareModel = new ShareModel();
            share.title = '标题';
            share.banner = '标语提示';
            share.thumb = '缩略图';
            share.descr = '描述';
            share.url = '分享的链接';
            this.navCtrl.push(this.browserPage, {
                browser: {
                    title: '页面名称',
                    url: '这里放置访问的页面链接',
                    share: share
                }
            });
  • 1
  • 2
  • 3

BrowserPage使用效果

  打开一个页面:
 


  打开菜单:
 


  调用分享,分享页面链接:
使用BrowserPage调用分享


注意事项

在iOS中iframe加载不了网页的问题(iframe白屏)

  需要在config.xml添加“allow-navigation”,允许设置多个域下的访问,如(下面这个是初始项目给出的栗子):

<allow-navigation href="http://ionic.local/*"/>
  • 1
  •  

  通用的写法有(当前安全性就低一些咯,可以设置允许访问的几个域):

<allow-navigation href="*" />
 

在iOS中iframe加载页面后页面不可滚动的问题

  在iframe的容器,如div,增加一个 -webkit-overflow-scrolling: touch;属性。如:

.scroll-wrapper {  
    -webkit-overflow-scrolling: touch;  
    overflow-y: scroll;  
    /* 提示: 请在此处加上需要设置的大小(dimensions)或位置(positioning)信息! */  
}  
.scroll-wrapper iframe {  
    /* 你自己指定的样式 */  
}  
  • 1
  • 2
  • 3
  • 4
  • 5

  在Ionic2中的.scroll-content类样式包含了 -webkit-overflow-scrolling: touch;属性,所以不会出现这样的问题(页面不可滚动的问题)。那如果我们定义 .scroll-content 的overflow属性为 hidden。那就会出现这样的问题了。

为您推荐

友情链接 |九搜汽车网 |手机ok生活信息网|ok生活信息网|ok微生活
 Powered by www.360SDN.COM   京ICP备11022651号-4 © 2012-2016 版权