JavaScript常用函数大全

我的梦境 提交于 2019-12-01 01:55:55

##新打开窗口

利用form标签

如利用以下的HTML

<form method="get" target="_blank" action="http://www.baidu.com/" id="g-form">
  <input type="hidden" name="keywords3" value="123">
</form>

当要打开新的窗口,把以上的HTML插入到<body/>里,然后赋值好input[type=hidden]的参数,再触发form.submit()方法。(不能直接在action赋值为一个带参数的URL,而是利用input[type=hidden])

利用window.open方法

这个可以查看window.open方法的API来

##检测是否支持transition

var supportTransition = (function() {
    var s = document.createElement('p').style,
        r = 'transition' in s ||
        'WebkitTransition' in s ||
        'MozTransition' in s ||
        'msTransition' in s ||
        'OTransition' in s;
    s = null;
    return r;
})();

##检测是否已安装flash及版本

// 检测是否已经安装flash,检测flash的版本
var flashVersion = (function() {
    var version;

    try {
        version = navigator.plugins['Shockwave Flash'];
        version = version.description;
    } catch (ex) {
        try {
            version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash')
                .GetVariable('$version');
        } catch (ex2) {
            version = '0.0';
        }
    }
    version = version.match(/\d+/g);
    return parseFloat(version[0] + '.' + version[1], 10);
})();

##判断浏览器是否支持图片的base64

(function() {
    var data = new Image();
    var support = true;
    data.onload = data.onerror = function() {
        if (this.width != 1 || this.height != 1) {
            support = false;
        }
        window.isSupportBase64 = support;
    };
    data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
})();

检查文档DOM元素是否在Document中

通过不停检查它的父节点有没有document元素即可

#检查元素是否在文档中
checkIfInDocument = (dom)->
  if !dom
    return false
  curParent = dom.parentNode
  inDoc = null
  recur = ->
    if null == curParent
      inDoc = false
    else if "html" == curParent.tagName.toLowerCase()
      inDoc = true
    else
      curParent = curParent.parentNode
      recur()
  recur()
  return inDoc

手机号码正则判断

var rePhone = /^(13|14|15|17|18)\d{9}$/;

秒数转换为相差的时间

/* @param {number} s: 秒数 */
function arrive_timer_format(s) {
  var t, hour, min, sec, day;
  if (s > -1) {
    hour = Math.floor(s / 3600);
    min = Math.floor(s / 60) % 60;
    sec = s % 60;
    day = parseInt(hour / 24);
    if (day > 0) {
      hour = hour - 24 * day;
      t = day + "day " + hour + ":";
    } else t = hour + ":";
    if (min < 10) {
      t += "0";
    }
    t += min + ":";
    if (sec < 10) {
      t += "0";
    }
    t += sec;
  }

  return [day, hour, min, sec, t];
}

图片自动判断居中

// 智能适配图片在容器的位置、大小
// 注意事项,每个img的父容器一定要有大小
// 很多时候没注意,加了个宽度和高度都为0的a标签,这时要把a设为display:block;
function autoAdjustImg(imgSelector) {
  var $imgs = $(imgSelector),

    adjust = function($img, $wrap) {
      var wrapW = $wrap.width(),
        wrapH = $wrap.height(),
        wrapRatio = wrapW / wrapH,
        imgW = $img.width(),
        imgH = $img.height(),
        imgRatio = imgW / imgH,

        adjustW = function() {
          $img.css({
            width: wrapW + 'px',
            height: 'auto',
            marginTop: (wrapH - wrapW / imgW * imgH) / 2 + 'px'
          });
        },

        adjustH = function() {
          $img.css({
            height: wrapH + 'px',
            width: 'auto',
            marginLeft: (wrapW - wrapH / imgH * imgW) / 2 + 'px'
          });
        },

        adjustRect = function() {
          $img.css({
            marginLeft: (wrapW - imgW) / 2 + 'px',
            marginTop: (wrapH - imgH) / 2 + 'px'
          });
        };

      if (imgW > wrapW && imgH > wrapH) {
        if (wrapRatio > imgRatio) {
          // 证明是图片的高度较大
          adjustH();
        } else {
          // 图片的宽度较大
          adjustW();
        }
      } else if (imgW > wrapW) {
        adjustW();
      } else if (imgH > wrapH) {
        adjustH();
      } else {
        adjustRect();
      }

      $img[0]._autoAdjusted = true;
    };

  $.each($imgs, function(i, img) {
    var $curImg = $(img),
      $curWrap = $curImg.parent();

    if (img.complete) {
      adjust($curImg, $curWrap);
    } else {
      img.onload = function() {
        adjust($curImg, $curWrap);
      };
    }
  });
}

使弹窗页面居中

这个方法已集成在本人开发的弹窗插件中:查看链接jquery.popup.js

免疫bodyclick方法

这个是个比较好的方法,一个弹出窗口,要设定在任何其他地方点击这个窗口会自动消失,但点这个窗口内部是没事的。那么就要用到这个方法了。->即用于检查是否点击了目标窗口而触发的bodyclic事件,如果是,你就可以另作处理了。

function clickBodyUnlessById(evt, id){
  // 是否为普通的Body点击事件,true->普通事件,false->点击到目标ID的Dom了
  return id === evt.target.id || $(evt.target).parents(['#', id].join('')).length?!1:!0;
}
#免疫bodyclick
clickBodyUnlessByDom = (evt, dom)->
  $dom = $(dom)
  specialId = "__kobe_special_id_zzzz__"
  if !$dom.prop("id")
    $dom.prop("id", specialId)
  id = $dom.prop("id")
  #是否为普通body点击事件, true->普通事件, false->点击到目标dom了
  if id == evt.target.id
    isNormal = false
  else if $(evt.target).parents("#"+id).length
    isNormal = false
  else
    isNormal = true

  if specialId == id
    $dom.attr("id", null)

  return isNormal
// 一般用法
$(document).on("click", function(evt){
  if(false === clickBodyUnlessById(evt, 'test')) return;  // 通过id
  // if(false === clickBodyUnlessByDom(evt, $("div#test"))) return; // (可选)通过Dom
  $("#test").remove();
});

将url参数转为obj

# 直接读取location来转换URL参数
urlParamToObj = ()->
  if location.search
    u = location.search
  else
    u = location.href
    u = u.slice(0, u.indexOf("#"))
  p = {}
  if -1 != u.indexOf("?")
    sear = u.slice(u.indexOf("?")+1).split("&")
    for item in sear
      do(item)->
        s = item.split("=")
        p[s[0]] = s[1]
  return p

##数组去重

//此方法充分利用了递归和indexOf方法,感谢网友@真爱像深蓝
var unique = function(arr, newArr) {
  var num;

  if (-1 == arr.indexOf(num = arr.shift())) newArr.push(num);

  arr.length && unique(arr, newArr);
}

##数据求交集

var intersection = function(array1, array2) {
  return array1.filter(function(n) {
    return array2.indexOf(n) != -1;
  });
}

克隆方法-clone()

貌似本方法未作严谨处理,比如处理Date,RegExp,function的情况。如果确认只是普通使用场景,克隆对象不存在上面的情况,那么可放心使用本方法

简版:

function clone(src){
  var dist;

  switch(typeof src){
    case "object":
      if(src instanceof Array){
        dist = [];
        for(var i=0,j=src.length; j>i; i++){
          dist.push(clone(src[i]));
        }
      }else if (null !== src){
        dist = {};
        for(var key in src){
          dist[key] = clone(src[key]);
        }
      }else{
        dist = src;
      }
      break;

    default:
      dist = src;
  }

  return dist;
}

原版:

function clone(obj) {
  var o;
  switch (typeof obj) {
    case 'undefined':
      break;
    case 'string':
      o = obj + '';
      break;
    case 'number':
      o = obj - 0;
      break;
    case 'boolean':
      o = obj;
      break;
    case 'object':
      if (obj === null) {
        o = null;
      } else {
        if (obj instanceof Array) {
          o = [];
          for (var i = 0, len = obj.length; i < len; i++) {
            o.push(clone(obj[i]));
          }
        } else {
          o = {};
          for (var k in obj) {
            o[k] = clone(obj[k]);
          }
        }
      }
      break;
    default:
      o = obj;
      break;
  }
  return o;
}

邮箱格式-正则检查

var reEmail = /^(?:\w+\.)*\w+@\w+(?:\.\w+)+$/i;
reEmail.test( "abc@abc.com" ),       // true
reEmail.test( "abc.@abc.com" ),      // false
reEmail.test( "abc.def@abc.com" ),   // true
reEmail.test( "abc@abc.def.cn" );    // true

生成GUID码

Math.guid = function(){
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c){

    var r = Math.random()*16|0, v = c == "x" ? r : (r&0x3|0x8);
    return v.toString(16);
  }).toUpperCase();
};

随机生成数字字母的字符串(验证码)

function generateRandomAlphaNum(len) {
  var rdmString = "";
  for (; rdmString.length < len; rdmString += Math.random().toString(36).substr(2));
  return rdmString.substr(0, len);
}
// 译者注:特意查了一下Math.random()生成0到1之间的随机数,number.toString(36)是将这个数字转换成36进制(0-9,a-z),最后substr去掉前面的“0.”字符串

base64字符串编码与解码

function base64Encode(str) {
  return btoa(unescape(encodeURIComponent(str)));
}
function base64Decode(str) {
  return decodeURIComponent(escape(atob(str)));
}

js兼容获取最终样式

function getStyle(obj, attribute) {
  return obj.currentStyle ? obj.currentStyle[attribute] : document.defaultView.getComputedStyle(obj, null)[attribute];
}
//IE:
var bgColor = oDiv.currentStyle.backgroundColor; //只读的,如果对它进行写入会发生错误
//DOM:
//getComputedStyle(obj,null)接受两个参数,需要获取样式的元素和诸如:hover和:first-letter之类的伪元素
var bgColor = document.defaultView.getComputedStyle(oDiv, null).backgroundColor;

大数字每3位添加逗号

function addCommas(nStr) {
  nStr += '';
  var x = nStr.split('.');
  var x1 = x[0];
  var x2 = x.length > 1 ? '.' + x[1] : '';
  var rgx = /(d+)(d{3})/;

  while (rgx.test(x1)) {
    x1 = x1.replace(rgx, '$1' + ',' + '$2');
  }

  return x1 + x2;
}

window.requestAnimationFrame兼容写法

window.requestAnimFrame = function() {
  return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(e, t) {
    return window.setTimeout(e, 1e3 / 60)
  };
}();

js的trim()

s = new String("   -- kobe  ").trim();//  -> "-- kobe"
s = new String("   -- kobe  ").trimLeft();// -> "-- kobe  "
s = new String("   -- kobe  ").trimRight();// -> "   -- kobe"

// 正则实现trim()
function trim(a) {return a.replace(/(^\s*)|(\s*$)/g, "")}

// jquery
$.trim(" haha ");

判断浏览器类型

//浏览器判断,使用方法:
var userAgent = navigator.userAgent.toLowerCase();
browser = {
  version: (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [0, '0'])[1],
  safari: /webkit/.test(userAgent),
  opera: /opera/.test(userAgent),
  chrome: /chrome/.test(userAgent),
  msie: /msie/.test(userAgent) && !/opera/.test(userAgent),
  mozilla: /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent)
}
//判断IE6
function isIe6() {
  if (browser.msie && browser.version == '6.0') {
    alert('他就是IE6');
  } else {
    alert('不是IE6');
  }
}
isIe6();

jQuery方法:

/* <![CDATA[ */
$(document).ready(function() {
  var bro = $.browser;
  var binfo = "";
  if (bro.msie) {
    binfo = "Microsoft Internet Explorer " + bro.version;
  }
  if (bro.mozilla) {
    binfo = "Mozilla Firefox " + bro.version;
  }
  if (bro.safari) {
    binfo = "Apple Safari " + bro.version;
  }
  if (bro.opera) {
    binfo = "Opera " + bro.version;
  }
  //alert(binfo);
  $("#browser").html(binfo);
})
/* ]]> */

获取浏览器的前缀

var prefix = (function() {
  if ("undefined" !== typeof window.getComputedStyle) {
    var styles = window.getComputedStyle(document.documentElement, ''),
      pre = (Array.prototype.slice
        .call(styles)
        .join('')
        .match(/-(moz|webkit|ms)-/) || (styles.OLink === '' && ['', 'o'])
      )[1],
      dom = ('WebKit|Moz|MS|O').match(new RegExp('(' + pre + ')', 'i'))[1];
    return {
      dom: dom,
      lowercase: pre,
      css: '-' + pre + '-',
      js: pre[0].toUpperCase() + pre.substr(1)
    };
  }
})();

输出有:

{"dom":"WebKit","lowercase":"webkit","css":"-webkit-","js":"Webkit"}
{"dom":"MS","lowercase":"ms","css":"-ms-","js":"Ms"}
{"dom":"Moz","lowercase":"moz","css":"-moz-","js":"Moz"}

throttle-debounce

/*
 * 频率控制 返回函数连续调用时,fn 执行频率限定为每多少时间执行一次
 * @param fn {function}  需要调用的函数
 * @param delay {number}    延迟时间,单位毫秒
 * @param immediate  {bool} 给 immediate参数传递false 绑定的函数先执行,而不是delay后后执行。
 * @return {function}   实际调用函数
 */
function throttle(fn, delay, immediate, debounce) {
  var curr = +new Date(), //当前时间
    last_call = 0,
    last_exec = 0,
    timer = null,
    diff, //时间差
    context, //上下文
    args,
    exec = function() {
      last_exec = curr;
      fn.apply(context, args);
    };
  return function() {
    curr = +new Date();
    context = this,
    args = arguments,
    diff = curr - (debounce ? last_call : last_exec) - delay;
    clearTimeout(timer);

    if (debounce) {
      if (immediate) {
        timer = setTimeout(exec, delay);
      } else if (diff >= 0) {
        exec();
      }
    } else {
      if (diff >= 0) {
        exec();
      } else if (immediate) {
        timer = setTimeout(exec, -diff);
      }
    }

    last_call = curr;
  }
}

/*
 * 空闲控制 返回函数连续调用时,空闲时间必须大于或等于 delay,fn 才会执行
 * @param fn {function}  要调用的函数
 * @param delay {number}    空闲时间
 * @param immediate {bool} 给 immediate参数传递false 绑定的函数先执行,而不是delay后后执行。
 * @return {function}   实际调用函数
 */
function debounce(fn, delay, immediate) {
  return throttle(fn, delay, immediate, true);
}

/* 调用控制
 * 每次调用都会延迟执行fn,直至不再调用后再延迟执行
 * @param fn {function}  要调用的函数
 * @param delay {number}    延迟时间
 */
function debounceLast(fn, delay){
  var timer, delay = delay || 100, _this, args;

  return function(){
    if(timer){
      clearTimeout(timer);
    }

    _this = this, args = arguments;

    timer = setTimeout(function(){
      fn.apply(_this, args);
      timer = null;
    }, delay);
  }
}

简单来说,假设设置了delay为1秒,如果连续不停快速触发fn,throttle会每秒触发一次fn,因为频率控制在最多每秒触发1次; 而debounce第一秒后触发fn,之后都不会触发fn,因为至少要1秒的空闲时间才可以继续触发fn; 而debounceLast的方法一直被触发的话那一直都不会执行,直至停止触发后才延迟delay毫秒后执行

获取css的伪元素

:hover, :active, :before……

var bgcolor = window.getComputedStyle(
    document.querySelector('.element'), ':before'
).getPropertyValue('background-color');

var aFontSize = window.getComputedStyle(document.getElementById("a"), ":hover").fontSize;

js类型判断

  • typeof:不能很好判断obj, null , arr, regexp和自定义对象
  • constructor: 支持大部分对象类型判断,特别是自定义类型对象,但不能在null和undefined上使用
  • Object.prototype.toString.call():支持绝大多数类型判断,但不支持自定义类型对象
var toString = Object.prototype.toString;
console.log(toString.call(arr)); // [object Array]
console.log(toString.call(nullObj)); //[object Null]
console.log(toString.call(user)); // [object Object]不能作进一步的判断

为什么不直接用obj.toString()?因为obj.toString()返回的是其对象的内容,如数值,字符串,数组等内容,不好做判断

总结:推荐使用Object.prototype.toString.call()方法,因为他能解决绝大部分情况的判断,在遇到返回值为[object Object]时,再使用constructor辅助判断,看是否是自定义对象。

判断是否支持移动端触摸事件

'ontouchstart' in document.documentElement

Function.prototype.bind补丁

if (!Function.prototype.bind) {
  Function.prototype.bind = function(obj) {
    var slice = [].slice,
      args = slice.call(arguments, 1),
      self = this,
      nop = function() {},
      bound = function() {
        return self.apply(this instanceof nop ? this : (obj || {}),
          args.concat(slice.call(arguments)));
      };

    nop.prototype = self.prototype;

    bound.prototype = new nop();

    return bound;
  };
}

position-sticky的实现

在目标区域在屏幕中可见时,它的行为就像position:relative;而当页面滚动超出目标区域时,它的表现就像position:fixed,它会固定在目标位置。

position:sticky是一个新的css3属性,它的表现类似position:relativeposition:fixed的合体,在目标区域在屏幕中可见时,它的行为就像position:relative;而当页面滚动超出目标区域时,它的表现就像position:fixed,它会固定在目标位置。

HTML5浏览器实现:

.sticky {
  position: -webkit-sticky;
  position:sticky;
  top: 15px;
}
···

其他浏览器实现:

```html
<style>
.sticky { position: fixed; top: 0; }
.header { width: 100%; background: #F6D565; padding: 25px 0; }
</style>

<div class="header"></div>

<script>
var header = document.querySelector('.header');
var origOffsetY = header.offsetTop;

function onScroll(e) {
 window.scrollY >= origOffsetY ? header.classList.add('sticky') : header.classList.remove('sticky');
}

document.addEventListener('scroll', onScroll);
</script>

##字符串长度截取

function cutstr(str, len) {
  var temp,
    icount = 0,
    patrn = /[^\x00-\xff]/,
  strre = "";
  for (var i = 0; i < str.length; i++) {
    if (icount < len - 1) {
      temp = str.substr(i, 1);
      if (patrn.exec(temp) == null) {
        icount = icount + 1
      } else {
        icount = icount + 2
      }
      strre += temp
    } else {
      break;
    }
  }
  return strre + "..."
}

##字符串替换全部

String.prototype.replaceAll = function(s1, s2) {
  return this.replace(new RegExp(s1, "gm"), s2)
}

##转义html标签

function HtmlEncode(text) {
  return text.replace(/&/g, '&').replace(/\"/g, '"').replace(/</g, '<').replace(/>/g, '>')
}

##时间日期格式转换

Date.prototype.Format = function(formatStr) {
  var str = formatStr;
  var Week = ['日', '一', '二', '三', '四', '五', '六'];
  str = str.replace(/yyyy|YYYY/, this.getFullYear());
  str = str.replace(/yy|YY/, (this.getYear() % 100) > 9 ? (this.getYear() % 100).toString() : '0' + (this.getYear() % 100));
  str = str.replace(/MM/, (this.getMonth() + 1) > 9 ? (this.getMonth() + 1).toString() : '0' + (this.getMonth() + 1));
  str = str.replace(/M/g, (this.getMonth() + 1));
  str = str.replace(/w|W/g, Week[this.getDay()]);
  str = str.replace(/dd|DD/, this.getDate() > 9 ? this.getDate().toString() : '0' + this.getDate());
  str = str.replace(/d|D/g, this.getDate());
  str = str.replace(/hh|HH/, this.getHours() > 9 ? this.getHours().toString() : '0' + this.getHours());
  str = str.replace(/h|H/g, this.getHours());
  str = str.replace(/mm/, this.getMinutes() > 9 ? this.getMinutes().toString() : '0' + this.getMinutes());
  str = str.replace(/m/g, this.getMinutes());
  str = str.replace(/ss|SS/, this.getSeconds() > 9 ? this.getSeconds().toString() : '0' + this.getSeconds());
  str = str.replace(/s|S/g, this.getSeconds());
  return str
}

##加入收藏夹

function AddFavorite(sURL, sTitle) {
  try {
    window.external.addFavorite(sURL, sTitle)
  } catch (e) {
    try {
      window.sidebar.addPanel(sTitle, sURL, "")
    } catch (e) {
      alert("加入收藏失败,请使用Ctrl+D进行添加")
    }
  }
}

##设为首页

function setHomepage() {
  if (document.all) {
    document.body.style.behavior = 'url(#default#homepage)';
    document.body.setHomePage('http://w3cboy.com')
  } else if (window.sidebar) {
    if (window.netscape) {
      try {
        netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect")
      } catch (e) {
        alert("该操作被浏览器拒绝,如果想启用该功能,请在地址栏内输入 about:config,然后将项 signed.applets.codebase_principal_support 值该为true")
      }
    }
    var prefs = Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefBranch);
    prefs.setCharPref('browser.startup.homepage', 'http://w3cboy.com')
  }
}

##关闭网页时警告

window.onbeforeunload = function(){
  return "真的要离开?";
};

##解绑匿名函数事件

利用arguments.callee

document.body.addEventListener("click", function(){
  alert("clicked!");
  document.body.removeEventListener("click", arguments.callee, false);
}, false);
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!