10

前端常用代码片段(一) 点这里
前端常用代码片段(二) 点这里
前端常用代码片段(三) 点这里
前端常用代码片段(四) 点这里

1.tap事件点透问题?

问题点击穿透问题:点击蒙层(mask)上的关闭按钮,蒙层消失后发现触发了按钮下面元素的click事件

zepto的tap事件是绑定到document的,所以一般点击tap事件都会冒泡到document才会触发。当点击隐藏蒙层的时候默认也会手指触发到蒙层下面的元素 执行事件

1. github上有个fastclick插件,用来规避click事件的延时执行

2. 用touchend代替tap事件并阻止掉touchend的默认行为preventDefault()

//tap事件出现点透问题
$("#id").on("tap", function (event) {
    //很多处理比如隐藏什么的
    event.preventDefault();
});

//touchend事件解决点头问题
$("#id").on("touchend", function (event) {
    //很多处理比如隐藏什么的
    event.preventDefault();
});

3:给tap事件里面的隐藏蒙层方法执行的方法300毫秒延迟

$("#id").on('tap',function(ev){
    setTimeout(function(){
        $("#id").hide();
    },320)
})

2.固定定位布局 键盘挡住输入框内容?

1.通过绑定窗口改变事件,监听键盘的弹出。

然后去改变固定定位元素的位置。默认键盘的宽度应该是页面的2分之一。所以我们位移的距离改成键盘的二分之一就可以

window.onresize = function(){
    //$(".mian")就是固定定位的元素
    if($(".mian").css('top').replace('px','') != 0){
        $(".mian").css('top',0);
    }else{
        var winHeight = $(window).height();
        $(".mian").css('top',-(winHeight/4));
    }
}

2.通过定时器实时监听是否触发input。

如果触发input框 就把固定定位,改变成静态定位。这样就会浏览器会总动把内容顶上去。

function fixedWatch(el) {
    //activeElement 获取焦点元素
    if(document.activeElement.nodeName == 'INPUT') {
        el.css('position', 'static');
    } else {
        el.css('position', 'fixed');
    }
}

setInterval(function() {
    fixedWatch($('.mian'));
}, 500);

3.去掉字符左右空格

export const trimLeOrRi=(str)=>{
   //删除左右两端的空格  
   return str.replace(/(^\s*)|(\s*$)/g, ""); 
}

4.通过JS判断一个数组

4.1 instanceof方法

instanceof 运算符是用来测试一个对象是否在其原型链原型构造函数的属性

var arr = []; 
arr instanceof Array; // true

4.2.constructor方法

constructor属性返回对创建此对象的数组函数的引用,就是返回对象相对应的构造函数

var arr = []; 
arr.constructor == Array; //true

4.3.toString.call

这种写法,是 jQuery 正在使用的

Object.prototype.toString.call(obj).slice(8,-1) == Array

4.4.ES5新增方法isArray()

var a = new Array(123);
var b = new Date();
console.log(Array.isArray(a)); //true
console.log(Array.isArray(b)); //false

字符串也是有length属性的

我们知道所有的Array都是有length属性的,就算是空数组,那么length 为0,那么字符串有没有呢?接下来我们来验证一下。

var str="sdfsd5565s6dfsd65sd6+d5fd5";
console.log(str.length)      // 26

结果是有的,所以我们在判断类型时,不能单纯拿有没有length属性来判断是不是数组了,我们可以用下面的方法来判断是否是数组:

var obj=[1,2] ;
console.log(toString.call(obj) === '[object Array]');

5. 删除数组尾部元素

一个简单的用来清空或则删除数组尾部元素的简单方法就是改变数组的length属性值。

const arr = [11, 22, 33, 44, 55, 66];
// truncanting
arr.length = 3;
console.log(arr); //=> [11, 22, 33]
// clearing
arr.length = 0;
console.log(arr); //=> []
console.log(arr[2]); //=> undefined

6.使用对象解构来处理数组

可以使用对象解构的语法来获取数组的元素:

const csvFileLine = '1997,John Doe,US,john@doe.com,New York';
const { 2: country, 4: state } = csvFileLine.split(',');

7.在switch语句中用范围值

可以使用下面的技巧来写满足范围值的switch语句:

//不推荐使用,只开阔眼界
function getWaterState(tempInCelsius) {
  let state;
  
  switch (true) {
    case (tempInCelsius <= 0): 
      state = 'Solid';
      break;
    case (tempInCelsius > 0 && tempInCelsius < 100): 
      state = 'Liquid';
      break;
    default: 
      state = 'Gas';
  }
  return state;
}
//推荐
function getWaterState2(tempInCelsius) {
  if (tempInCelsius <= 0) {
    return 'Solid';
  }
  if (tempInCelsius < 100) {
    return 'Liquid';
  }
  return 'Gas';
}

8.平铺多维数组

方法1:es6
使用Spread操作,可以很容易去平铺嵌套多维数组:

const arr = [11, [22, 33], [44, 55], 66];
const flatArr = [].concat(...arr); //=> [11, 22, 33, 44, 55, 66]
可惜,上面的方法仅仅适用于二维数组。不过,通过递归,我们可以平铺任意维度的嵌套数组。

unction flattenArray(arr) {
  const flattened = [].concat(...arr);
  return flattened.some(item => Array.isArray(item)) ? 
    flattenArray(flattened) : flattened;
}

const arr = [11, [22, 33], [44, [55, 66, [77, [88]], 99]]];
const flatArr = flattenArray(arr); 
//=> [11, 22, 33, 44, 55, 66, 77, 88, 99]

方法2:递归

function flatten(arr){
  var res = [];
  for(var i=0;i<arr.length;i++){
    if(Array.isArray(arr[i])){
      res = res.concat(flatten(arr[i]));
    }else{
      res.push(arr[i]);
    }
  }
  return res;
}

方法3:reduce

function flatten(arr){
  return arr.reduce(function(prev,item){
    return prev.concat(Array.isArray(item)?flatten(item):item);
  },[]);
}

本节参考文章:5分钟掌握JavaScript小技巧

9.如果数组列表太大,以下递归代码将导致堆栈溢出。你如何解决这个问题,仍然保留递归模式?

var list = readHugeList();

var nextListItem = function() {
    var item = list.pop();

    if (item) {
        // process the list item...
        nextListItem();
    }
};

通过修改nextListItem函数可以避免潜在的堆栈溢出,如下所示:

var list = readHugeList();

var nextListItem = function() {
    var item = list.pop();

    if (item) {
        // process the list item...
        setTimeout( nextListItem, 0);
    }
};

堆栈溢出被消除,因为事件循环处理递归,而不是调用堆栈。当nextListItem运行时,如果item不为null,则将超时函数(nextListItem)推送到事件队列,并且函数退出,从而使调用堆栈清零。当事件队列运行超时事件时,将处理下一个项目,并设置一个计时器以再次调用nextListItem。因此,该方法从头到尾不经过直接递归调用即可处理,因此调用堆栈保持清晰,无论迭代次数如何。

10.10!

function f(n){
    return (n > 1) ? n * f(n-1) : n
}

11.移动端底部input被弹出的键盘遮挡

Element.scrollIntoView():方法让当前的元素滚动到浏览器窗口的可视区域内。

document.querySelector('#inputId').scrollIntoView();
//只要在input的点击事件,或者获取焦点的事件中,加入这个api就好了

这个api还可以设置对齐方法,选择将input放在屏幕的上方/下方,类似的api还有: Element.scrollIntoViewIfNeeded(),这两个是解决同一个问题的,选择一个用就可以了。

window.addEventListener('resize', function() {
  if(
    document.activeElement.tagName === 'INPUT' ||
    document.activeElement.tagName === 'TEXTAREA'
  ) {
    window.setTimeout(function() {
      if('scrollIntoView' in document.activeElement) {
        document.activeElement.scrollIntoView();
      } else {
        document.activeElement.scrollIntoViewIfNeeded();
      }
    }, 0);
  }
});

本节参考文章:关于input的一些问题解决方法分享及评论

12.控制input显/隐密码

这个就很简单了,只需更改input的type属性值就可以了。可以看一下codepen的demo

//点击函数,获取dom,判断更改属性。
show(){
    let input=document.getElementById("inputId");  
    if(input.type=="password"){ 
      input.type='text';
    }else{
      input.type='password';
    } 
}

本节参考文章:关于input的一些问题解决方法分享

13.input多行输入显示换行

在使用textarea标签输入多行文本的时候,如果没有对多行文本显示处理,会导致没有换行的情况,如果用户需要换行...

解决方法:
只要在显示内容的地方将该属性设置为 white-space: pre-line 或者 white-space:pre-wrap,多行文本就可以换行了。

备注:white-space 属性用于设置如何处理元素内的空白,其中包括空白符和换行符。

clipboard.png

14.输入框首尾清除空格-trim()

输入框清除首尾空格是input较为常见的需求,通常在上传的时候将首尾空格去除掉。

原生清除方法:

//原生方法获取值,清除首尾空格返回一个新的字符串
var str2 = document.getElementById("inputId").trim();

Vue清除方法:

<input v-model.trim="msg">

15.在input中监听键盘事件

在用户登录或者搜索框的时候,一般都会监听键盘事件绑定回车按键,来执行登录/搜索 等操作。

原生绑定:

<input onkeydown="keydownMsg(event)" type="text" />
function keydownMsg(key) {
    keyCode = key.keyCode; //获取按键代码
    if (keyCode == 13) {  //判断按下的是否为回车键
        // 在input上监听到回车 do something
    }
}

Vue按键修饰符
Vue为监听键盘事件,提供了按键修饰符,并且为常用的按键提供了别名,使用方法如下:当回车按键在input中被按下的时候,会触发里面的函数。

<input @keyup.enter="enterActive">

16.元素滚动到浏览器窗口的可视区域

Element.scrollIntoView()方法让当前的元素滚动到浏览器窗口的可视区域内。
Element.scrollIntoViewIfNeeded()方法也是用来将不在浏览器窗口的可见区域内的元素滚动到浏览器窗口的可见区域。但如果该元素已经在浏览器窗口的可见区域内,则不会发生滚动。

因而再有什么回到顶部、去到置顶位置和键盘弹出挡住输入框之类的需求,都可以简单解决了。

scrollIntoView

scrollIntoView只接受一个参数,但接受两种类型的参数,分别是Boolean型参数和Object型参数。

  • 先说Boolean型参数,参数可以使true和false。如果为true,元素的顶端将和其所在滚动区的可视区域的顶端对齐。若为false,元素的底端将和其所在滚动区的可视区域的底端对齐。

    <body>
        <div class="chunk"></div>
        <div class="btn-top">up</div>
        <div class="btn-bottom">down</div>
        <script>
        const up = document.querySelector('.btn-top');
        const down = document.querySelector('.btn-bottom');
        const test = document.querySelector('.chunk');
        up.addEventListener('click', function() {
          test.scrollIntoView(true);
        });
        down.addEventListener('click', function() {
          test.scrollIntoView(false);
        });
        </script>
    </body>
  • Object型参数,这个对象有两个属性,属性block 值可以是start和end;属性behaviorautoinstantsmooth

    up.addEventListener('click', function() {
      test.scrollIntoView({
        block: 'start',
        behavior: 'smooth'
      });
    });
    down.addEventListener('click', function() {
      test.scrollIntoView({
        block: 'end',
        behavior: 'smooth'
      });
    });

scrollIntoViewIfNeeded

scrollIntoViewIfNeeded可以接受一个Boolean型参数,和scrollIntoView不同,true为默认值,但不是滚动到顶部,而是让元素在可视区域中居中对齐;false时元素可能顶部或底部对齐,视乎元素靠哪边更近。

两者主要区别有两个。首先是scrollIntoViewIfNeeded是比较懒散的,如果元素在可视区域,那么调用它的时候,页面是不会发生滚动的。其次是scrollIntoViewIfNeeded只有Boolean型参数,也就是说,都是瞬间滚动,没有动画的可能了。

兼容性的话

scrollIntoView:Boolean型参数几乎随便用了
scrollIntoViewIfNeeded:IE和FireFox全红,移动端基本都OK

详细见原文

本节参考文章:scrollIntoView...

17.ES6 中的 解构运算符 ...

... 每次只能展开最外层的数组,被 [].concat 后,arr 就扁平化一次。

function flatten(arr){
  while(arr.some(item => Array.isArray(item))){
    arr = [].concat(...arr);
  }
  return arr;
}

const arr = [1, [2, [3, 4]]];
console.log(flatten(arr));

本节参考文章:数组扁平化

18.reverse数组

const reverse = xs => {
  if (xs.length === 1) return xs;
  const [head, ...tail] = xs;
  return reverse(tail).concat(head);
};

reverse([1,2,3,4,5,6]) // [6,5,4,3,2,1]

19.正则实现trim()功能

function myTrim(str) {
  let reg = /^\s+|\s+$/g;
  return str.replace(reg, "");
}
console.log(myTrim('    asdf    '));

本节参考文章:2018前端面试总结...

20.js 数组每一项去除空格

var s = "222 , 3334,         3666    "

s.replace(/\s/g,"") // "222,3334,3666"

于梦中2010
2.1k 声望181 粉丝

前端菜鸟儿,请多关照!