Skip to content

776A0A/demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

75 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JS相关

  1. new模拟
  2. call模拟
  3. bind模拟
  4. jsonp函数封装
  5. 二分查找的两种写法
  6. 常用正则验证
  7. 判断客户端
  8. 数组去重

CSS&HTML相关

  1. 显示省略号
  2. 点击显示二级下拉菜单及遮罩层
  3. toast弹窗
  4. 布局相关
  5. 样式重置
  6. 通用媒体查询
  7. 全屏背景、内容垂直居中、强制出现垂直滚动条、CSS固定页脚
  8. @font-face模板
  9. 基于文件类型的链接样式
  10. px2rem

JS相关

new模拟

function new2(fn) { // 将fn当成构造函数
    if (!(fn instanceof Function)) throw Error('not a function!')
    let obj = Object.create(fn.prototype); // 继承构造器函数原型
    let args = [...arguments].slice(1); // 获取剩余参数
    let res = fn.apply(obj, args); // 改变fn内的this指向,使得obj生成一些私有属性
    return res instanceof Object ? res : obj; // 判断res,如果为object,则直接返回,效果和new操作符一样
}

call模拟

// 具体思路是使用对象方法的调用方式,this绑定将直接绑定到对象上
// 模拟apply只是内部传参的类型不同
Function.prototype.call2 = function(obj = window) {
    obj.fn = this; // this为函数。为obj添加方法,这样使用对象方法调用法this的取值就是obj了,相当于将this值绑定在了obj
    let args = [...arguments].slice(1); // 剩余参数
    let res = obj.fn(...args); // 保留函数返回值
    delete obj.fn; // 调用后删除
    return res;
}

bind模拟

// bind并非立即调用,会返回一个绑定this后的函数
// 如果对返回函数使用new操作符,那么this将重新绑定在new返回的对象上
Function.prototype.bind2 = function(obj) {
    let thisFn = this; // 获取调用函数
    let args = [...arguments].slice(1); // 剩余参数
    let FnBound = function() {
        // 关键一步,判断是否使用new操作符
        // 函数柯里化,将先传入的参数与后传入的参数拼接
        return thisFn.apply(this instanceof FnBound ? this : obj, [...args, ...arguments]);
    }
    // 遵从bind,将返回函数的原型绑定为调用函数的原型,使用Object.create创建的实例作为中转站
    FnBound.prototype = Object.create(thisFN.prototype);
    return FnBound;
}

jsonp函数封装

function jsonp(url, params = {}, cb) {
    // 随机的回调函数名字,避免缓存问题
    let cbName = `jsonp_${(Math.random()*Math.random())}`;
    window[cbName] = function(data) {
        cb(data)
        document.body.removeChild(scriptEle)
    }
    let queryStr = ''; // 查询参数
    for (let key in params) {
        queryStr += `${key}=${params[key]}&`;
    }
    url += `?${queryStr}callback=${cbName}`;
    let scriptEle = document.createElement('script');
    scriptEle.src = url;
    document.body.appendChild(scriptEle)
}

二分查找的两种写法

// 有序数组中查找相应value的key
function binarySearch_1(arr, value) {
	let low = 0,
		high = arr.length - 1;
	while (low <= high) {
		let mid = parseInt((low + high) / 2);
		if (value === arr[mid]) {
			return mid;
		} else if (value < arr[mid]) { // 折半
			high = mid + 1;
		} else if (value > arr[mid]) { // 折半
			low = mid - 1;
		} else {
			return -1;
		}
	}
}
function binarySearch_2(arr, value, high, low = 0) {
	let high = high || arr.length - 1,
		mid = parseInt((low + high) / 2);
	if (value === arr[mid]) {
		return mid;
	} else if (value < arr[mid]) { // 折半
		high = mid + 1;
	} else if (value > arr[mid]) { // 折半
		low = mid - 1
	} else {
		return -1;
	}
}

常用正则验证

// checkType ('hjkhjhT','lower')'需要验证的字符串','匹配的格式'
// email:验证邮箱
// phone:验证手机号
// tel:验证座机号
// number:验证数字
// english:验证英文字母
// chinese:验证中文字
// lower:验证小写
// upper:验证大写
function checkType (str, type) {
    switch (type) {
        case 'email':
            return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str);
        case 'phone':
            return /^1[3|4|5|7|8][0-9]{9}$/.test(str);
        case 'tel':
            return /^(0\d{2,3}-\d{7,8})(-\d{1,4})?$/.test(str);
        case 'number':
            return /^[0-9]$/.test(str);
        case 'english':
            return /^[a-zA-Z]+$/.test(str);
        case 'chinese':
            return /^[\u4E00-\u9FA5]+$/.test(str);
        case 'lower':
            return /^[a-z]+$/.test(str);
        case 'upper':
            return /^[A-Z]+$/.test(str);
        default :
            return true;
    }
}

判断客户端

function IsPC() {
   let userAgentInfo = navigator.userAgent;
   let Agents = ["Android", "iPhone","SymbianOS", "Windows Phone","iPad", "iPod"];
   let flag = true;
   for (let i = 0; i < Agents.length; i++) {
      if (userAgentInfo.indexOf(Agents[i]) > 0) {
         flag = false;
         break;
      }
   }
   return flag;
}
// 或者
if (/(iPhone|iPad|iPod|iOS|Android)/i.test(navigator.userAgent)) { //移动端
    // do something...
}

数组去重

利用对象属性无法重复的特性:

function distinct(arr1, arr2) {
    arr1 = [...arr1, ...arr2];
    const res = [], obj = {};
    for(let val of arr1) {
        if(!obj[val]) {
            res.push(val);
            res[val] = true;
        }
    }
    return res;
}

CSS&HTML相关

显示省略号

/* 单行文本显示... */
p {
    text-overflow: ellipsis;
    white-space: wrap;
    overflow: hidden;
}
/* 多行文本显示... */
P {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
}

点击显示二级下拉菜单及遮罩层

通过JS改变相应的class

ul {
    position: absolute;
    /* 相对于顶部导航栏的位移 */
    top: 52px;
    left: 0;
    right: 0;
    z-index: 1000;
    background-color: #fff;
    transform: translateY(calc(-100%));
}
ul.show {
    transform: translateY(0);
}
.mask {
    position: fixed;
    /* 占满屏幕 */
    top: 52px;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, .6);
    z-index: 999;
    display: none;
}
.mask.show {
    display: block;
}

可以通过JS在弹出mask后禁止触摸滑动,mask消失后恢复滑动

document.addEventListener('touchmove', (e) =>{ e.preventDefault() }, { passive: false })

toast弹窗

包裹一个外层元素,使用JS切换显示与否

.mask_2 {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    height: 100vh;
    background-color: rgba(0, 0, 0, .6);
    z-index: 100000;
}

.toast {
    position: fixed;
    /* 居中 */
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 100001;
    background-color: #fff;
    padding-top: 20px;
    border-radius: 10px;
    text-align: center;
    width: 76%;
}

布局相关

<div class="icon">
    <a class="call">
        <img src="../../../images/dh@2x.png" alt="电话icon">
    </a>
    <a class="call">
        <img src="../../../images/dw@2x.png" alt="定位icon">
    </a>
</div>
.icon {
    float: right;
    display: flex;
    flex-flow: column nowrap;
    justify-content: space-between;
    align-items: center;
    position: absolute;
    /* 实现两个icon在两边 */
    top: 0;
    bottom: 0;
    right: 15px;
}
.icon a:nth-child(1) {
    margin-top: 15px;
}
.icon a:nth-child(2) {
    margin-bottom: 15px;
}
.icon a {
    display: inline-block;
    border: 1px solid rgba(0, 0, 0, .3);
    padding: 15px;
    text-align: center;
    border-radius: 50%;
    position: relative;
}
.icon a img {
    width: 40%;
    display: inline-block;
    position: absolute;
    /* 居中 */
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}

样式重置

html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
  margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; outline: none; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box;
}
html { height: 101%; -webkit-text-size-adjust: 100%; -webkit-overflow-scrolling : touch;} /* IOS Safari在横屏的时候会放大字体,第二个属性让滑动更流畅 */
body { font-size: 62.5%; line-height: 1; font-family: Arial, Tahoma, sans-serif; }
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; }
ol, ul { list-style: none; }
blockquote, q { quotes: none; }
blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; }
strong { font-weight: bold; } 
table { border-collapse: collapse; border-spacing: 0; }
img { border: 0; max-width: 100%; }
p { font-size: 1.2em; line-height: 1.0em; color: #333; }
textarea{ resize: none; }
input:focus, textarea:focus, select:focus{ outline: none; }
input::-webkit-inner-spin-button{ -webkit-appearance: none; } /* 去掉number输入框右边点击上下的小三角 */
select{ -webkit-appearance: none; } /* 去掉select的默认样式 */

通用媒体查询

/* Smartphones (portrait and landscape) ----------- */
@media only screen 
and (min-device-width : 320px) and (max-device-width : 480px) {
  /* Styles */
}

/* Smartphones (landscape) ----------- */
@media only screen and (min-width : 321px) {
  /* Styles */
}

/* Smartphones (portrait) ----------- */
@media only screen and (max-width : 320px) {
  /* Styles */
}

/* iPads (portrait and landscape) ----------- */
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) {
  /* Styles */
}

/* iPads (landscape) ----------- */
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : landscape) {
  /* Styles */
}

/* iPads (portrait) ----------- */
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : portrait) {
  /* Styles */
}

/* Desktops and laptops ----------- */
@media only screen and (min-width : 1224px) {
  /* Styles */
}

/* Large screens ----------- */
@media only screen and (min-width : 1824px) {
  /* Styles */
}

/* iPhone 4 ----------- */
@media only screen and (-webkit-min-device-pixel-ratio:1.5), only screen and (min-device-pixel-ratio:1.5) {
  /* Styles */
}

全屏背景、内容垂直居中、强制出现垂直滚动条、CSS固定页脚

/* 全屏背景 */
html { 
    background: url('images/bg.jpg') no-repeat center center fixed; 
    -webkit-background-size: cover;
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover;
}
/* 内容垂直居中 */
.container {
    min-height: 6.5em;
    display: table-cell;
    vertical-align: middle;
}
/* 强制出现垂直滚动条 */
html { height: 101% }
/* CSS固定页脚 */
#footer {
    position: fixed;
    left: 0px;
    bottom: 0px;
    height: 30px;
    width: 100%;
    background: #444;
}

@font-face模板

@font-face {
    font-family: 'MyWebFont';
    src: url('webfont.eot'); /* IE9 Compat Modes */
    src: url('webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
    url('webfont.woff') format('woff'), /* Modern Browsers */
    url('webfont.ttf')  format('truetype'), /* Safari, Android, iOS */
    url('webfont.svg#svgFontName') format('svg'); /* Legacy iOS */
}

body {
    font-family: 'MyWebFont', Arial, sans-serif;
}

基于文件类型的链接样式

/* external links */
a[href^="http://"] {
    padding-right: 13px;
    background: url('external.gif') no-repeat center right;
}

/* emails */
a[href^="mailto:"] {
    padding-right: 20px;
    background: url('email.png') no-repeat center right;
}

/* pdfs */
a[href$=".pdf"] {
    padding-right: 18px;
    background: url('acrobat.png') no-repeat center right;
}

px2rem

// 转换px为rem函数,不传值默认参数为30
@function px2rem($px: 30) {
    @return ($px / 100) + rem;
}

About

记录一些有用的代码片段

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published