基于CSS3 Transform的自适应响应式React封装组件以及对于Swiper.js的封装

这三个小的组件是笔者对常见的一些操作的React封装,性能不一定优化,只是为了方便使用,随手写的,不过如果有什么功能建议欢迎开Issue
Github系列Repos

ScalableComponent

借鉴了pageResponse这个移动端响应式插件

核心思想就是基于CSS3 Transform中的scale变换,根据屏幕尺寸与视觉设计稿的尺寸对比进行自动释放,以求达到较好的浏览效果,适合于懒人快速适配。

Usage

设置视口

源代码

/  * Created by apple on 16/6/30. */import React, {Component, PropTypes} from "react";export default class ScalableComponent extends Component {    //设置属性值    static propTypes = {        mode: PropTypes.oneOf(['auto', 'contain', 'cover']), //选择的模式        width: PropTypes.number, //视觉稿宽度        height: PropTypes.number, //视觉稿高度        origin: PropTypes.string,//缩放中心点        wrapperBackgroundColor: PropTypes.string//背景颜色    };    /      * @function 构造函数     * @param props     */    constructor(props) {        super(props);        let userAgent = navigator.userAgent;        //判断是否为指定设备        this.wp = userAgent.match(/Windows Phone ([\d.]+)/); //判断是否为WindowsPhone        this.android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/); //判断是否为Android        //获取设备的宽高比        this.state = {            deviceWidth: document.documentElement.clientWidth,            deviceHeight: document.documentElement.clientHeight        };        //根据模式判断页面缩放比例        this.mode = this.props.mode || "auto";        //缩放中心        this.origin = this.props.origin || "left top 0";        //传入的视觉稿        this.visualWidth = this.props.width || 320;        this.visualHeight = this.props.height || 504;        this.wrapperBackgroundColor = this.props.wrapperBackgroundColor || "black";        this._calcScaleRatio = this._calcScaleRatio.bind(this);        this._updateDimensions = this._updateDimensions.bind(this);    }    /      * @function 为了避免重绘,在ComponentWillMount之前     */    componentDidMount() {        //监听页面尺寸变化        window.addEventListener("resize", this._updateDimensions);    }    componentWillUnmount() {        //移除页面尺寸变化监听        window.removeEventListener("resize", this._updateDimensions);    }    /      * @function 更新屏幕尺寸     * @private     */    _updateDimensions() {        this.setState({            deviceWidth: document.documentElement.clientWidth,            deviceHeight: document.documentElement.clientHeight        });    }    /      * @function 计算缩放参数     * @private     */    _calcScaleRatio() {        //默认缩放比例为1        let scaleRatio = 1;        let deviceAspectRatio = this.state.deviceWidth / this.state.deviceHeight;        //计算传入的视觉稿的比        let visualAspectRatio = this.visualWidth / this.visualHeight;        //计算缩放比        if (this.mode === "contain") {            //如果是包含模式,根据宽高中较大值进行缩放            scaleRatio = deviceAspectRatio > visualAspectRatio ? this.state.deviceHeight / this.visualHeight : this.state.deviceWidth / this.visualWidth;        } else if (this.mode === "cover") {            scaleRatio = deviceAspectRatio                 {/*直接将子元素放置在这里*/}                {this.props.children}        )    }}

Mode

Contain

Contain模式即保证页面完全包含在浏览器窗口中,在保证页面的宽高比情况下调整页面的宽度或者高度中的较大者,使得页面水平垂直居中,左右或上下可能出现空白。

Cover

Cover模式即使页面完全覆盖浏览器窗口,保持页面的宽高比,调整页面的宽度或高度(较小者),页面水平垂直居中,超出浏览器窗口左右或上下的内容会被隐藏

Auto

保持页面的宽高比,调整页面的宽度,使页面宽度完全包含在浏览器窗口中

Demo:Swiper封装

笔者一开始只是想对于Swiper.js做简单的封装,但是后来发现好像Swiper.js没有官方的isomorphic版本,最终为了方便还是选择封装一个同时加载外部脚本与样式的小组件。

ReactExternalLoader:外部脚本/组件加载封装组件

Usage

import React from "react";import {render} from "react-dom";import {ReactExternalLoader} from "../external_loader";render({alert("Loaded!");}}>        HI        This is Demo For Scalable, document.getElementById('root'));

源代码

/  * Created by apple on 16/7/1. */import React, {Component, PropTypes} from "react";//加载ES6 Promise Polyfillrequire('es6-promise').polyfill();//判断某个脚本是否已经被加载const promises = {};/  * @function 用于加载Script脚本 * @param src * @returns {*} */function loadScript(src) {    //判断该脚本是否被加载过    if (promises[src]) {        return promises[src]    }    //构造一个Promise对象    let promise = promises[src] = new Promise(resolve => {        //创建一个script元素        var el = document.createElement('script');        var loaded = false;        //设置加载完成的回调事件        el.onload = el.onreadystatechange = () => {            //防止重复加载            if ((el.readyState && el.readyState !== 'complete' && el.readyState !== 'loaded') || loaded) {                return false;            }            //加载完成后将该脚本的onload设置为null            el.onload = el.onreadystatechange = null;            loaded = true;            resolve();        };        el.async = true;        el.src = src;        let head = document.getElementsByTagName('head')[0];        head.insertBefore(el, head.firstChild);    });    return promise;}/  * @function 用于加载CSS文件 * @param src * @returns {*} */function loadCSS(src) {    //判断该脚本是否被加载过    if (promises[src]) {        return promises[src]    }    //构造一个Promise对象    let promise = promises[src] = new Promise(resolve => {        //创建一个script元素        var el = document.createElement('link');        el.rel = "stylesheet";        el.href = src;        el.media = "only x";        var loaded = false;        //设置加载完成的回调事件        el.onload = el.onreadystatechange = () => {            //防止重复加载            if ((el.readyState && el.readyState !== 'complete' && el.readyState !== 'loaded') || loaded) {                return false;            }            //加载完成后将该脚本的onload设置为null            el.onload = el.onreadystatechange = null;            loaded = true;            el.media = "all";            resolve();        };        //获取文档头元素        let head = document.getElementsByTagName('head')[0];        //插入刚才创建好的元素        head.insertBefore(el, head.firstChild);    });    return promise;}export class ReactExternalLoader extends Component {    //设置默认的Props    static defaultProps = {        //需要加载的外部资源地址        srcArray: ['javascript:void(0)'],        //正在加载的指示        loadingIndicator: (            Loading        ),        //加载完成回调        onLoad: () => {        }    };    //设置需要载入的Props    static propTypes = {        srcArray: React.PropTypes.array,        loadingIndicator: React.PropTypes.object,        onLoad: React.PropTypes.func    };    //全局状态    state = {        done: false    };    /      * @function 组件加载完毕之前的回调     */    componentWillMount() {        Promise.all(            this.props.srcArray.map((src)=> {                //判断是否为JS                if (typeof src === "string" && src.indexOf(".js") > -1) {                    return loadScript(src);                } else {                    return loadCSS(src);                }            })        ).then(            ()=> {                //设置加载完成                this.setState({                    done: true                });                //调用外部的完成回调                this.props.onLoad();            }        );    }    /      * @function 渲染方法     * @returns {*}     */    render() {        //如果加载完成        if (this.state.done) {            //返回实际的子组件            return this.props.children        } else {            //返回加载指示            return this.props.loadingIndicator;        }    }}

Swiper封装与使用

Usage

/  * Created by apple on 16/7/4. */import React from "react";import {render} from "react-dom";import ScalableComponent from "../scalable";import {SwiperContainer, SwiperSlide} from "../../scroll/slider/swiper";render(                    HI Slide1                    This is Demo For Scalable                    HI Slide2                    This is Demo For Scalable    , document.getElementById('root'));

最终效果:

关键字:react.js, swiper.js

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部