• 00-Web难点



    typora-copy-images-to: media

    Web学习路线

    1. HTML
    2. CSS
    3. Javascript
      • ECMAScript
      • BOM
      • DOM
    4. jQuery
    5. Ajax
    6. H5
      • Canvas
    7. CSS3
    8. 移动Web
    9. UI框架
      • Bootstrap
      • MUI
    10. 模板引擎
    • art-template
    • ejs
    • swig
    1. ES6
    2. Git
    3. Node
      • 原生 - Node
      • 框架 - Express
    4. 数据库
      • Mongodb
        • 原生 - mongodb
        • 框架 - mongoose
      • MySQL
    5. 框架
      • Vue
        • Webpack
      • React
      • Angular
    6. 微信小程序

    HTML

    [TODO] 统一target设置

    	<head>
    <base target="_blank">
    	</head> 
    

    CSS

    CSS 初始化样式

    body,h1,h2,h3,h4,h5,h6,p,dl,dd,ul,ol,li,form,input,textarea,th,td,select,div,section,nav,span,i { margin: 0; padding: 0; box-sizing: border-box; }
    em { font-style: normal; }
    li { list-style: none; }
    a { text-decoration: none; }
    img { border: none; vertical-align: top; }
    /* img { font-size: 0; } */
    input,textarea { outline: none; }
    textarea { resize: none; overflow: auto; }
    body { font-family: 'Microsoft YaHei','宋体',Arial; font-size: 12px; }
    

    CSS 公共样式

    /* 浮动 */
    .fl { float: left; }
    .fr { float: right; }
    
    /* 清除浮动:在有浮动的父容器中添加 */
    .clear { zoom: 1; }
    .clear:after { content:''; display: block; clear: both; }
    
    /* 页面居中 */
    .center { margin: 0 auto; }
    
    /* 三角形 */
    .triangle_up,.triangle_down {
         0;
        height: 0;
        overflow: hidden;
        border-left: 4px solid transparent;
        border-right: 4px solid transparent;
        /*下面部分兼容IE6*/
        _border-left: 4px solid #fff;
        _border-right: 4px solid #fff;
    }
    .triangle_up {
        border-bottom: 4px solid red;
    }
    .triangle_down {
        border-top: 4px solid red;
    }
    

    字体图标初始化

    @font-face {
        font-family: "wjs";
        src: 
            url(../fonts/MiFie-Web-Font.svg) format('svg'),
            url(../fonts/MiFie-Web-Font.eot) format('embeded-opentype'),
            url(../fonts/MiFie-Web-Font.ttf) format('truetype'),
            url(../fonts/MiFie-Web-Font.woff) format('woff');
    }
    .wjs-icon {
        font-family: "wjs";
    }
    .wjs-icon-phone::before{
        content: "e908";
    }
    .wjs-icon-tel::before{
        content: "e909";
    }
    ...
    
    // 调用
    <i class="wjs-icon wjs-icon-phone"></i>
    

    banner背景图随窗口调整始终居中

    .box {
        height: 300px;
         100%;
    background: url(wjs/images/slide_01_2000x410.jpg) no-repeat center / cover;
    }
    /* 或者 */
    .box {
        height: 300px;
         100%;
        background: url(wjs/images/slide_01_2000x410.jpg) no-repeat;
    background-position: center;
    background-size: cover;
    }
    
    <div class="box"></div>
    

    CSS3 实现渐变-兼容IE78

    .grandient {
        background: -moz-linear-grandient(left top,#颜色1,#颜色2);
        background: -webkit-linear-grandient(left top,#颜色1,#颜色2);
        background: -ms-linear-grandient(left top,#颜色1,#颜色2);
    background: linear-grandient(left top,#颜色1,#颜色2);
        -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType=0,starColorstr=#颜色1,endColorstr=#颜色2)";
        background: #颜色3;
    }
    

    CSS实现三角形-兼容IE6

    .triangle {
         0;
        height: 0;
        overflow: hidden;
        border-left: 4px solid transparent;
        border-right: 4px solid transparent;
        border-bottom: 4px solid red;
        /*下面部分兼容IE6*/
        _border-left: 4px solid #fff;
        _border-right: 4px solid #fff;
    }
    

    JavaScript

    兼容

    HTML对象获取问题-兼容

    	// FireFox
    	document.getElementById("idName");
    	// IE
    	document.idname 或者 document.getElementById("idName");
    // 解决办法:统一使用 
    document.getElementById("idName");
    

    const问题-兼容

    • FireFox:可以使用const关键字或var关键字来定义常量;

    • IE:只能使用var关键字来定义常量.

    • 解决办法:统一使用var关键字来定义常量.

    event.x,event.y与event.pageX,event.pageY问题-兼容

    • FireFox:event对象有pageX,pageY属性,但是没有x,y属性.

    • IE:event对象有x,y属性,但是没有pageX,pageY属性;

    • 解决办法:使用mX(mX = event.x ? event.x : event.pageX)来代替IE下的event.x或者Firefox下的event.pageX

    window.location.href问题-兼容

    • IE/Firefox2.0.x:可以使用window.locationwindow.location.href

    • Firefox1.5.x:只能使用window.location

    • 解决办法:使用window.location来代替window.location.href

    document.formName.item('itemName')-兼容

    • IE: document.formName.item(”itemName”)document.formName.elements ["elementName"]

    • FireFox:只能使用document.formName.elements["elementName"]

    • 解决办法:统一使用document.formName.elements["elementName"]

    innerText在IE中能正常工作,在Firefox中却不行

    需要使用textContent

    // 解决办法
    if(navigator.appName.indexOf("Explorer") > -1){
    	document.getElementById('element').innerText = "my text";	// IE
    }else{
    	document.getElementById('element').textContent = "my text";	// 非IE
    }
    

    FF和IE,width由于Box模型解释不一致导致相差2px

    问题

    box.style{ 100; border 1px; }
    // IE:box.width = 100
    // FF:box.width = 100 + 1*2 = 102
    

    解决办法

    div{margin:30px!important;margin:28px;}
    

    注意这两个margin的顺序一定不能写反,IE不能识别!important这个属性,但别的浏览器可以识别。所以在IE下其实解释成这样:div{margin:30px;margin:28px}
    重复定义的话按照最后一个来执行,所以不可以只写margin:XXpx!important;

    min-width在IE下不识别

    #container{ 
    	min- 600px; 
    	expression(document.body.clientWidth< 600? "600px": "auto" );
    }
    

    第一个min-width是正常的;但第2行的width使用了Javascript,这只有IE才认得,这也会让你的HTML文档不太正规。它实际上通过Javascript的判断来实现最小宽度。

    对齐文本和文本输入框

    /* 使用vertical-align: middle | top */
    input {
    	200px;
    	height:30px;
    	border:1px solid red;
    	vertical-align:middle;
    }
    

    png图片透明-兼容IE6

    <!--[if IE 6]>
    <script src="js/DD_belatedPNG_0.0.8a.js"></script>
    <script>
    DD_belatedPNG.fix('*');
    </script>
    <![endif]-->
    

    DD_belatedPNG_0.0.8a.js

    JS中变量严格大小写

    // Js中变量严格大小写
    var num = 1;
    var NUM = 2;
    console.log(num);   // 1
    console.log(NUM);   // 2
    

    数组

    indexOf()中参数必须是严格数据类型

    // indexOf()中的参数必须是严格数据类型
    var arr = [5,6,7,2,4,11,9];
    console.log( arr.indexOf(4));       // 4
    console.log( arr.indexOf('4'));     // -1
    

    forEach()遍历数组(JS原生的遍历方法)

    只能遍历数组

    var arr = [1,3,5,9,4,6,4,1,4,8,4,12];
    // val:数组中的值,idx数组中的索引
    arr.forEach(function(val,idx){
        console.log(idx + ' : ' + val);
    });
    

    [TODO] $('选择器').each()(jQuery中的遍历方法1)

    只有jquery对象才能调用each()方法

    
    

    $.each()(jQuery中的遍历方法2)

    只有jquery对象才能调用each()方法

    可以遍历对象、数组、集合

    var arr = {name: 'XA', age: 15};
    $.each(arr, function(index, item){
        console.log(item);
        console.log(index);
    });
    

    map()映射

    var arr1 = [1,3,5,9,4,6,4,1,4,8,4,12];
    var arr2 = arr1.map(function(value, index){
        return value * value;
    });
    console.log(arr2);  // [1, 9, 25, 81, 16, 36, 16, 1, 16, 64, 16, 144]
    

    filter()过滤

    var arr1 = [1,2,3,4,5,6,7,8,9,10,11,12];
    // 过滤:索引对3能够取余 或者 值>=9
    var arr2 = arr1.filter(function(value, index){
        return index % 3 !== 0 || value >= 9;	 // 过滤条件
    });
    console.log(arr2);  // [1, 4, 7, 9, 10, 11, 12]
    

    every()遍历的所有选项都满足条件,返回true

    var arr1 = [1,2,3,4,5,6];
    var result = arr1.every(function(value, index){
        return value < 6;		// 条件
    });
    console.log(result);    // false
    

    some()遍历的选项最少有一个满足条件,返回true

    var arr1 = [1,2,3,4,5,6];
    var result = arr1.some(function(value, index){
        return value > 5;	// 条件
    });
    console.log(result);    // true
    

    函数

    分别获取实参和形参的个数

    function fn(a,b){
        console.log(arguments.length);      // 4
        console.dir(fn.length);     // 2
        console.log(arguments.callee.length);   // 2 arguments.callee表示当前的函数体
    }
    fn(10,20,30,40);
    

    [TODO] sort()排序

    
    

    递归

    案例1:求斐波那契数列中第N个数的值

    // 递归案例:求斐波那契数列中第N个数的值
    // 1 1 2 3 5 8 13 21 34...
    function fn(n){
        if( n === 1 || n === 2 ) return 1;	// 出口
        return fn(n-1) + fn(n-2);
    }
    console.log( fn(1) );   // 1
    console.log( fn(2) );   // 1
    console.log( fn(3) );   // 2
    console.log( fn(7) );   // 13
    console.log( fn(9) );   // 34
    

    案例2:求N个数的累加

    // 递归案例:求N个数的累加
    // 1+2+3+4+5+6+7+8+9...
    function getSum(n){
        if( n === 1 ) return 1;		// 出口
        return n + getSum(n-1);
    }
    console.log( getSum(15) );      // 120
    console.log( getSum(100) );     // 5050
    

    案例3:求n的阶乘n!

    // 递归案例:求n的阶乘 n!
    // 1*2*3*4*5*6*7*8...
    function getFactorial(n){
        if ( n === 1 ) return 1;
        return n * getFactorial(n-1);
    }
    console.log(getFactorial(1));  // 1
    console.log(getFactorial(2));  // 2
    console.log(getFactorial(3));  // 6
    console.log(getFactorial(10));  // 3628800
    

    案例4:遍历多维数组

    // 递归案例4:遍历多维数组
    var arr = [
        12,
        ['张三',13,'男'],
        ['李四',14,'女'],
        '宋词',
        ['王五',15,'男'],
        ['周六',16,'女'],
        ['陈七',17,'男']
    ];
    function scanArr(arr){
        arr.forEach(function(item,i){
            if (item instanceof Array){
                scanArr(item);
            }else{
                console.log(item);
            }
        });
    }
    scanArr(arr);
    

    对象

    字面量对象和JSON的区别

    • JSON的属性名必须用双引号包裹(单引号虽然在JS中可以,但是不规范)
    • JSON本质上是一种数据交换格式
    /* 字面量对象和JSON的区别 */
    // 字面量对象
    var oDog = {
        name: '二哈',
        age: 3,
        act: function(){
            console.log('卖萌,犯傻');
        }
    }
    console.log(oDog);  // {name: "二哈", age: 3, act: ƒ}
    console.log( oDog.name);    // 二哈
    oDog.act();     // 卖萌,犯傻
    
    // JSON
    var jPerson = {
        "name": '张三',
        "age": 10,
        "act": function(){
            console.log('犯罪');
        }
    }
    console.log(jPerson);   // {name: "张三", age: 10, act: ƒ}
    

    使用for in 遍历对象

    var oDog = {
        name: '皇阿玛',
        age: 10,
        act: function(){
            console.log('装逼');
        };
    }
    for( key in oDog ){
        console.log(key + '=>' +oDog[key]);
    }
    

    prototype的使用

    function Person(){
        this.age = 10;
    }
    var p = new Person();
    // 注意:这里不能写成p.prototype.name, 必须是Person.prototype.name
    Person.prototype.name = '张三'; // 
    p.constructor.prototype.eat = function(){
        alert('吃');
    }
    
    console.log(p.prototype);  // undefined
    console.log(p.name);    // 张三
    console.log(p.age);     // 10
    
    var p1 = new Person();
    console.log(p1);    // Person{age: 10}
    console.log(p1.name);   // 张三
    

    构造函数的终极写法

    function Person(option){
        this._init(option);
    }
    Person.prototype = {
        // 属性
        _init: function(option){
            this.name = option.name;
            this.age = option.age;
        },
    
        // 方法
        eat: function(food){
            alert(this.name+'正在吃'+food);
        },
        run: function(num){
            alert(this.name+'今天跑了'+num+'里');
        }
    }
    
    var p1 = new Person({"name": "张三", "age": 15});
    console.log(p1.name);
    console.log(p1.age);
    p1.eat('橘子');
    p1.run('10');
    

    JS特效(进阶)

    事件

    委托

    事件对象event的属性和方法-兼容

    • 获取事件类型
      event.type

    • 事件触发元素-在窗口可视区域的位置

    event.clientX	
    event.clientY
    
    • 事件触发元素-在页面中的位置,IE9+支持
    event.pageX *
    event.pageY *  
    

    ​ 兼容处理

    // page* = client* + 页面滚动出去的距离
    /**
     * 获取页面滚动出去的距离 - 兼容处理
     */
    function _getScroll(){
    	var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
    	var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    	return {
    		scrollLeft: scrollLeft,
    		scrollTop: scrollTop
    	}
    }
    /**
     * 获取事件触发元素与整个页面文档的距离 - 兼容处理
     */
    function _getPage(e){
    	var pageX = e.pageX || e.clientX + _getScroll().scrollLeft;
    	var pageY = e.pageY || e.clientY + _getScroll().scrollTop;
    	return {
    		pageX: pageX,
    		pageY: pageY
    	}
    }
    
    • 获取触发事件的元素
    event.target *
    

    ​ 兼容处理

    event.target || event.srcElement
    
    • 取消默认行为
    event.preventDefault() * 
    

    ​ 兼容处理

    /**
     * 取消默认行为
     */
    function _preventDefault(e){
    	if(navigator.userAgent.indexOf('MSIE') == -1){
    		e.preventDefault();
    	}else{
    		return false;
    	}
    }
    

    offset、client、scroll三大家

    offset系列

    • 获取与当前元素最近的定位父级元素之间的距离
    offsetLeft		
    offsetTop		
    
    • 内容 + padding + border
    offsetWidth	
    offsetHeight	
    
    • 获取距离当前元素最近的定位父级元素
    offsetParent	
    

    client系列

    • 当前元素border的宽度
    clientLeft
    clientTop
    
    • 内容 + padding
    clientWidth
    clientHeight
    

    scroll系列

    • 盒子内容滚动出去的距离(包括边框)
    scrollLeft
    scrollTop
    
    • 整个内容的宽度和高度
      可见内容 + 滚动出去的内容
    scrollWidth
    scrollHeight
    

    综合案例

    1. 拖拽案例
      D:00php2019web5-webapi est02-拖拽案例.html
    2. 弹出登录窗口
      D:00php2019web5-webapi est03-弹出登录窗口.html
    3. 放大镜
      D:00php2019web5-webapi est04-放大镜.html
    4. 模拟滚动条
      D:00php2019web5-webapi est05-模拟滚动条.html

    [TODO] 几个正则API之间的异同

    exp.test( str )
    exp.exec( str )

    str.match( exp )
    str.replace( exp )
    str.search( exp )

    jQuery

    四种width、四种height

    $dom.width();		// 内容
    $dom.innerWidth();	// 内容 + padding
    $dom.outerWidth();	// 内容 + padding	+ border
    $dom.outerWidth(true);	// 内容 + padding + border + margin
    
    // height同上
    

    移动Web

    CSS初始化样式(移动端)

    /* reset 初始化样式 */
    body,h1,h2,h3,h4,h5,h6,p,dl,dd,ul,ol,form,input,textarea,th,td,select {
      margin: 0; 
      padding: 0; 
      -webkit-box-sizing: border-box;
      box-sizing: border-box;
      -webkit-tap-highlight-color: transparent;
    }
    body { font-family: "微软雅黑", sans-serif; font-size: 14px; color: #333; }
    em { font-style: normal; }
    ul,ol { list-style: none; }
    a { text-decoration: none; color: #333; }
    img { border: none; vertical-align: top; }
    /* img { font-size: 0; } */
    input,textarea { outline: none; border: none; -webkit-appearance: none; }
    textarea { resize: none; overflow: auto; }
    
    /* common 公共样式 */
    .fl { float: left; }
    .fr { float: right; }
    
    .clearFix::before,
    .clearFix::after {
        content: "";
        display: block;
        visibility: hidden;
        height: 0;
        line-height: 0;
        clear: both;
    }
    .m_l10 {
        margin-left: 10px;
    }
    .m_r10 {
        margin-right: 10px;
    }
    .m_t10 {
        margin-top: 10px;
    }
    .m_b10 {
        margin-bottom: 10px;
    }
    
    body .container {  100%; max- 750px; min- 320px; margin: 0 auto; }  /* 设置最大宽度,最小宽度,居中显示 */
    

    布局-双飞翼

    <div class="box">
        <a href="#" class="fl"></a>
        <form action="#"></form>
        <a href="#" class="fr">登录</a>
    </div>
    
    .fl {
         70px;
        height: 20px;
    position: absolute;
        left: 0;
        top:  0;
    }
    .fr {
         50px;
        height: 40px;
    position: absolute;
        right: 0;
        top:  0;
    }
    form {
     100%;
    padding: 0px 50px 0 70px;
    }
    

    布局-两栏自适应

    .box1 {
         100px;
        height: 100px;
        background-color: pink;
      
    float: left; /* 重点1 */
    }
    .box2 {
    overflow: hidden; /* 重点2 */
    }
    
    <!-- 浮动元素.box1要写在.box2前面 -->    
    <div class="box1"></div>
    <div class="box2">许多内容。。。</div>
    

    [TODO] 布局-响应式

    [TODO] 布局-rem布局

    轮播图

    <div class="banner">
        <ul class="clearFix">
            <li><a href="javascript:;"><img src="uploads/l8.jpg" alt=""></a></li>
            <li><a href="javascript:;"><img src="uploads/l1.jpg" alt=""></a></li>
            <li><a href="javascript:;"><img src="uploads/l2.jpg" alt=""></a></li>
            <li><a href="javascript:;"><img src="uploads/l3.jpg" alt=""></a></li>
            <li><a href="javascript:;"><img src="uploads/l4.jpg" alt=""></a></li>
            <li><a href="javascript:;"><img src="uploads/l5.jpg" alt=""></a></li>
            <li><a href="javascript:;"><img src="uploads/l6.jpg" alt=""></a></li>
            <li><a href="javascript:;"><img src="uploads/l7.jpg" alt=""></a></li>
            <li><a href="javascript:;"><img src="uploads/l8.jpg" alt=""></a></li>
            <li><a href="javascript:;"><img src="uploads/l1.jpg" alt=""></a></li>
        </ul>
        <ul class="clearFix">
            <li class="now"></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
    </div>
    
    /**
     * 1、自动滚动
     *   - 每隔1秒,图片切换,并且实现循环无缝滚动
     *   - 轮播图中的点,跟随图片切换
     *   - 设置一个监听动画结束的事件,每次动画执行结束时执行,判断动画结束时当前index的值,如果>=9,则快速切换到第1张,并取消transition动画
     * 2、手动滚动
     *   - 根据touchstart、touchmove和touchend三个touch事件中e.touches[0]的clientX判断滑动方向
     *      - 为负值:向左滑动,下一张,index ++
     *      - 为正值:向右滑动,上一张,index --
     *      - 根据index切换图片
     */
    var slider = function(){
        // 获取元素
        var eBanner = document.querySelector('.banner');
        var eImageBox = eBanner.querySelector('ul');
        var eDotBox = eBanner.querySelectorAll('ul:last-of-type')[0];
        var eImages = eImageBox.querySelectorAll('li');
        var eDots = eDotBox.querySelectorAll('li');
        var bannerWidth = eBanner.offsetWidth;
    
        var index = 1;  // 索引,取值范围[0,9]
        // 定时滚动
        var timer = setInterval(function(){
            index ++;
            // 过渡动画
            eImageBox.style.transition = 'all 0.2s';
            eImageBox.style.webkitTransition = 'all 0.2s';
            // 设置移动
            eImageBox.style.transform = 'translateX('+(-index * bannerWidth )+'px)';
            eImageBox.style.webkitTransform = 'translateX('+(-index * bannerWidth )+'px)';
        },1000);
    
        // 监听动画结束
        eImageBox.addEventListener('transitionend', function(){
            if( index >=9 ){
                index = 1;
            }else if( index <=0 ){
                index = 8;
            }
            // 清除动画
            eImageBox.style.transition = 'none';
            eImageBox.style.webkitTransition = 'none';
            // 设置移动
            eImageBox.style.transform = 'translateX('+(-index * bannerWidth )+'px)';
            eImageBox.style.webkitTransform = 'translateX('+(-index * bannerWidth )+'px)';
            
            // 设置点切换
            // 此时index的取值范围是[1,8]
            eDots.forEach(function(item,i){
                item.classList.remove('now');
            });
            eDots[index-1].classList.add('now');
        });
    
        // 手动滚动
        var sx = 0,
            dx = 0;
        eBanner.addEventListener('touchstart', function(e) {
            // 停止定时器
            clearInterval(timer);
            sx = e.touches[0].clientX;
        });
        eBanner.addEventListener('touchmove', function(e) {
            var mx = e.touches[0].clientX;
            dx = mx - sx;
            // 图片跟随移动
            eImageBox.style.transform = 'translateX('+(-index*bannerWidth+dx)+'px)';
        });
        eBanner.addEventListener('touchend', function(e) {
            if( Math.abs(dx) < bannerWidth / 4 ){
                // 吸附回去
            }else{
                // 切换图片
                if( dx < 0 ){
                    // 左滑动 - 下一页
                    index ++;
                }else{
                    // 右滑动 - 上一页
                    index --;
                }
            }
            // 过渡动画
            eImageBox.style.transition = 'all 0.2s';
            eImageBox.style.webkitTransition = 'all 0.2s';
            // 设置移动
            eImageBox.style.transform = 'translateX('+(-index * bannerWidth )+'px)';
            eImageBox.style.webkitTransform = 'translateX('+(-index * bannerWidth )+'px)';
    
            // 重置参数
            sx = 0,
            dx = 0;
            // 定时器重新开启
            clearInterval(timer);
            timer = setInterval(function(){
                index ++;
                // 过渡动画
                eImageBox.style.transition = 'all 0.2s';
                eImageBox.style.webkitTransition = 'all 0.2s';
                // 设置移动
                eImageBox.style.transform = 'translateX('+(-index * bannerWidth )+'px)';
                eImageBox.style.webkitTransform = 'translateX('+(-index * bannerWidth )+'px)';
            },1000);
        });
    }
    

    手势事件swipe

    <div id="box"></div>
    
    // 手势事件:swipeLeft, swipeRight, swipeUp, swipeDown
    var eBox = document.querySelector('#box');
    setSwipeXEvent(eBox, function(e){
        console.log('左滑动',e,this);  // 左滑动
    },function(e){
        console.log('右滑动',e,this);  // 右滑动
    });
    /* 手势事件:swipeLeft, swipeRight, swipeUp, swipeDown */
    function setSwipeXEvent(dom, callbackLeft, callbackRight){
        var sx = 0,dx = 0,minDistance = 30;
        dom.addEventListener('touchstart', function(e){
            sx = e.touches[0].clientX;
        });
        dom.addEventListener('touchmove', function(e){
            var mx = e.touches[0].clientX;
            dx = mx - sx;
        });
        dom.addEventListener('touchend', function(e){
            // 滑动的距离需要超过最小距离,才算是一次滑动
            if( Math.abs(dx) > minDistance ){
                if( dx > 0 ){
                    // 右滑动
                    callbackRight && callbackRight.call(this, e);
                }else {
                    // 左滑动
                    callbackLeft && callbackLeft.call(this, e);
                }
            }
        });
    }
    

    tap事件

    <div id="box"></div>
    
    // 1. tap事件 轻击、轻触(响应速度快)
    // 2. 移动端也有click事件,但是为了区分是滑动还是点击,click点击会有延迟(300ms),PC上模拟不会有延迟效果
    // 3. 这种延迟影响用户体验,响应太慢了
    // 4. 解决方案:tap事件、fastclick.js插件
    //   - 使用tap事件(不是移动端原生事件,通过touch相关事件衍生过来),了解其原理(延迟150ms)
    //   - 使用fastclick.js插件,提高移动端click响应速度
    // tap事件
    var eBox = document.querySelector('#box');
    addTapEvent( eBox, function(e){
        console.log('tap事件', this, e);
    } );
    /**
     * tap事件注意点:
     *   - 不能移动
     *   - 最大延迟为150ms 
     **/
    function addTapEvent(dom,callback){
        var sx = 0, isMove = false, nowTime = 0;
        dom.addEventListener('touchstart', function(e){
            nowTime = Date.now();
            sx = e.touches[0].pageX;
        });
        dom.addEventListener('touchmove', function(e){
            var mx = e.touches[0].pageX;
            isMove = true;
        });
        dom.addEventListener('touchend', function(e){
            var disTime = Date.now() - nowTime;
            if( disTime < 150 && !isMove ){
                console.log(disTime);
                callback && callback.call(this, e);
            }
            // 重置参数
            sx =0;
            nowTime = 0;
            isMove = false;
        });
    }
    

    Nodejs

    Github

    找开源项目的一些途径
    https://github.com/trending/
    https://github.com/521xueweihan/HelloGitHub
    https://github.com/ruanyf/weekly
    https://www.zhihu.com/column/mm-fe

    特殊的查找资源小技巧-常用前缀后缀
    • 找百科大全 awesome xxx
    • 找例子 xxx sample
    • 找空项目架子 xxx starter / xxx boilerplate
    • 找教程 xxx tutorial

    其他

    不同浏览器的UserAgent信息

    • IE

    • FireFox

    • Chrome

    • Safari

    ASCII码(常用)

    键盘 ASCII码 键盘 ASCII码 键盘 ASCII码 键盘 ASCII码
    ESC 27 7 55 O 79 g 103
    SPACE 32 8 56 P 80 h 104
    ! 33 9 57 Q 81 i 105
    " 34 : 58 R 82 j 106
    # 35 ; 59 S 83 k 107
    $ 36 < 60 T 84 l 108
    % 37 = 61 U 85 m 109
    & 38 > 62 V 86 n 110
    ' 39 ? 63 W 87 o 111
    ( 40 @ 64 X 88 p 112
    ) 41 A 65 Y 89 q 113
    ***** 42 B 66 Z 90 r 114
    + 43 C 67 [ 91 s 115
    ' 44 D 68 ** 92 t 116
    - 45 E 69 ] 93 u 117
    . 46 F 70 ^ 94 v 118
    / 47 G 71 _ 95 w 119
    0 48 H 72 ` 96 x 120
    1 49 I 73 a 97 y 121
    2 50 J 74 b 98 z 122
    3 51 K 75 c 99 { 123
    4 52 L 76 d 100 | 124
    5 53 M 77 e 101 } 125
    6 54 N 78 f 102 ~ 126
    另外2个特殊ASCII码:回车=13换行=10

    文件名中不能包含的9个字符

       // 反斜杠
    /   // 斜杠
    |   // 竖斜杠
    <   // 小于号
    >   // 大于号
    *   // 星号
    ?   // 问号(英文)
    :   // 冒号(英文)
    "   // 双引号(英文)
    

    好看的颜色

    颜色 图片 备注
    #0fb3ff 渐变: ->
    #006aee
    #e53935
    #ffac13
    #ff6700 小米主题色

    好看的页面元素

    小米官网

    https://www.mi.com/

    LOL直播 - bilibili

    https://www.famulei.com/data/team/225

    background-image: linear-gradient(-45deg,#0fb3ff 0%,#006aee 100%);
    border-radius: 4px 4px 0 0;
    font-size: 18px;
    color: #fff;
    text-align: center;
    line-height: 26px;
    


    其他

    2中黄色搭配,再加上白色背景、黑色字体

    颜色:'#0000ff4d','#8dffc0','#a4e2ff','#e5a4ff','#fff1a4','#ffa4a4'

  • 相关阅读:
    数据库
    知道版本对于出0day后批量攻击dedecms有非常大的帮助,先判断版本再选择相应exp,效率大增
    跟我开发NSP(网上查询平台):如何选择开发项目
    Python3基础教程(十七)—— Virtualenv
    Python3基础教程(十六)—— 迭代器、生成器、装饰器
    Python3基础教程(十五)—— PEP8 代码风格指南
    Python3简明教程(十四)—— Collections模块
    Python3简明教程(十二)—— 模块
    Python3简明教程(十一)—— 类
    Python3简明教程(十)—— 异常
  • 原文地址:https://www.cnblogs.com/pikachu/p/14797518.html
Copyright © 2020-2023  润新知