Coder Social home page Coder Social logo

blogs's People

Contributors

donglee0504 avatar

Watchers

 avatar  avatar

blogs's Issues

clean code

clean code (javascript)

[toc]

1.强类型

建议使用 === 而不是 == 来判断是否相等

// 如果没有妥善处理的话,可能会出现和预想不一样的结果
0 == false; // true
0 === false; // false
2 == "2"; // true
2 === "2"; // false

const value = "500";
if (value === 500) {
    // 不会执行
    console.log(value);
}

if (value === "500") {
    // 会执行
    console.log(value);
}

2.变量命名

let daysSLV = 10;
let y = new Date().getFullYear();

let ok;
if (user.age > 30) {
    ok = true;
}

const MAX_AGE = 30;
let daysSinceLastVisit = 10;
let currentYear = new Date().getFullYear();

...

const isUserOlderThanAllowed = user.age > MAX_AGE;

不要使用多余的无意义的单词来组合命名

let nameValue;
let theProduct;

let name;
let product;

不要使用无意义的字符/单词来命名,增加额外的记忆负担

const users = ["John", "Marco", "Peter"];
users.forEach(u => {
    doSomething();
    doSomethingElse();
    // ...
    // ...
    // ...
    // ...
    // 这里u到底指代什么?
    register(u);
});

const users = ["John", "Marco", "Peter"];
users.forEach(user => {
    doSomething();
    doSomethingElse();
    // ...
    // ...
    // ...
    // ...
    register(user);
});

在某些环境下,不用添加冗余的单词来组合命名。比如一个对象叫user,那么其中的一个名字的属性直接用name,不需要再使用username了。

const user = {
  userName: "John",
  userSurname: "Doe",
  userAge: "28"
};

const user = {
  name: "John",
  surname: "Doe",
  age: "28"
};

3.函数

请使用完整的声明式的名字来给函数命名。比如一个函数实现了某个行为,那么函数名可以是一个动词或则一个动词加上其行为的被作用者。名字就应该表达出函数要表达的行为。

function notif(user) {
    // implementation
}

function notifyUser(emailAddress) {
    // implementation
}

避免使用过多参数。最好一个函数只有 2 个甚至更少的参数。参数越少,越容易做测试。

function getUsers(fields, fromDate, toDate) {
    // implementation
}

function getUsers({ fields, fromDate, toDate }) {
    // implementation
}

getUsers({
    fields: ["name", "surname", "email"],
    fromDate: "2019-01-01",
    toDate: "2019-01-18"
});

为函数参数设置默认值,而不是在代码中通过条件判断来赋值。

function createShape(type) {
    const shapeType = type || "cube";
    // ...
}

function createShape(type = "cube") {
    // ...
}

使用Objecg.assign来设置默认对象值。

const shapeConfig = {
    type: "cube",
    width: 200,
    height: null
};

function createShape(config) {
    config.type = config.type || "cube";
    config.width = config.width || 250;
    config.height = config.width || 250;
}

createShape(shapeConfig);

const shapeConfig = {
  type: "cube",
  width: 200
  // Exclude the 'height' key
};

function createShape(config) {
  config = Object.assign(
    {
      type: "cube",
      width: 250,
      height: 250
    },
    config
  );

  ...
}

createShape(shapeConfig);

不要使用 true/false 的标签(flag),因为它实际上让函数做了超出它本身的事情。

function createFile(name, isPublic) {
    if (isPublic) {
        fs.create(`./public/${name}`);
    } else {
        fs.create(name);
    }
}

function createFile(name) {
    fs.create(name);
}

function createPublicFile(name) {
    createFile(`./public/${name}`);
}

不要污染全局。如果你需要对现有的对象进行扩展,不要在对象的原型链上定义函数。请使用 ES 的类和继承。

Array.prototype.myFunc = function myFunc() {
    // implementation
};

class SuperArray extends Array {
    myFunc() {
        // implementation
    }
}

4.对象

  • 使用 Object.assign 设置默认属性
// Good:
const menuConfig = {
  title: 'Order',
  // 不包含 body
  buttonText: 'Send',
  cancellable: true
};
function createMenu(config) {
  config = Object.assign({
    title: 'Foo',
    body: 'Bar',
    buttonText: 'Baz',
    cancellable: true
  }, config);
  // config : {title: "Order", body: "Bar", buttonText: "Send", cancellable: true}
  // ...
}
createMenu(menuConfig);

5.尽量不要写全局方法

  • 在 JavaScript 中,永远不要污染全局,会在生产环境中产生难以预料的 bug。举个例子,比如你在 Array.prototype 上新增一个 diff 方法来判断两个数组的不同。而你同事也打算做类似的事情,不过他的 diff 方法是用来判断两个数组首位元素的不同。很明显你们方法会产生冲突,遇到这类问题我们可以用 ES2015/ES6 的语法来对 Array 进行扩展。
// Bad:
Array.prototype.diff = function diff(comparisonArray) {
  const hash = new Set(comparisonArray);
  return this.filter(elem => !hash.has(elem));
};
// Good:
class SuperArray extends Array {
  diff(comparisonArray) {
    const hash = new Set(comparisonArray);
    return this.filter(elem => !hash.has(elem));        
  }
}

6. 使用 promise 或者 Async/Await 代替回调

// Bad:
get('https://en.wikipedia.org/wiki/Robert_Cecil_Martin', (requestErr, response) => {
  if (requestErr) {
    console.error(requestErr);
  } else {
    writeFile('article.html', response.body, (writeErr) => {
      if (writeErr) {
        console.error(writeErr);
      } else {
        console.log('File written');
      }
    });
  }
});
// Good:
get('https://en.wikipedia.org/wiki/Robert_Cecil_Martin')
  .then((response) => {
    return writeFile('article.html', response);
  })
  .then(() => {
    console.log('File written');
  })
  .catch((err) => {
    console.error(err);
  });

// perfect:
async function getCleanCodeArticle() {
  try {
    const response = await get('https://en.wikipedia.org/wiki/Robert_Cecil_Martin');
    await writeFile('article.html', response);
    console.log('File written');
  } catch(err) {
    console.error(err);
  }
}

7.ES类

const Person = function(name) {
    if (!(this instanceof Person)) {
        throw new Error("Instantiate Person with `new` keyword");
    }

    this.name = name;
};

Person.prototype.sayHello = function sayHello() {
    /**/
};

const Student = function(name, school) {
    if (!(this instanceof Student)) {
        throw new Error("Instantiate Student with `new` keyword");
    }

    Person.call(this, name);
    this.school = school;
};

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
Student.prototype.printSchoolName = function printSchoolName() {
    /**/
};

class Person {
    constructor(name) {
        this.name = name;
    }

    sayHello() {
        /* ... */
    }
}

class Student extends Person {
    constructor(name, school) {
        super(name);
        this.school = school;
    }

    printSchoolName() {
        /* ... */
    }
}

使用函数调用链。像 jQuery,Lodash 都使用这个模式。你只需要在每一个函数的末尾返回this,之后的代码会更加的简洁。

class Person {
    constructor(name) {
        this.name = name;
    }

    setSurname(surname) {
        this.surname = surname;
    }

    setAge(age) {
        this.age = age;
    }

    save() {
        console.log(this.name, this.surname, this.age);
    }
}

const person = new Person("John");
person.setSurname("Doe");
person.setAge(29);
person.save();

class Person {
    constructor(name) {
        this.name = name;
    }

    setSurname(surname) {
        this.surname = surname;
        // Return this for chaining
        return this;
    }

    setAge(age) {
        this.age = age;
        // Return this for chaining
        return this;
    }

    save() {
        console.log(this.name, this.surname, this.age);
        // Return this for chaining
        return this;
    }
}

const person = new Person("John")
    .setSurname("Doe")
    .setAge(29)
    .save();

总结

  1. 命名要简洁易懂
  2. 函数参数多采用结构赋值,参数默认值;函数**为单一职责
  3. 类采用ES6语法糖

作者:Fundebug
链接:https://juejin.im/post/5cff04cbf265da1bd3054f31
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

模板引擎

/*! @preserve https://github.com/wusfen */
function wutpl(tpl){
    var code = tpl
        .replace(/<%=(.*?)%>/g, '\f_html_+= $1\f') // <%= %>
        .replace(/<%(.*?)%>/g, '\f$1\f') // <% %>
        .replace(/(^|\f)([\s\S]*?)(\f|$)/g, function($, $1, $2, $3){ // \f html \f
            return '\n_html_+= "' + $2
                .replace(/\\/g, '\\\\') // \  ->  '\\'
                .replace(/\r?\n/g, '\\n') // \n  ->  '\\n'
                .replace(/"/g, '\\"') // "  ->  '\\"'
                + '"\n'
        })
    return Function('_data_', 'var _html_="";with(_data_){'+code+'}return _html_')
}

// ========== 示例与解析 ==========

// 模板
var tpl = `
<ul>
    <% for(var i=0; i<list.length; i++){ %>
    <li>
        <%= list[i].name %>
    </li>
    <% } %>
</ul>
`

// 编译模板
var render = wutpl(tpl)


// 以上模板实际上编译成了以下代码 (render函数)
function anonymous(_data_) {
    var _html_ = "";
    with (_data_) {
        _html_ += "\n<ul>\n    "
        for (var i = 0; i < list.length; i++) {
            _html_ += "\n    <li>\n        "
            _html_ += list[i].name
            _html_ += "\n    </li>\n    "
        }
        _html_ += "\n</ul>\n"
    }
    return _html_
}


// 渲染数据
var html = render({
    list:[
        {id:1, name:'wsf'},
        {id:2, name:'Tom'}
    ]
})


// 输出结果
console.log(html)
/*
<ul>
    
    <li>
        wsf
    </li>
    
    <li>
        Tom
    </li>
    
</ul>
*/


// 复以上内容到控制台运行即看到结果

github:https://github.com/wusfen/wu.tmpl.js/blob/master/9%E8%A1%8C%E4%BB%A3%E7%A0%81%E5%AE%9E%E7%8E%B0%E6%A8%A1%E6%9D%BF%E5%BC%95%E6%93%8E.js

vue-cli 2.X 打包字体路径问题

vue cli 2.x 打包后字体路径出错
此问题是webpack的bug
解决方案
目录 build/utils.js
原代码

if (options.extract) {
      return ExtractTextPlugin.extract({
        use: sourceLoader,
        fallback: 'vue-style-loader'
      })
    } else {
      return ['vue-style-loader', sourceLoader].join('!')
    }

修改后

if (options.extract) {
      return ExtractTextPlugin.extract({
        use: sourceLoader,
        fallback: 'vue-style-loader',
        publicPath: '../../'
      })
    } else {
      return ['vue-style-loader', sourceLoader].join('!')
    }

参考 vuejs-templates/webpack#166

reduce的使用

提取对象的某些属性

let res = {
        name: 'lidong',
        age: 18,
        sports: 'baseketball'
    },
    obj,
    arr = ['name'];
    obj = arr.reduce((p, n) => {
        if(n in res) {
            p[n] = res[n]
        };
        return p
    },{})
    console.log(obj); // {name: "lidong"}

计算出一个字符串中每个字符出现的次数

let str = 'hello world';
    let obj2 = str.split('').reduce((acc, item) => {
        acc[item] = (acc[item] || 0) + 1;
        return acc
    }, {});
    console.log(obj2) // {h: 1, e: 1, l: 3, o: 2, " ": 1, …}

css和javascript中图片路径的不同

之前在写前端代码时,在图片路径的设置那里经常会遇到一个问题.比方说,我
(1)在根目录下面新建了个"images"文夹,里面放了张图片top.gif
(2)在根目录下另外新建了两个文件夹"CSS"和"JS"专门用来存放用到的.css文件和.js文件(假设我们用到的为"test.css"和"test.js")
假设在根目录下有个"test.html"文件,里面分别引用了"test.css"以及"test.js"

<script type="text/javascript" src="JS/test.js"></script> 在test.html中有这样一个标签

Just for test!

如果这时我要设置id为top的标签的背景图片,在"test.css"里这样写: #top{ background:url(../images/top.gif); } 在test.js里面这样写: document.getElementById("top").style.background="images/top.gif"; 可以发现两者有明显的不同,被这问题困扰了很久,却一直搞不清楚是什么原因,在网上google了下,终于找到了答案. html页面中,引用js脚本和css文件的机制是不一样的. (1)对于js脚本,html是吧脚本加载到页面中一起解析(就跟你的js脚本直接写在这个页面是一样的) (2)而对css文件,则仅仅是提供一个连接,并不会将其加载到html页面中,如在本例中,html根据链接去css文件中寻找所需要的图片文件

这两者的区别很重要,当我们要引用一个图片时,在js文件中要以引用它的html的路径为准,而在css文件中,要以改css路径为准.

小程序text标签之坑

<text>1</text>
<text>
  2
</text>

输出
1
2

<text>1</text>
<text>2</text>

输出
12
总结:text的闭合标签注意

React

React 中 setState 什么时候是同步的,什么时候是异步的?
在 React 中,如果是由 React 引发的事件处理(比如通过 onClick 引发的事件处理),调用 setState 不会同步更新 this.state,除此之外的 setState 调用会同步执行 this.state。所谓“除此之外”,指的是绕过 React 通过 addEventListener 直接添加的事件处理函数,还有通过 setTimeout/setInterval 产生的异步调用。
**原因:**在 React 的 setState 函数实现中,会根据一个变量 isBatchingUpdates 判断是直接更新 this.state 还是放到队列中回头再说,而 isBatchingUpdates 默认是 false,也就表示 setState 会同步更新 this.state,但是,有一个函数 batchedUpdates,这个函数会把 isBatchingUpdates 修改为t rue,而当 React 在调用事件处理函数之前就会调用这个 batchedUpdates,造成的后果就是由 React 控制的事件处理过程 setState 不会同步更新 this.state。
Advanced-Frontend/Daily-Interview-Question#17

连续点击开启实验室功能

需求:用户需在连续点击才能看到某些信息
思路:类似js的节流,点击时记录当前时间,然后与上次时间进行对比。借鉴 https://github.com/jrainlau/rhyke
源码

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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <button>点击</button>
</body>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script>
  var obj = {
    tabTime: 0,
    tabStart: 0,
    tabTime: 0,
    userRhythm: [],
    isTimeout: false,
    timer: null,
    options: {
      el: 'body',
      rhythm: '...',
      dashTime: 400,
      timeout: 2000,
      tabEvent: false,
      matching: () => {},
      matched: () => {},
      unmatched: () => {},
      onTimeout: () => {}
    },
    init: function () {
      this.addEvent({
        el: "button",
        dashTime: 400,
        timeout: 2000,
        rhythm: '.....',
        matching(arr) {
          console.log(arr)
        },
        matched() {
          alert('Monster awoke!!')
        }
      });
    },

    addEvent: function (options) {
      var that = this;
      that.options = Object.assign(that.options, options)
      $(options.el).click(function () {
        that.tabStartEvent = options.tabEvent ? 'touchstart' : 'mousedown';
        that.tabEndEvent = options.tabEvent ? 'touchend' : 'mouseup';
        that.tabStartFunc();
        that.tabEndFunc();
      })
    },
    tabStartFunc() {
      this.stopTimer()
      this.tabStart = new Date().getTime()
    },
    stopTimer() {
      clearTimeout(this.timer)
    },
    tabEndFunc() {
      this.tabTime = new Date().getTime() - this.tabStart
      if (!this.isTimeout) {
        this.tabTime < this.options.dashTime ? this.userRhythm.push('.') : this.userRhythm.push('-')
        this.options.matching(this.userRhythm)
        this.matchRhythem(this.userRhythm)
        this.startTimer()
      } else {
        this.reset()
      }
    },
    matchRhythem(userRhythm) {
      const rhythm = this.options.rhythm
      const testRhythm = userRhythm.join('')
      if (testRhythm.length === rhythm.length && testRhythm === rhythm) {
        this.options.matched()
        this.reset()
      } else if (testRhythm.length === rhythm.length && testRhythm !== rhythm) {
        this.options.unmatched()
        this.reset()
      }
    },
    reset() {
      this.userRhythm = []
      this.isTimeout = false
      this.timeoutStart = 0
      this.timeout = 0
    },
    startTimer() {
      this.timer = setTimeout(() => {
        this.isTimeout = true
        this.reset()
        this.options.onTimeout()
      }, this.options.timeout)
    }
  }
  obj.init();
</script>

</html>

swiper实现文字滚动

实现效果
用swiper实现
ezgif com-video-to-gif

<div class="swiper-container swiper-container2" id="banner2">
      <div class="swiper-wrapper">
        <div class="swiper-slide">
          <div class="comment">
            <div class="comment_user">180*****123<span class="comment_date">12-10</span></div>
            <div class="comment_content">前两天看内参推荐买了钢铁,今天暴跌及时空仓,居然还有盈余,真是太惊险了</div>
          </div>
        </div>
        <div class="swiper-slide">
          <div class="comment">
            <div class="comment_user">158*****314<span class="comment_date">6-10</span></div>
            <div class="comment_content">老师说得很对,抄底还是要抄估值底的龙头,我准备听老师的,买消费+医药</div>
          </div>
        </div>
        <div class="swiper-slide">
          <div class="comment">
            <div class="comment_user">187*****227<span class="comment_date">11-19</span></div>
            <div class="comment_content">老师很实在,从不推荐所谓的妖股,稳中求胜,跟我的风格很合。</div>
          </div>
        </div>
        <div class="swiper-slide">
          <div class="comment">
            <div class="comment_user">136*****188<span class="comment_date">7-14</span></div>
            <div class="comment_content">我文化水平不高也能看懂,很好</div>
          </div>
        </div>
        <div class="swiper-slide">
          <div class="comment">
            <div class="comment_user">150*****233<span class="comment_date">8-19</span></div>
            <div class="comment_content">之前对这种内参持怀疑态度,观察了一周,服了,说跌就跌,说反弹还真反弹了,真是准!</div>
          </div>
        </div>
        <div class="swiper-slide">
          <div class="comment">
            <div class="comment_user">188*****667<span class="comment_date">10-02</span></div>
            <div class="comment_content">老师说还要下跌,让多看少动,我手痒没听,抄到半山腰了,真是后悔</div>
          </div>
        </div>
        <div class="swiper-slide">
          <div class="comment">
            <div class="comment_user">155*****229<span class="comment_date">7-09</span></div>
            <div class="comment_content">我文化水平不高也能看懂,很好</div>
          </div>
        </div>
        <div class="swiper-slide">
          <div class="comment">
            <div class="comment_user">132*****687<span class="comment_date">9-19</span></div>
            <div class="comment_content">完这个,对各个行业的把握更全面了,选股不会再盲目了</div>
          </div>
        </div>
        <div class="swiper-slide">
          <div class="comment">
            <div class="comment_user">158*****145<span class="comment_date">12-19</span></div>
            <div class="comment_content">之前对这种内参持怀疑态度,观察了一周,服了,说跌就跌,说反弹还真反弹了,真是准!</div>
          </div>
        </div>
        <div class="swiper-slide">
          <div class="comment">
            <div class="comment_user">153*****663<span class="comment_date">11-29</span></div>
            <div class="comment_content">贴合行情,依托研报推出策略,有理有据,我信服</div>
          </div>
        </div>
        <div class="swiper-slide">
          <div class="comment">
            <div class="comment_user">156*****324<span class="comment_date">12-18</span></div>
            <div class="comment_content">紧跟老师步伐,我随时在准备抄底了!</div>
          </div>
        </div>
        <div class="swiper-slide">
          <div class="comment">
            <div class="comment_user">186*****996<span class="comment_date">12-18</span></div>
            <div class="comment_content">前两天看内参推荐买了钢铁,今天暴跌及时空仓,居然还有盈余,真是太惊险了</div>
          </div>
        </div>
      </div>
    </div>

js部分

new Swiper('#banner2', {
        loop: true,
        direction: 'vertical',
        slidesPerView: '5',
        autoplay: 3800,
        noSwiping: true,
        noSwipingClass: 'swiper-slide',
        spaceBetween: 10
      });

注意:每个slide之间的间距用css控制会出现slide滚动不完全,采用swiper的配置项spaceBetween即可

工作总结

1、移动端iOS时间显示问题:

比如2018-08-08 24:00:00 应写成 2018/08/09 00:00:00

2、Android line-height字体居中问题:

外层元素display:table,里面元素:display:table-cell;vertical-align:middle;

3、小的图片logo可以转化为64位base码:

减少http请求

4、计算当天是当年的第几周

function getWeekOfYear (time) {
     var thisDay;
     if (time) {
       thisDay = new Date(time)
     } else {
       thisDay = new Date()
     }
     var firstDay = new Date(thisDay.getFullYear(),0, 1); //本年的第一天,Js月份从0开始记!0就是1月啦。  
     var dayWeek = thisDay.getDay(); //今天周几  
     if (dayWeek == 0) {
       dayWeek = 7;
     }
     startWeek = firstDay.getDay(); //本年第一天周几  
     if (startWeek == 0) {
       startWeek = 7;
     }
     //第几周  
      return ((thisDay.getTime() - firstDay.getTime()) / (24 * 60 * 60 * 1000) + startWeek - dayWeek) / 7 + 1
   };

5、移动端滚动穿透解决方案

body.modal-open {
    position: fixed;
    width: 100%;
}
var ModalHelper = (function(bodyCls) {
  var scrollTop;
  return {
    afterOpen: function() {
      scrollTop = document.scrollingElement.scrollTop;
      document.body.classList.add(bodyCls);
      document.body.style.top = -scrollTop + 'px';
    },
    beforeClose: function() {
      document.body.classList.remove(bodyCls);
      // scrollTop lost after set position:fixed, restore it back.
      document.scrollingElement.scrollTop = scrollTop;
    }
  };
})('modal-open');

在modalOpen时调用ModalHelper.afterOpen();
在modalClose时调用ModalHelper.beforeClose();
网址链接:https://uedsky.com/2016-06/mobile-modal-scroll/ https://segmentfault.com/a/1190000005617307

6、iOS app调用Safari打开H5链接

if let url = URL(string: "https://www.reddit.com") {
    if #available(iOS 10.0, *) {
        UIApplication.shared.open(url, options: [:])
    } else {
        UIApplication.shared.openURL(url)
    }
}

8、获取当前周的周一的日期

function getFirstDayOfWeek (date) {
    var day = date.getDay() || 7;
    return new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1 - day);
};

9、页面滚动到可视区域GIF图从第一帧播放

function lazyload() {
   var seeHeight = document.body.clientHeight; //可见区域高度
   var scrollTop = $(window).scrollTop(); //滚动条距离顶部高度;
   for (var i = 0; i < num; i++) {
     if (((gif.eq(i).offset().top) < seeHeight + scrollTop) && (gif.eq(i).offset().top >= scrollTop)) { // GIF图进入可视区
       if (!gifInit[i]._init) { // GIF进入
         var src = gif.eq(i).attr('data-src');
         gif.eq(i).attr('src', src);
         gifInit[i]._init = true
         console.log(gifInit[i]._init, 'true')
       } else {
         return
       }
     } else {
       gifInit[i]._init = false //GIF离开
       console.log(gifInit[i]._init, 'false')
     }
   }
 };
 $(window).scroll(lazyload);
})

10、防抖

1、在keyup事件外层定义一个延时器
2、在keyup事件触发时清除掉定时

$(".stock_code_put").on("keyup", function () {
               clearTimeout(that.timer);
               that.timer = setTimeout(function () {
                   that.searchCode = $(".stock_code_put").val();
                   if (that.searchCode) {
                       that.ajaxSearch();
                   } else {
                       $(".search_list").addClass("none");
                   }
               }, 500); 
//函数防抖
  function debounce(method,time){
    var timer = null;
    return function(){
      console.log('被触发')
      var context = this;
      //在函数执行的时候先清除timer定时器;
      
      console.log(timer)
      clearTimeout(timer);
      timer = setTimeout(function(){
        method.call(context);
      },time);
    }
  }
  //防抖给人的感受是执行后等待一定时间才会被执行
  //如果在等待的时间内又被触发,以最后的为准 因为上次的被clear掉了
  //总之一定会等待规定时间秒才会被执行
// 节流
function throttle (func,delay){
    var prev = Date.now();
    return function(){
      console.log('被触发')
        var context = this;
        var args = arguments;
        var now = Date.now();
        if(now-prev>=delay){
            func.apply(context,args);
            prev = Date.now();
        }
    }
  }
  // 函数节流给人的感受是上次执行时间和第二次执行时间相隔一定秒。否则不会被执行真正的函数
  // 上面函数返回是一个闭包,prev不会被清除掉,并且每次prev都会更新为最后一次执行的时间
  // 要么不会执行,要么就立即执行不会等待

11、多次异步请求相互依赖问题解决方案

a、请求后台时返回promise对象,然后then回调

ajax1: function(){
return new promise(resolve) {
// 请求数据
resolve(data)
}
} 
ajax2: function(){
return new promise(resolve) {
// 请求数据
resolve(data)
}
}   
ajax1().then().then(ajax2()) 

b、采用async await

function timeout(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

async function asyncPrint(value, ms) {
  await timeout(ms);
  console.log(value) // timeout函数执行完毕后才会打印
}

asyncPrint('hello world', 50);

12、安卓端键盘调起时input被遮挡

//点击评论框 var bfscrolltop = 0;//获取软键盘唤起前浏览器滚动部分的高度 $('input[type="text"],textarea').focus(function() { //给个延迟 bfscrolltop = document.body.scrollTop;//获取软键盘唤起前浏览器滚动部分的高度 interval = setInterval(function() { document.body.scrollTop = document.body.scrollHeight}, 100 ); window.addEventListener('touchmove', fn, false); }).blur(function(){ clearInterval(interval); }); //如果你的页面中使用了iscorll插件,这时候你需要处理评论框的滑动事件————拒绝滑动 function fn(ev) { var _target = ev.target || ev.srcElement; if(_target.nodeName != 'TEXTAREA') { $('.pinglun_footerr_text').blur(); } }; --------------------- 本文来自 风中乘凉 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qq_37231097/article/details/76614702?utm_source=copy

小程序客服采用button实现

<button class="cs_button" open-type="contact" session-from="weapp">
  <image class="cs_image" src="../images/cs.png"></image>
</button> 
.cs_button {
  background-color: #fff;
  border: 0px;
  height: 100rpx;
  position: fixed;
  margin-left: 240rpx;
}
// 这里是关键css 否则button有边框
.cs_button:after {
  border: 0px;
}

.cs_image {
  width: 100rpx;
  height: 100rpx;
}


本文来自 Afanbaby 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/Afanbaby/article/details/78796968?utm_source=copy

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.