Fork me on GitHub

通过canvas取图片上的颜色

通过canvas取图片上的颜色

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>canvas</title>
</head>
<body>

    <img id="img" src="http://127.0.0.1:5501/Image/2.jpg" alt="" style="display: none;">

    <canvas id="myCanvas" width="300" height="500" style="border:1px solid #c3c3c3;"></canvas>
    <div id="block" style="width:150px;height:150px;border:1px solid #c3c3c3;"></div>
</body>
<script src="../../../PlugIN/jquery.js"></script>
<script>
    var img= document.getElementById("img");

    var c=document.getElementById("myCanvas");
    var ctx=c.getContext("2d");

    ctx.drawImage(img,0,0, 150, 250);

    var x,y ;  
    // 随机取图片上某个位置的颜色
    setInterval(function(){
        x= Math.random(1,150)*100
        y= Math.random(1,250)*100
        console.log(x,y)
        var imgData=ctx.getImageData(x,y,1, 1);
        console.log(imgData)
        var r = imgData.data[0];
        var g = imgData.data[1];
        var b = imgData.data[2];
        document.getElementById('block').style.backgroundColor = "rgb("+r+","+g+","+b+")";
    },500);

</script>
</html>

nginx解决跨域

nginx解决跨域

前端开发,经常会遇到请求接口跨域的问题,要解决这个问题,经常会用到jsonp方式,今天就学习一个新的方式: nginx 代理方式

1 下载并安装 nginx

下载地址:http://nginx.org/en/download.html

2 配置nginx

找到nginx里面的 nginx.conf文件 配置要代理的域名和端口

在 http{ ...  } 里面配置新的 server  。 例如: 

server {
    listen       83;
    server_name  localhost;

    #charset koi8-r;

    #access_log  logs/host.access.log  main;

    location / {
        root   F:/nginxTest/html;
        try_files $uri $uri/ /index.html last;
    }
    location /api{
          rewrite  /api/(.*)$ /$1 break;
          proxy_pass http://221.12.19.157:8013;
    }
    location ~ .*\.(js|css|jpg|jpeg|gif|png|ico|pdf|txt)$ {
          root F:/nginxTest/;
    }  

 }

说明:

配置1: (注意避开当前已被占用的端口)

端口号 listen xx  

配置2:location /

root 入口页面的文件存放地址

配置3:location /api

proxy_pass 代理服务器域名

aiax 中请求

 <script>
    $.ajax({
        type: "get",
        url: "/api/get_home.aspx",
        success: function (msg) {
            console.log(JSON.stringify(msg));
        }
    });
</script>

启动 nginx 后 , 用 localhost: + 配置的端口 打开页面 即可

静态购物车

静态购物车

// 购物车 数量增减
// numEle-存放数量的元素 input可手动输入,此处判断了 存放元素的标签类型 ##

js封装

var ShoppingCart = function (opt) {
    var _default = {
        addEle: null,  // 数量加按钮
        reduceEle: null,   // 数量减按钮,
        numEle: null,      // 存放数量的元素
        maxNum: null        //  最大值
    }
    this._opation = $.extend({}, _default, opt)
    this.initnum = 1;
    this.init()
}
ShoppingCart.prototype = {
    init: function () {
        let $this = this
        var tagType = this._opation.numEle[0].tagName.toLowerCase();
        vals($this.initnum)  // 默认 1
        var currentNum;
        this._opation.addEle.click(function () {

            currentNum = tagType == 'input' ? $this._opation.numEle.val() - 0 : $this._opation.numEle.html() - 0;
            currentNum += 1;
            if ($this._opation.maxNum != null && currentNum > Number($this._opation.maxNum)) {
                currentNum = Number($this._opation.maxNum);
            }
            vals(currentNum)
        })
        this._opation.reduceEle.click(function () {
            currentNum = tagType == 'input' ? $this._opation.numEle.val() - 0 : $this._opation.numEle.html() - 0;
            currentNum -= 1;
            if (currentNum <= 0) {
                currentNum = 1;
            }
            vals(currentNum)
        })
        // 手动输入数值判断 是否合法 不合法则让其等于最大值
        this._opation.numEle.keyup(function () {
            currentNum = $this._opation.numEle.val() - 0;
            if ($this._opation.maxNum != null && currentNum > Number($this._opation.maxNum)) {
                currentNum = Number($this._opation.maxNum);
            }
            vals(currentNum)
        })
        function vals(num) {
            if (tagType == 'input') {
                $this._opation.numEle.val(num);
            } else {
                $this._opation.numEle.html(num);
            }
        }

    }
}

用法

var g = new ShoppingCart({
    addEle: $('.add'), // 数量加按钮
    reduceEle: $('.reduce'), // 数量减按钮,
    numEle: $('.inputCard'), // 存放数量的元素
    maxNum: 20 //  最大值
})

无缝滚动

文字无缝滚动

html

 <div id="scrollContent">
    <div class="scrollContentTranslate">
        <p id="scroll1">内容纯属娱乐,暂不向未满18岁青少年提供服务。严格按照法律法规和用户协议对您的信息进行全方位的保护,请放心使用。<span></span> </p>
        <p id="scroll2"></p>
    </div>
 </div>
<script> 
  indexScroll.init() 
</script>

css

#scrollContent {
    width: 93%;
    margin: 0 auto 2.5rem;
    padding-left: .4rem;
    overflow: hidden;

    .scrollContentTranslate {
        float: left;
        width: auto;
        min-width: 8000%;
    }

    #scroll1,
    #scroll2 {
        float: left;
        font-size: .32rem;
        color: #fff;
        white-space: nowrap;

        span {
            display: inline-block;
            width: 3.67rem;
        }
    }
}

js

var indexScroll = {
    init: function () {
        var speed = 50; //数字越大速度越慢
        var tab = document.getElementById("scrollContent");
        var tab1 = document.getElementById("scroll1");
        var tab2 = document.getElementById("scroll2");
        tab2.innerHTML = tab1.innerHTML;
        function Marquee() {
            if (tab2.offsetWidth - tab.scrollLeft <= 0)
                tab.scrollLeft -= tab1.offsetWidth
            else {
                tab.scrollLeft++;
            }
        }
        setInterval(Marquee, speed);
    }
}

音频播放控件

页面audio.html

html:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <script src="../js/jquery.js"></script>
    <script src="../js/flexible.debug.js"></script>
    <meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no">
    <title>济公全传-奇文小说</title>
    <!-- 播放器样式 -->
    <link rel="stylesheet" type="text/css" href="../css/audio.css">
    <!-- 页面样式,按设计稿 -->
    <link rel="stylesheet" href="../css/style.css">


</head>

<body>
    <!-- 磨砂背景 -->
    <!-- <div class="blur">
            <img src="../../Image/2.jpg" alt="">
        </div> -->
    <!--fixLayer  -->
    <div class="audiosWrap fixLayer">
        <div class="header wHeadBg pageHead">
            <div class="head-left"><a class="back" href="#"><img src="../img/back.png" alt=""></a></div>
            <!-- <div class="head-left"><a class="back" href="#"><img src="../img/backW.png" alt=""></a></div> -->
            <div class="head-middle">
                <p>尤物小妻潜上瘾</p>
            </div>
            <!-- <div class="head-right">
                <p class="headRightBox">
                    <a class="menu" href="javascript:;"></a>
                </p>
            </div> -->
        </div>
        <!-- 标题 -->
        <div class="cdText">
            <p>尤物小妻潜上瘾</p>
        </div>
        <!-- 封面 -->
        <div class="cdBox">
            <div class="coverBox">
                <img class="coverImage" src="../img/1.jpg">
            </div>
        </div>
        <!-- 播放器控制面板 -->
        <div class="controlBox">
            <div id="playContent">

                <div onclick="myControl.selectTime(event)" id="progressWrap">
                    <div id="progress" style="display: block;"></div>
                    <div class="timeBox">
                        <span id="currentTime">00:00</span>
                        <span id="totleTime">12:30</span>
                    </div>
                </div>

            </div>

            <ul>
                <li class="small">
                    <a id="prevButton" class="prev gray"
                        href="./listening.html?url=http://file.huaxiazi.com/mp3/%E6%B5%8E%E5%85%AC%E5%85%A8%E4%BC%A0/jgqz002.mp3"></a>
                </li>
                <li class="playbg">
                    <a id="playButton" onclick="myControl.mainControl()" class="play"></a>
                </li>
                <li class="small">
                    <a id="nextButton" class="next"
                        href="http://file.huaxiazi.com/mp3/%E6%B5%8E%E5%85%AC%E5%85%A8%E4%BC%A0/jgqz003.mp3"></a>
                </li>
            </ul>

            <ol>
                <li class="collect noCollected">
                    <a href="javascript:;"><i></i><span>收藏</span></a>
                </li>
                <li id="playSpeed" class="speed">
                    <a href="javascript:;"><i></i><span>1倍数</span></a>
                </li>
                <li class="directory">
                    <a
                        href="../../HTML/page/listening-moreList.html?url=http://file.huaxiazi.com/mp3/%E6%B5%8E%E5%85%AC%E5%85%A8%E4%BC%A0/jgqz003.mp3"><i></i><span>目录</span></a>
                </li>
            </ol>

            <audio id="myMusic">
                <!-- <source src="http://file.huaxiazi.com/mp3/%E6%B5%8E%E5%85%AC%E5%85%A8%E4%BC%A0/jgqz001.mp3" type="audio/ogg">
                <source src="http://file.huaxiazi.com/mp3/%E6%B5%8E%E5%85%AC%E5%85%A8%E4%BC%A0/jgqz001.mp3" type="audio/mpeg">
            -->
            </audio>
        </div>

    </div>

    <!-- 固定悬浮窗 -->
    <div class="fixAudio">
        <p>5</p><img src="../../Image/1.jpg" alt="">
    </div>
</body>
<!-- 
    音频
 -->
<script src="../js/jquery.cookie.js"></script>
<script src="../js/audiospage.js"></script>
<script src="../js/audios.js"></script>

<script>
    // 自动播放
    var myControl = new Control({
        currentSrc: 'http://file.huaxiazi.com/mp3/%E6%B5%8E%E5%85%AC%E5%85%A8%E4%BC%A0/jgqz001.mp3',
        callback: function() {
            console.log('执行事件')
        }
    })
    myControl.initAutoPlay()

    // 点击播放
    // $('#test').click(function(){
    //     myControl.mainControl()
    // })
</script>

</html>

audio.js

js

//播放器控制面板    
var Control = function (o) {
    let that = this
    var setting = {
        audio: $("#myMusic")[0], //播放器
        progressWrap: $("#progressWrap"), //歌曲进度条容器
        progress: $("#progress"),     //歌曲进度条
        playBtn: $("#playButton"),   //主控按钮
        allTimeNode: $("#totleTime"),    //总时间容器
        currentTimeNode: $("#currentTime"),   //当前时间容器
    }
    this._opation = $.extend({}, setting, o);

    this.audio = this._opation.audio;
    this.progressWrap = this._opation.progressWrap;
    this.progress = this._opation.progress;
    this.playBtn = this._opation.playBtn;
    this.allTimeNode = this._opation.allTimeNode;
    this.currentTimeNode = this._opation.currentTimeNode;

    this.init();
}

Control.prototype = {
    // 默认设置
    init: function () {
        let that = this
        //播放控制    
        this.start = true;
        //定时器
        this.timer = null;

        // 设置播放地址
        this.audio.src = this._opation.currentSrc;
        // 进入页面播放速率
        this.setPlaySpeed();
        // 进入页面开始播放地址以及时间点
        this.pagePlay();
        // 每隔2s记录一次播放地址时间
        setInterval(function () {
            that.setCookieSong()
        }, 2000);

        if (this._opation.callback && typeof that._opation.callback == "function") {
            this._opation.callback()
        }


    },
    // 微信端自动播放
    initAutoPlay: function () {
        let that = this;
        document.addEventListener('DOMContentLoaded', function () {
            that.goPlayStyle();
            function audioAutoPlay() {
                that.audio.play()
                document.addEventListener("WeixinJSBridgeReady", function () {
                    // 可用数据足以开始播放 if(that.audio.readyState >=4){ alert('readyState=' + readyState) }
                    that.audio.play()
                }, false);

                that.timer = setInterval(
                    function () {
                        that.oTime()
                    }, 1000)
                that.start = false;
                that.autoNext();
            }
            audioAutoPlay();
        });
    },

    //转换为时间格式
    timeDispose: function (number) {
        var minute = parseInt(number / 60);
        var second = parseInt(number % 60);
        minute = minute >= 10 ? minute : "0" + minute;
        second = second >= 10 ? second : "0" + second;
        return minute + ":" + second;
    },

    //播放时间
    oTime: function () {
        // if(this.audio.readyState >=4){  }  // 可用数据足以开始播放
        var currentProgress = Math.round(this.audio.currentTime / this.audio.duration * parseInt(this.progressWrap.css("width")));
        this.progress.css("width", currentProgress + "px");
        this.allTimeNode.html(this.timeDispose(this.audio.duration));
        this.currentTimeNode.html(this.timeDispose(this.audio.currentTime));
    },

    //播放进度选择
    selectTime: function (event) {
        var moveTo = event.pageX - this.progressWrap.offset().left;
        this.audio.currentTime = moveTo / parseInt(this.progressWrap.css("width")) * this.audio.duration;
        this.progress.css("width", moveTo + "px");
        this.currentTimeNode.html(this.timeDispose(this.audio.currentTime));
    },
    // 主控
    mainControl: function () {
        function pp(a) {
            if (a.start) {
                a.goPlay();
            } else {
                a.goPause();
            }
        }
        setTimeout(pp(this), 500);
    },
    // 监听播放完毕后 自动播放下一曲
    autoNext: function () {
        let that = this
        this.audio.addEventListener('waiting', function () {
            that.allTimeNode.html('加载中...');
        }, false);

        this.audio.addEventListener('ended', function () {
            console.log('自动下一曲')
            that.restTime()
            that.goPause()
            var nextUrl = $("#nextButton").attr("href");
            console.log(nextUrl)
            that.audio.src= nextUrl;
            that.goPlay();
        }, false);
    },
    restTime: function () {
        let that = this;
        let ua = window.navigator.userAgent.toLowerCase();
        if (ua.match(/MicroMessenger/i) == 'micromessenger') {
            that.audio.addEventListener('canplay', function () {
                that.audio.currentTime = 0;
            }, false);
        } else {
            that.audio.currentTime = 0;
        }
        $.cookie('songTime', 0, { path: '/' });
    },
    // 每隔2s记录 当前播放地址,时间
    setCookieSong: function () {
        var mediaUrl = this.audio.currentSrc;
        var mediaTime = this.audio.currentTime;
        $.cookie('mediaUrl', mediaUrl, { path: '/' });
        $.cookie('mediaTime', mediaTime, { path: '/' });
    },
    // 切换页面 接着播放
    pagePlay: function () {
        let that = this;
        var mediaUrlPage = $.cookie('mediaUrl');
        var mediaTimePage = $.cookie('mediaTime');
        if (mediaTimePage && mediaTimePage != that.audio.duration) {
            mediaTimePage = parseFloat(mediaTimePage)
        } else {
            mediaTimePage = 0;
        }
        console.log('mediaTime=' + mediaTimePage)
        console.log('mediaUrl=' + mediaUrlPage);
        if (mediaUrlPage) {
            this.audio.currentSrc = mediaUrlPage;
            let ua = window.navigator.userAgent.toLowerCase();
            if (ua.match(/MicroMessenger/i) == 'micromessenger') {
                that.audio.addEventListener('canplay', function () {
                    that.audio.currentTime = mediaTimePage;
                }, false);
            } else {
                that.audio.currentTime = mediaTimePage;
            }
        }
    },
    // 倍数播放1.0  1.5 2.0
    setPlaySpeed: function () {
        let that = this;
        var speed = $.cookie('playSpeed');
        speed = speed ? parseFloat(speed) : 1;
        console.log(speed)
        this.audio.playbackRate = speed;
        that.speedStyle($('#playSpeed'), speed);
        // 修改  1-speed10 1.5-speed15  2-speed20
        $('#playSpeed').click(function () {
            let $this = $(this)
            $(this).removeAttr('class')
            speed += 0.5;
            if (speed > 2) { speed = 1; }
            that.speedStyle($this, speed);
            that.audio.playbackRate = speed;
            $.cookie('playSpeed', speed, { path: '/' });
        })
    },
    // 倍数播放控制按钮
    speedStyle: function ($this, spd) {
        $this.find('span').text(spd + '倍数')
        $this.removeAttr('class').attr('class', 'speed' + spd * 10)
    },


    //播放
    goPlay: function () {
        this.audio.play();
        var _this = this;
        this.goPlayStyle();
        this.timer = setInterval(function () { _this.oTime() }, 1000)
        this.start = false;
        this.autoNext();
        thisTime = new Date();
        starttime = thisTime.getFullYear() + "" + (thisTime.getMonth() > 8 ? '' : '0') + (thisTime.getMonth() + 1) + "" + (thisTime.getDate() > 9 ? '' : '0') + thisTime.getDate() + (thisTime.getHours() > 9 ? '' : '0') + thisTime.getHours() + (thisTime.getMinutes() > 9 ? '' : '0') + thisTime.getMinutes() + (thisTime.getSeconds() > 9 ? '' : '0') + thisTime.getSeconds();

    },

    //暂停
    goPause: function () {
        this.audio.pause();
        this.goPauseStyle();
        clearInterval(this.timer);
        this.start = true;
    },

    //播放样式
    goPlayStyle: function () {
        this.playBtn.addClass("pause");
        this.playBtn.removeClass("play");
        $("#progress").show();

    },

    //暂停样式
    goPauseStyle: function () {
        this.playBtn.addClass("play");
        this.playBtn.removeClass("pause");
    },

}

页面样式 style.css

css

/* 页面样式 */
html,
body {
    height: auto;
    min-height: 100vh;
    position: relative;
}

/* 头部样式 */
.header {
    width: 100%;
    height: 1.2rem;
    overflow: hidden;
    position: relative;
    /* position: fixed; */
    /* position: absolute;
    top: 0;
    left: 0;
    z-index: 500; */
}

.header .head-left {
    height: 1.2rem;
    position: absolute;
    top: 0;
    left: 0.47rem;
    z-index: 8;
}

.header .head-left a {
    display: block;
    height: 100%;
    overflow: hidden;
    cursor: pointer;
}

.header .head-middle {
    width: 100%;
    height: 1.2rem;
}

.header .head-right {
    height: 1.2rem;
    position: absolute;
    top: 0;
    right: 0.47rem;
    z-index: 8;
}

.header .head-right .headRightBox {
    width: auto;
    height: 1.2rem;
}

.header .head-right .headRightBox a {
    height: 100%;
    overflow: hidden;
    text-align: right;
    padding-right: 0.03rem;
    display: block;
    float: left;
    font-size: 0;
}

.header .head-right .headRightBox a img {
    display: block;
    width: 0.48rem;
    height: 0.48rem;
    margin: auto;
}

.pageHead .head-left a {
    text-align: left;
    padding-top: 0.39rem;
    font-size: 0;
}

.pageHead .head-left a img {
    height: 0.43rem;
}

.pageHead .head-middle {
    padding: 0 1.53rem 0;
}

.pageHead .head-middle p {
    text-align: center;
    font-size: 0.48rem;
    line-height: 1.2rem;
    height: 1.2rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: bold;
}

.pageHead .head-middle p i {
    font-size: 0.4rem;
    color: #BFBDB8;
}

.pageHead .head-right .headRightBox a {
    width: 0.8rem;
    background: url('../img/menu.png') no-repeat center;
    background-size: 0.48rem 0.48rem;
}

.wHeadBg {
    background-color: #fff;
    /* 白色底 */
    box-shadow: 0 0 .2rem #e8ecf0;
    -moz-box-shadow: 0 0 .2rem #e8ecf0;
    -webkit-box-shadow: 0 0 .2rem #e8ecf0;
    color: #221802;
}

.nHeadBg {
    background-color: transparent;
    color: #FFF;
    border-bottom: 1px solid #fff;
    /* 透明底 */
}



.fixAudio {
    width: 2rem;
    height: 1.8rem;
    position: fixed;
    right: 0.27rem;
    bottom: 3.2rem;
    z-index: 500;
  }
  .fixAudio p {
    display: block;
    width: 0.8rem;
    height: 0.8rem;
    font-size: 0.38rem;
    color: #fff;
    position: absolute;
    right: 0;
    top: 0;
    border-radius: 50%;
    border: 2px solid #fff;
    z-index: 10;
    text-align: center;
    line-height: calc(0.8rem - 4px);
    background-color: red;
    /* 不支持线性的时候显示 */
    background-image: linear-gradient(#ee9c9c, #df7979, #F53F3F);
    box-shadow: 0 0 0.13rem #8c8c8f;
    -moz-box-shadow: 0 0 0.13rem #8c8c8f;
    -webkit-box-shadow: 0 0 0.13rem #8c8c8f;
  }
  .fixAudio img {
    width: 1.6rem;
    height: 1.6rem;
    position: absolute;
    left: 0.25rem;
    top: 0.1rem;
    border-radius: 50%;
    border: 2px solid #fff;
    box-shadow: 0 0 0.13rem #8c8c8f;
    -moz-box-shadow: 0 0 0.13rem #8c8c8f;
    -webkit-box-shadow: 0 0 0.13rem #8c8c8f;
  }


/* ---------------------------------------------------------------- */

/* 磨砂背景 */
.blur {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
}
.blur img {
    width: 100%;
    height: 100%;
    -webkit-filter: blur(20px);
    -moz-filter: blur(20px);
    -ms-filter: blur(20px);
    filter: blur(20px);
    position: absolute;
}
.blur::after{
    content:'';
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    overflow: hidden;
    background-color: #000;
    opacity: 0.3;
    z-index: 2;
}

/* --------------------------- 正文样式   ------------------------------------ */

.audiosWrap {
    width: 100%;
    height: auto;
    min-height: 100vh;
    background-color: #fff;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 10;
}
.fixLayer{
    position: fixed;
    z-index: 100000;
    top: 100vh;
}

.slideOut{
    animation:slideOut 0.5s  linear forwards ;
    -webkit-animation:slideOut 0.5s linear forwards ; /* Safari 和 Chrome */
}
@keyframes slideOut {
    from { top: 0; } to { top: 100vh; }
}
@-webkit-keyframes slideOut{
    from { top: 0; } to { top: 100vh; }
}
.slideIn{
    animation:slideIn 0.5s  linear forwards ;
    -webkit-animation:slideIn 0.5s linear forwards ; /* Safari 和 Chrome */
}
@keyframes slideIn {
    from { top: 100vh; } to {top: 0;}
}
@-webkit-keyframes slideIn{
    from { top: 100vh; } to {top: 0;}
}
/* --------------------------------------------------------------- */

.cdText{

}
.cdText p{
    height: .67rem;
    padding: .4rem;
    font-size: .32rem;
    color: #999;
    text-align: center;
    position: relative;
    z-index: 10;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ---------------------------------------------------------------- */

/* 封面 */
.cdBox {
    position: relative;
    margin: 1.07rem auto;
}
.coverBox {

}
.coverBox img {
    width: 6.4rem;
    height: 6.4rem;
    display: block;
    margin: auto;
    border-radius: 50%;
    box-shadow: #807D7D 0px 0.03rem 0.16rem;
    -webkit-box-shadow: #807D7D 0 0.03rem 0.16rem;
    -moz-box-shadow: #807D7D 0px 0.03rem 0.16rem;
}

页面样式 audio.css

css

/* 播放器样式 */
*{
    font-family:'PingFang-SC-Bold' ;
    margin:0;
    padding: 0;
    -moz-box-sizing: border-box;  
    -webkit-box-sizing: border-box; 
    -o-box-sizing: border-box; 
    -ms-box-sizing: border-box; 
    box-sizing: border-box; 
    -webkit-overflow-scrolling: touch;
    list-style: none;
  }
a{ text-decoration: none;}
.controlBox{

}

#playContent{
    width: 100%;
    z-index: 50;
    overflow: hidden;
    text-align: center;
    min-height: 1.5rem;
}
.timeBox{ 
    overflow: hidden;
    margin-top: .27rem;
}

#currentTime { 
    font-size: .32rem;
    color: #B3B3B3;
    /* display: inline-block;
    vertical-align: middle; */
    /* margin-left: 0.16rem; */
    float: left;
}
#totleTime {
    font-size: .32rem;
    color: #B3B3B3;
    /* display: inline-block;
    vertical-align: middle; */
    /* margin-right: 0.16rem; */
    float: right;
}
#progressWrap{    
    width: 7.2rem;
    height: .12rem;
    border-radius: .09rem;
    background-color:#E6E6E6;
    position: relative;
    display: inline-block;
    vertical-align: middle;
}

#progress{
    background: #F2AC17;
    height: .12rem;
    position: absolute;
    width: 0;
    top: 0;
    left: 0;
    display: none;
}

#progress:after{
    content: "";
    position: absolute;
    width: .24rem;
    background: #F2AC17;
    height: .24rem;
    top: -0.06rem;
    right: -0.24rem;
    border-radius: 50%;
}



.controlBox ul{
    width: 7.2rem;
    overflow: hidden;
    position: relative;
    z-index: 55;
    margin: .2rem auto ;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.controlBox ul li a{
    display: block;
    margin: auto;
}
.controlBox ul li.small{
    width: 1.33rem;
    height: 1.33rem;
}
.controlBox ul li.small a{
    width: 1.33rem;
    height: 1.33rem;
    border-radius: 50%;
}
.controlBox a.next{
    background:url(../img/next.png) no-repeat 50%;
    background-size: 1.33rem 1.33rem;
}
.controlBox a.prev{
    background:url(../img/pre.png) no-repeat center;
    background-size: 1.33rem 1.33rem;
} 


.controlBox ul li.playbg{
    width: 1.81rem;
    height: 1.81rem;
}
.controlBox ul li.playbg a{
    width: 1.81rem;
    height: 1.81rem;
    border-radius: 50%;
}

.controlBox a.play{
    background:url(../img/pause.png) no-repeat center;
    background-size: 1.81rem 1.81rem;
}

.controlBox a.pause{
    background:url(../img/play.png) no-repeat center;   
    background-size: 1.81rem 1.81rem;
}



.controlBox ol{
    width: 7.2rem;
    overflow: hidden;
    position: relative;
    z-index: 55;
    margin: .93rem auto  0;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.controlBox ol li a{
    min-width: 1.33rem;
    display: block;
    text-align: center;
}
.controlBox ol li a i{
    display: block;
    height: .53rem;
    margin: 0 auto;
}
.controlBox ol li a span{
    display: block;
    color: #999999;
    font-size: .32rem;
}

.controlBox ol li.hasCollected i{
    background:url(../img/start.png) no-repeat center;   
    background-size: auto .48rem;
}
.controlBox ol li.hasCollected span{
    color: #F2AC17;
}
.controlBox ol li.noCollected i{
    background:url(../img/start0.png) no-repeat center;   
    background-size: auto .48rem;
}

.controlBox ol li.speed10 i{
    background:url(../img/1b.png) no-repeat center;   
    background-size: auto .48rem;
}
.controlBox ol li.speed15 i{
    background:url(../img/1.5b.png) no-repeat center;   
    background-size: auto .48rem;
}
.controlBox ol li.speed20 i{
    background:url(../img/2b.png) no-repeat center;   
    background-size: auto .48rem;
}

.controlBox ol li.directory i{
    background:url(../img/ml.png) no-repeat center;   
    background-size: auto .48rem;
}

移动端布局自适应flexible.js

移动端flexible.js, 自适应

;(function(win, lib) {
    var doc = win.document;
    var docEl = doc.documentElement;
    var metaEl = doc.querySelector('meta[name="viewport"]');
    var flexibleEl = doc.querySelector('meta[name="flexible"]');
    var dpr = 0;
    var scale = 0;
    var tid;
    var flexible = lib.flexible || (lib.flexible = {});

    if (metaEl) {
        console.warn('将根据已有的meta标签来设置缩放比例');
        var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
        if (match) {
            scale = parseFloat(match[1]);
            dpr = parseInt(1 / scale);
        }
    } else if (flexibleEl) {
        var content = flexibleEl.getAttribute('content');
        if (content) {
            var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
            var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
            if (initialDpr) {
                dpr = parseFloat(initialDpr[1]);
                scale = parseFloat((1 / dpr).toFixed(2));    
            }
            if (maximumDpr) {
                dpr = parseFloat(maximumDpr[1]);
                scale = parseFloat((1 / dpr).toFixed(2));    
            }
        }
    }

    if (!dpr && !scale) {
        var isAndroid = win.navigator.appVersion.match(/android/gi);
        var isIPhone = win.navigator.appVersion.match(/iphone/gi);
        var devicePixelRatio = win.devicePixelRatio;
        if (isIPhone) {
            // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
            if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
                dpr = 3;
            } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
                dpr = 2;
            } else {
                dpr = 1;
            }
        } else {
            // 其他设备下,仍旧使用1倍的方案
            dpr = 1;
        }
        scale = 1 / dpr;
    }

    docEl.setAttribute('data-dpr', dpr);
    if (!metaEl) {
        metaEl = doc.createElement('meta');
        metaEl.setAttribute('name', 'viewport');
        metaEl.setAttribute('content', 'initial-scale=' + 1 + ', maximum-scale=' + 1 + ', minimum-scale=' + 1 + ', user-scalable=no');
        if (docEl.firstElementChild) {
            docEl.firstElementChild.appendChild(metaEl);
        } else {
            var wrap = doc.createElement('div');
            wrap.appendChild(metaEl);
            doc.write(wrap.innerHTML);
        }
    }

    function refreshRem(){
        var width = docEl.getBoundingClientRect().width;
        if (width / dpr > 540) {
            width = 540 * dpr;
        }
        var rem = width / 10;
        docEl.style.fontSize = rem + 'px';
        flexible.rem = win.rem = rem;
    }

    win.addEventListener('resize', function() {
        clearTimeout(tid);
        tid = setTimeout(refreshRem, 300);
    }, false);
    win.addEventListener('pageshow', function(e) {
        if (e.persisted) {
            clearTimeout(tid);
            tid = setTimeout(refreshRem, 300);
        }
    }, false);

    if (doc.readyState === 'complete') {
        doc.body.style.fontSize = 12 * dpr + 'px';
    } else {
        doc.addEventListener('DOMContentLoaded', function(e) {
            doc.body.style.fontSize = 12 * dpr + 'px';
        }, false);
    }


    refreshRem();

    flexible.dpr = win.dpr = dpr;
    flexible.refreshRem = refreshRem;
    flexible.rem2px = function(d) {
        var val = parseFloat(d) * this.rem;
        if (typeof d === 'string' && d.match(/rem$/)) {
            val += 'px';
        }
        return val;
    }
    flexible.px2rem = function(d) {
        var val = parseFloat(d) / this.rem;
        if (typeof d === 'string' && d.match(/px$/)) {
            val += 'rem';
        }
        return val;
    }

})(window, window['lib'] || (window['lib'] = {}));

JAVAScript中DOM与BOM的差异分析

JAVAScript中DOM与BOM的差异分析

JAVAScript 有三部分构成,ECMAScript,DOM和BOM,根据浏览器的不同,具体的表现形式也不尽相同。我们今天来谈一谈DOM和BOM这俩者之间的差异。

用百科上的来说:

  1. DOM是 W3C 的标准; [所有浏览器公共遵守的标准]

  2. BOM 是 各个浏览器厂商根据 DOM在各自浏览器上的实现;[表现为不同浏览器定义有差别,实现方式不同]

  3. window 是 BOM 对象,而非 js 对象;

DOM(文档对象模型)是 HTML 和 XML 的应用程序接口(API)。

BOM 主要处理浏览器窗口和框架,不过通常浏览器特定的 JavaScript 扩展都被看做 BOM 的一部分。而这些扩展则包括:

<1>弹出新的浏览器窗口
<2>移动、关闭浏览器窗口以及调整窗口大小
<3>提供 Web 浏览器详细信息的定位对象
<4>提供用户屏幕分辨率详细信息的屏幕对象
<5>对 cookie 的支持
<6>IE 扩展了 BOM,加入了 ActiveXObject 类,可以通过 JavaScript 实例化 ActiveX 对象

javacsript是通过访问BOM(Browser Object Model)对象来访问、控制、修改客户端(浏览器),由于BOM的window包含了document,window对象的属性和方法是直接可以使用而且被感知的,因此可以直接使用window对象的document属性,通过document属性就可以访问、

检索、修改XHTML文档内容与结构。因为document对象又是DOM(Document Object Model)模型的根节点。可以说,BOM包含了DOM(对象),浏览器提供出来给予访问的是BOM对象,从BOM对象再访问到DOM对象,从而js可以操作浏览器以及浏览器读取到的文档。其中

DOM包含:window

1 Window对象包含属性:document、location、navigator、screen、history、frames

2 Document根节点包含子节点:forms、location、anchors、images、links

从window.document已然可以看出,DOM的最根本的对象是BOM的window对象的子对象。而他们之前的最大区别:DOM描述了处理网页内容的方法和接口,BOM描述了与浏览器进行交互的方法和接口。

首先我们来仔细了解一下DOM:

在HTML中DOM的节点层次为:

DOM操作creatElement(element)创建一个新的元素节点creatTextNode()创建一个包含给定文本的新文本节点appendChild()指定节点的最后一个节点列表后添加一个新的子节insertBefore()将一个给定节点插入到一个给定元素节点的给定子节点的前面removeChild()从一

个给定元素中删除子节点replaceChild()把一个给定父元素里的一个子节点替换为另外一个节点,DOM通过创建树来表示文档,描述了处理网页内容的方法和接口,从而使开发者对文档的内容和结构具有空前的控制力,用DOM API可以轻松地删除、添加和替换节点。

访问节点的方法如下:

var oHtml = document.documentElement;//返回存在于 XML 以及 HTML 文档中的文档根节点oHtml包含了一个表示<html />的HTMLElement对象
document.body //是对 HTML 页面的特殊扩展,提供了对 <body> 标签的直接访问
document.getElementById("ID") //通过指定的 ID 来返回元素,getElementById() 无法工作在 XML 中,IE6还会返回name为指定ID的元素
document.getElementByName("name")//获取所有name特性等于指定值的元素,不过在IE6和Opera7.5上还会返回id为给定名称的元素且仅检查<input/>和<img/>
var x=document.getElementsByTagName("p"); //使用指定的标签名返回所有的元素列表NodeList,索引号从0开始。当参数是一个星号的时候,IE6并不返回所有的元素,必须用document.all来替代

获取到节点之后就要对它进行操作,操作的方法我们用事件来实现,事件类型有:

鼠标事件:click、dbclick、mousedown、mouseup、mouseover、mouseout、mousemove 
键盘事件:keydown、keypress、keyup 
HTML事件:load、unload、abort、error、select、change、submit、reset、resize、scroll、focus、blur

下面我们来了解一下BOM:

BOM的核心是window,而window对象又具有双重角色,它既是通过js访问浏览器窗口的一个接口,又是一个Global(全局)对象。这意味着在网页中定义的任何对象,变量和函数,都以window作为其global对象。

window 对象

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
window.close(); //关闭窗口 

window.alert("message"); //弹出一个具有OK按钮的系统消息框,显示指定的文本

window.confirm("Are you sure?"); //弹出一个具有OK和Cancel按钮的询问对话框,返回一个布尔值

window.prompt("What's your name?", "Default"); //提示用户输入信息,接受两个参数,即要显示给用户的文本和文本框中的默认值,将文本框中的值作为函数值返回

window.status //可以使状态栏的文本暂时改变

window.defaultStatus //默认的状态栏信息,可在用户离开当前页面前一直改变文本

window.setTimeout("alert('xxx')", 1000); //设置在指定的毫秒数后执行指定的代码,接受2个参数,要执行的代码和等待的毫秒数

window.clearTimeout("ID"); //取消还未执行的暂停,将暂停ID传递给它

window.setInterval(function, 1000); //无限次地每隔指定的时间段重复一次指定的代码,参数同setTimeout()一样

window.clearInterval("ID"); //取消时间间隔,将间隔ID传递给它

window.history.go(-1); //访问浏览器窗口的历史,负数为后退,正数为前进

window.history.back(); //同上

window.history.forward(); //同上

window.history.length //可以查看历史中的页面数

document对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
document对象:实际上是window对象的属性,document == window.document为true,是唯一一个既属于BOM又属于DOM的对象 

document.lastModified //获取最后一次修改页面的日期的字符串表示

document.referrer //用于跟踪用户从哪里链接过来的

document.title //获取当前页面的标题,可读写

document.URL //获取当前页面的URL,可读写

document.anchors[0]或document.anchors["anchName"] //访问页面中所有的锚

document.forms[0]或document.forms["formName"] //访问页面中所有的表单

document.images[0]或document.images["imgName"] // 访问页面中所有的图像

document.links [0]或document.links["linkName"] //访问页面中所有的链接

document.applets [0]或document.applets["appletName"] //访问页面中所有的Applet

document.embeds [0]或document.embeds["embedName"] //访问页面中所有的嵌入式对象

document.write(); 或document.writeln(); //将字符串插入到调用它们的位置

location对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

location对象:表示载入窗口的URL,也可用window.location引用它

location.href //当前载入页面的完整URL,如http://www.somewhere.com/pictures/index.htm

location.portocol //URL中使用的协议,即双斜杠之前的部分,如http

location.host //服务器的名字,如www.wrox.com

location.hostname //通常等于host,有时会省略前面的www

location.port //URL声明的请求的端口,默认情况下,大多数URL没有端口信息,如8080

location.pathname //URL中主机名后的部分,如/pictures/index.htm

location.search //执行GET请求的URL中的问号后的部分,又称查询字符串,如?param=xxxx

location.hash //如果URL包含#,返回该符号之后的内容,如#anchor1

location.assign("http:www.baidu.com"); //同location.href,新地址都会被加到浏览器的历史栈中

location.replace("http:www.baidu.com"); //同assign(),但新地址不会被加到浏览器的历史栈中,不能通过back和forward访问

location.reload(true | false); //重新载入当前页面,为false时从浏览器缓存中重载,为true时从服务器端重载,默认为false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
navigator对象:包含大量有关Web浏览器的信息,在检测浏览器及操作系统上非常有用,也可用window.navigator引用它 

navigator.appCodeName //浏览器代码名的字符串表示

navigator.appName //官方浏览器名的字符串表示

navigator.appVersion //浏览器版本信息的字符串表示

navigator.cookieEnabled //如果启用cookie返回true,否则返回false

navigator.javaEnabled //如果启用java返回true,否则返回false

navigator.platform //浏览器所在计算机平台的字符串表示

navigator.plugins //安装在浏览器中的插件数组

navigator.taintEnabled //如果启用了数据污点返回true,否则返回false

navigator.userAgent //用户代理头的字符串表示

screen对象

1
2
3
4
5
6
7
8
9
10
11
screen对象:用于获取某些关于用户屏幕的信息,也可用window.screen引用它 

screen.width/height //屏幕的宽度与高度,以像素计

screen.availWidth/availHeight //窗口可以使用的屏幕的宽度和高度,以像素计

screen.colorDepth //用户表示颜色的位数,大多数系统采用32位

window.moveTo(0, 0);

window.resizeTo(screen.availWidth, screen.availHeight); //填充用户的屏幕

window对象方法则有以下这几种:

mahua

BOM和DOM的结构关系示意图:

mahua

window对象思维导图:

mahua

vue.js实战-基础篇

vue.js实战-基础篇

之前曾看过vue.js的官方文档, 看了一些理论知识, 前段时间,自己拿以前的项目来做实践,毕竟纸上得来终觉浅嘛, 不过,由于由于时间关系,做的实例不多,刚学习vue的同学可以看看。后续自己还会深入的去学习,陆续补上。欢迎大神们来指正以及给予辅导。

项目目录

Alt text

注意知识点:

  1. vue 做移动端 , meta 直接写在index.html 的head 里

    Index.html
    <meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no">
    
  2. v-for 的使用

    #####VUE1.0:

    li v-for="(index,item) in items" v-on:click="onclick($index)"></li>
    

    #####VUE2.0 $index 已弃用:

    <p v-for="(item,index) in tabs" v-on:click="tabsShow(index)">{{item.tabname}}</p>
    

    (参数一为key值 , 参数二为索引值)

3.组件命名时,不要用html元素如 head footer nav …..等命名。

  1. 每个页面公用的头部和尾部直接写在app.vue 中:
    Alt text

    注意:其他的组件页面最外层的容器不要设置高度。

一 less 安装使用

安装less依赖

npm install less less-loader –save

修改 webpack.base.conf.js 文件,配置loader加载依赖,让其支持外部的less,在原来的代码上添加

{
    test: /\.less$/,
    loader: 'style-loader!css-loader!less-loader'
  },

引入:

<style lang="sass">
 @import "/style/base.scss";(此处分号不可省)
</style>

二 swiper 使用

在static 中引入 swiper [
Swiper.min.css
Swiper.min.js
]

在 .eslintrc.js 中 配置swiper :

'globals': {
  'Swiper': true
}

组件:

<template>
       <div class="swiper-container">
          <div class="swiper-wrapper">

            <div class="swiper-slide" v-for="item in listImg">
              <img class="imgload" :src='item.url' alt="首页banner图片01">
            </div>
          </div>
          <!-- 如果需要分页器 -->
          <div class="swiper-pagination"></div>

          <!-- 如果需要导航按钮 -->

    </div>
</template>
<script>
import '../../../static/swiper/swiper.min.css'
import '../../../static/swiper/swiper.min.js'
export default {
  props: ['listImg'],
  name: 'swiper',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },
  mounted () {
    var swiper = new Swiper('.swiper-container', {
      pagination: '.swiper-pagination',
      paginationClickable: true,
      loop: true,
      speed: 600,
      autoplay: 1000,
      onTouchEnd: function () {
        swiper.startAutoplay()
      }
    })
  }
}
</script>

<style scoped lang="less">
.swiper-container {
    width: 100%;
    height:208px;
    background-color:red;
    .swiper-wrapper {
        width: 100%;
        height: 100%;
    }
    .swiper-slide {
        background-position: center;
        background-size: cover;
        width: 100%;
        height: 100%;
        img {
            width: 100%;
            height: 100%;
        }
    }
    .swiper-pagination-bullet {
        width:20px;
        height:20px;
        background-color:blue;
        display: inline-block;
        background: #7c5e53;
    }
}

</style>

构建项目时安装vue-router(会自动在项目中创建router文件,推荐使用) , 或者 在项目中通过 cnpm install vue-touter –save 来安装。

  1. 使用第一种方法自动安装时 router下的 xx.js 配置:

    import Vue from 'vue'
    import Router from 'vue-router'
    // 引入路由对应的组件
    import Index from '@/components/index'
    import Detail from '@/components/detail'
    // 全局使用路由
    Vue.use(Router)
    // 实例化路由并且暴露
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'Index',
          component: Index
        },
        {
          path: '/detail',
          name: 'Detail',
          component: Detail
        }
      ]
    })  
    
  2. 在main.js 中将路由 挂载在 入口上,供全局使用
    Alt text

3 组件中使用router-link to=”xxxx” 实现跳转(等同于a href=”xxx”)
Alt text

Alt text

四 tab选项卡

html:

<div  class="tabs" >
  <p v-for="(item,index) in tabs" v-on:click="tabsShow(index)" :class="{active:item.iscur}">{{item.tabname}}</p>
</div>
<div class="tabItems">   
 // 挂载当前显示的默认项
  <component :is='currentView' keep-alive></component>
</div>

Js :

export default {
      name: 'Index',
      data () {
        return {
          tabs: [
            {tabname: '男生', iscur: true, nowShow: 'list'},
            {tabname: '女生', iscur: false, nowShow: 'detail'}
          ],
          currentView: 'list'
        }
      },
      components: {
        'banner': Banner,
        'detail': Detail,
        'list': List
      },
      methods: {
        tabsShow: function (indexs) {
          var x = this
          this.tabs.map(function (v, i) {
            if (i === indexs) {
              v.iscur = true
              x.currentView = v.nowShow
            } else {
              v.iscur = false
            }
          })
       }
     }
}

五 相同组件绑定不同数据

例如:同一个swiper组件 ,在不同的父级组件下展示不同的图片源
Alt text
Alt text

主页 三组数据:
Alt text

在子组件上绑定数据,供子组件直接使用, 需要用什么数据就绑定什么数据(实际具体数据通过请求接口,此处为示例)
Alt text

在子组件中通过prop 继承父级Data
Alt text

在公共组件swiper 中 使用逻辑运算符即可:
Alt text

六 使用vuex 来存储数据 供全局使用

1 安装 npm install vuex –save
2 在 src 下 建一个store.js 文件
3 引入 vue vuex
Alt text

4 在需要使用数据的 .vue 中 data取出
Alt text

Alt text

七 使用公用的js 内的方法

例如在index.vue 中使用common.js中的init方法 :
Alt text

1 写入的方法 用 export暴露出来否则会报错(需要注意)
Alt text

2 在需要的文件中引入 { 方法 } 并且在method 中注入

Alt text

八 img 图片绑定路径问题

1 本地图片直接使用相对路径。
2 动态图片 v-bind:src=””
3 固定的图片属于静态文件。放置于static . 直接./static/…png 就可获取

今天的分享就到此了, 下次再继续深入。

版权声明: 本博客内容由本人自己所著。转载请注明出处!

React-Native学习指南

React-Native学习指南

最近在自学React-Native。在网上发现别人整理了一份针对学的React-Native的网站网址,觉得还挺有用的,就收藏了,顺便分享一下。

更详细的可参考 http://www.w3ctech.com/topic/909

教程

react-native 官方api文档 http://facebook.github.io/react-native/docs/getting-started.html

react-native 中文api文档 (翻译中) https://github.com/ecomfe/react-native-cn

react.js中文文档 http://reactjs.cn/

react.js入门教程(gitbook) http://hulufei.gitbooks.io/react-tutorial/content/introduction.html

react.js快速入门教程 - 阮一峰 http://www.ruanyifeng.com/blog/2015/03/react.html

react.js视频教程 http://react.nodejs-china.org/t/reactjszhong-wen-shi-pin-jiao-cheng-bai-du-wang-pan/584

react-native第一课 http://html-js.com/article/2783

深入浅出 React Native:使用 JavaScript 构建原生应用 http://zhuanlan.zhihu.com/FrontendMagazine/19996445

React Native通信机制详解 http://blog.cnbang.net/tech/2698/

React Native布局篇 http://segmentfault.com/a/1190000002658374

React Native 基础练习指北(一)

React Native 基础练习指北(二) http://segmentfault.com/a/1190000002647733

构建一个简单的列表页和2页导航 http://www.xn–cnq920ntha.cn/archives/235#6838470-tsina-1-17436-6a377b1a66595f9ede646cf5c012734c

Diary of Building an iOS App with React Native http://herman.asia/building-a-flashcard-app-with-react-native

Use React Native in Existing iOS App http://blog-en.leapoahead.com/post/use-react-native-in-existing-ios-app

tcomb-form-native使用视频教程(需翻墙) http://react.rocks/example/tcomb-form-native

开源APP

研究源码也是一个很好的学习方式

官方演示 App https://github.com/facebook/react-native/tree/master/Examples

ReactNativeRubyChina https://github.com/henter/ReactNativeRubyChina

HackerNews-React-Native https://github.com/iSimar/HackerNews-React-Native

React-Native新闻客户端 https://github.com/tabalt/ReactNativeNews

newswatch(新闻客户端) https://github.com/bradoyler/newswatch-react-native

buyscreen(购买页面) https://github.com/appintheair/react-native-buyscreen

V2EX客户端 https://github.com/samuel1112/v2er

react-native-todo

react-native-beer https://github.com/muratsu/react-native-beer

react-native-stars https://github.com/86/react-native-stars

模仿天猫首页的app https://github.com/baofen14787/react-native-demo

ReactNativeChess https://github.com/csarsam/ReactNativeChess

react native 编写的音乐软件 https://github.com/Johnqing/miumiu

react-native-pokedex https://github.com/ababol/react-native-pokedex

CNode-React-Native https://github.com/SFantasy/CNode-React-Native

8tracks电台客户端 https://github.com/voronianski/EightTracksReactNative

React-Native实现的计算器 https://github.com/yoxisem544/Calculator-using-React-Native

房产搜索app https://github.com/jawee/react-native-PropertyFinder

知乎专栏app https://github.com/LeezQ/react-native-zhihu-app

ForeignExchangeApp https://github.com/peralmq/ForeignExchangeApp

工具

react-native-snippets(代码提示) https://github.com/Shrugs/react-native-snippets

react-native-babel(使用ES6+) https://github.com/roman01la/react-native-babel

资源网站

React-native官网 http://facebook.github.io/react-native/

React-China社区 http://react-china.org/

React-native组件库(比较全的组件库) http://react.parts/

React Native Modules http://reactnativemodules.com/

11款React Native开源移动 UI 组件 http://www.oschina.net/news/61214/11-react-native-ui-components

业界讨论

谈谈 React Native - 唐巧 http://blog.devtang.com/blog/2015/02/01/talk-about-react-native/

如何评价React-Native? http://www.zhihu.com/question/27852694/answer/43990708

React Native概述:背景、规划和风险 http://div.io/topic/938

Mongoose基础篇

Mongoose基础篇

MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统

MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。

MongoDB 下载

你可以在mongodb官网下载该安装包,地址为 http://www.mongodb.org/downloads

Schema 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力

ModelSchema发布生成的模型,具有抽象属性和行为的数据库操作对

EntityModel创建的实体,他的操作也会影响数据库

SchemaModelEntity的关系 :
Schema生成ModeModel创造EntityModelEntity都可对数据库操作造成影响,但ModelEntity`更具操作性。

MongoDB 使用

1.首先你必须安装MongoDB和NodeJS

2.在项目只能够创建一个数据库连接,如下:

var mongoose = require('mongoose');    //引用mongoose模块
var db = mongoose.createConnection('localhost','test'); //    创建一个数据库连接

3.打开本机localhost的test数据库时,我们可以监测

4.在工作文档中定义一个Schema

var userSchema=new mongoose.Schema({
username:String,
password:String,
email:String,
});

schemas中的数据类型有以下几种:

  • String

  • Number

  • Date

  • Boolean

  • Buffer

  • ObjectId

  • Mixed

  • Array

特别需要说明一下ObjectId类型和Mixed类型以及Array类型,在schemas中声明这几

种类型的方式如下:

ObjectId就类似于唯一键值

projectSchema.add({

owner: mongoose.Schema.Types.ObjectId
})

//混合类型,顾名思义,就是说里面可以放置任意类型的数据,有两种方式创建该类型数据

//方式一:直接赋予一个空的字面量对象
vardjSchema= new mongoose.Schema({
mixedUp: {}
});

//方式二:根据Schemas.Types中值来赋予
vardjSchema= new mongoose.Schema({
mixedUp: Schema.Types.Mixed
});

//Array类型数据有两种创建方式,一种是简单数组创建:
var userSchema = new mongoose.Schema({
name: String,
emailAddresses: [String]
});

//第二种方式就是复杂类型数据数组,例如我们可以再数组中添加不同类型的schemas:

 var emailSchema = new mongoose.Schema({
 email: String,
 verified: Boolean
});
 var userSchema = new mongoose.Schema({
 name: String,
 emailAddresses: [emailSchema]
 });
 //注意:如果定义一个空的数据的话,则会创建为一个混合类型数据的数组:
 var emailSchema = new mongoose.Schema({
 email: String,
 verified: Boolean
 });
 var userSchema = new mongoose.Schema({
 name: String,
 emailAddresses: [emailSchema]
 });

5 将Schema发布为Model,并且输出

module.exports={
users:mongoose.model('users',userSchema,'users')
}

// model后的参数 第一个users是模型model的名字,可以随便取名

// 参数二是产出model的Schema名,和上面的要对应,

// 参数3是数据库下的集合名称,可以随意取

6.我们甚至可以为此Schema创建方法

//为Schema模型追加speak方法
PersonSchema.methos.speak = function(){
 console.log('我的名字叫'+this.name);
}
var PersonModel = db.model('Person',PersonSchema);
var personEntity = new PersonModel({name:'Krouky'});
personEntity.speak();//我的名字叫Krouky

7 如果要执行查询,需要依赖Model,当然Entity也是可以做到的

 PersonModel.find(function(err,persons){
  //查询到的所有person
});

查找数据和读取数据的方法

查询的方式

通常有2种查询方式,一种是直接查询,一种是链式查询(2种查询都是自己命名的)
直接查询 在查询时带有回调函数的,称之为直接查询,查询的条件往往通过API来设定,例如:

PersonModel.findOne({'name.last':'dragon'},'some     select',function(err,person){
  //如果err==null,则person就能取到数据
});

链式查询 在查询时候,不带回调,而查询条件通过API函数来制定,例如:

var query = PersonModel.findOne({'name.last':'dragon'});
query.select('some select');
query.exec(function(err,pserson){
//如果err==null,则person就能取到数据
  });
  这种方式相对直接查询,分的比较明细,如果不带callback,则返回query,query    没有执行的预编译查询语句,该query对象执行的方法都将返回自己,只有在执行    exec方法时才执行查询,而且必须有回调。    
更新数据

有三种方式来更新数据:

(1)update(conditions,update,options,callback);

该方法会匹配到所查找的内容进行更新,不会返回数据;

(2)findOneAndUpdate(conditions,update,options,callback);

该方法会根据查找去更新数据库,另外也会返回查找到的并未改变的数据;

(3)findByIdAndUpdate(conditions,update,options,callback);

该方法跟上面的findOneAndUpdate方法功能一样,不过他是根据ID来查找文档并更新的。

三个方法都包含四个参数,一下稍微说明一下几个参数的意思:

conditions:查询条件

update:更新的数据对象,是一个包含键值对的对象

options:是一个声明操作类型的选项,这个参数在下面再详细介绍

callback:回调函数

对于options参数,在update方法中和findOneAndUpdate、findByIdAndUpdate

两个方法中的可选设置是不同的;

//在update方法中,options的可选设置为:

{

safe:true|false, //声明是否返回错误信息,默认true

upsert:false|true, //声明如果查询不到需要更新的数据项,是否需要新插入一

条记录,默认false

multi:false|true, //声明是否可以同时更新多条记录,默认false

strict:true|false //声明更新的数据中是否可以包含在schema定义之外的字段

数据,默认true

}

//对于findOneAndUpdate、findByIdAndUpdate这两个方法,他们的options可

选设置项为:

{

new:true|false, //声明返回的数据时更新后的该是更新前的,如果为true则返回

更新后的,默认true

upsert:false|trure,

sort:javascriptObject, //如果查询返回多个文档记录,则可以进行排序,在这

里是根据传入的javascript object对象进行排序

select:String //这里声明要返回的字段,值是一个字符串

}

数据删除

跟更新数据一样,也有三种方法给我们删除数据:

remove();

findOneAndRemove();

findByIdAndRemove();

数据验证

mongoose内置数据验证

在mongoose中,数据验证这一层是放在schema中的,mongoose已经帮我们做了很多内

置的数据验证,有一些验证是针对某些数据类型的,也有一些是针对所有数据类型的。

能够作用在所有数据类型上的验证有require,意思就是该字段是否是必须的,例如:

email: { type: String, unique: true, required: true }

上面的代码就定义了一个email是必须的schema.

  • Copyrights © 2015-2021 魏姣
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信