用于积累javascript中的实用代码段。按照实现的功能进行划分,不区分先后。
ios qq 动态修改修改 document.title 的方法
IOS webview中网页标题只加载一次,动态改变是无效的。这个时候可以使用下述方法进行动态修改:
export function changeTitle (title, img) {
if (title === undefined || window.document.title === title) {
return
}
var mobile = navigator.userAgent.toLowerCase()
if (/iphone|ipad|ipod/.test(mobile)) {
var iframe = document.createElement('iframe')
iframe.style.display = 'none'
iframe.setAttribute('src', img)
var iframeCallback = function () {
setTimeout(function () {
iframe.removeEventListener('load', iframeCallback)
document.body.removeChild(iframe)
}, 0)
}
iframe.addEventListener('load', iframeCallback)
document.body.appendChild(iframe)
}
document.title = title
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
利用加载 iframe 的方式修改 title ,代码参考自 vue-wechat-title 。
将 location.search 中的参数转化为js对象
function getSearchArgs(){
var args = {};
var query = location.search.substring(1);
var pairs = query.split("&");
for(var i = 0;i < pairs.length; i++){
var pos = pairs[i].indexOf("=");
if(pos == -1) continue;
var name = pairs[i].substring(0, pos);
var value = pairs[i].substring(pos + 1);
value = decodeURIComponent(value);
args[name] = value;
}
return args;
}
/*
* 使用方法
* var searchArgs = getSearchArgs();
*/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
设置 rem 基准值
代码摘自:TIM-手机版
(function(designWidth, maxWidth) {
var doc = document,
win = window,
docEl = doc.documentElement,
remStyle = document.createElement("style"),
tid;
function refreshRem() {
var width = docEl.getBoundingClientRect().width;
maxWidth = maxWidth || 540;
width > maxWidth && (width = maxWidth);
var rem = width * 100 / designWidth;
remStyle.innerHTML = 'html{font-size:' + rem + 'px;}';
}
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(remStyle);
} else {
var wrap = doc.createElement("div");
wrap.appendChild(remStyle);
doc.write(wrap.innerHTML);
wrap = null;
}
//要等 wiewport 设置好后才能执行 refreshRem,不然 refreshRem 会执行2次;
refreshRem();
win.addEventListener("resize", function() {
clearTimeout(tid); //防止执行两次
tid = setTimeout(refreshRem, 300);
}, false);
win.addEventListener("pageshow", function(e) {
if (e.persisted) { // 浏览器后退的时候重新计算
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
}, false);
if (doc.readyState === "complete") {
doc.body.style.fontSize = "16px";
} else {
doc.addEventListener("DOMContentLoaded", function(e) {
doc.body.style.fontSize = "16px";
}, false);
}
})(750, 750);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
判断移动端还是PC端
代码摘自:TIM-手机版
window.OS = function() {
var a = navigator.userAgent,
b = /(?:Android)/.test(a),
d = /(?:Firefox)/.test(a),
e = /(?:Mobile)/.test(a),
f = b && e,
g = b && !f,
c = /(?:iPad.*OS)/.test(a),
h = !c && /(?:iPhone\sOS)/.test(a),
k = c || g || /(?:PlayBook)/.test(a) || d && /(?:Tablet)/.test(a),
a = !k && (b || h || /(?:(webOS|hpwOS)[\s\/]|BlackBerry.*Version\/|BB10.*Version\/|CriOS\/)/.test(a) || d && e);
return {
android: b,
androidPad: g,
androidPhone: f,
ipad: c,
iphone: h,
tablet: k,
phone: a
}
}();
if (!window.OS.phone && !window.OS.ipad) {
// 非移动端及ipad端跳转
location.href = '';
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
检测对象类型
toString()
检测对象类型
检测对象类型-->>var toString = Object.prototype.toString;
toString.call(undefined); // "[object Undefined]"
toString.call(null); // "[object Null]"
toString.call(new String); // "[object String]"
toString.call("abc"); // "[object String]"
toString.call(new Number); // "[object Number]"
toString.call(123); // "[object Number]"
toString.call(new Array); // "[object Array]"
toString.call([1,2,3]); // "[object Array]"
toString.call(new Boolean); // "[object Boolean]"
toString.call(true); // "[object Boolean]"
toString.call(new Object); // "[object Object]"
toString.call({a: 1, b: 2}); // "[object Object]"
toString.call(new Function); // "[object Function]"
toString.call(function(x){ return x * x; }); // "[object Function]"
toString.call(Math); // "[object Math]"
toString.call(new Date); // "[object Date]"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
下面提供一个获取所有类型的方法:
function getType(obj){
return Object.prototype.toString.call(obj).slice(8, -1);
}
getType(undefined); // "Undefined"
getType(null); // "Null"
getType("abc"); // "String"
getType(123); // "Number"
getType([1,2,3]); // "Array"
getType(true); // "Boolean"
getType({a: 1, b: 2}); // "Object"
getType(function(x){ return x * x; }); // "Function"
getType(Math); // "Math"
getType(new Date); // "Date"
2
3
4
5
6
7
8
9
10
11
12
13
14
多维数组变一维数组
原理是先把多维数组转字符串,再把字符串转为一维数组。
join()
多维数组变一维数组-->>[[1,2,3],[2,[2,3]]].join().split(',').map(x => x * 1); // [1, 2, 3, 2, 2, 3]
toString()
多维数组变一维数组-->>[[1,2,3],[2,[2,3]]].toString().split(',').map(x => x * 1); // [1, 2, 3, 2, 2, 3]
多维数组变一维数组-->>空字符串
([[1,2,3],[2,[2,3]]] + '').split(',').map(x => x * 1); // [1, 2, 3, 2, 2, 3]
concat.apply
(仅适用于二维数组)
多维数组变一维数组-->>[].concat.apply([], [[1,2,3],[2,2,3]]); // [1, 2, 3, 2, 2, 3]
Array.reduce
(仅适用于二维数组)
多维数组变一维数组-->>[[1,2,3],[2,2,3]].reduce(
( acc, cur ) => acc.concat(cur),
[]
); // [1, 2, 3, 2, 2, 3]
2
3
4
数组去重
Array.from(new Set([1, 2, 3, 2, 2, 3])); // [1, 2, 3]
生成从0到99的数组
Array.from({length: 100}, (v, i) => i); // [0, 1, 2, ....99]
Array.from(Array(100), (v, i) => i); // [0, 1, 2, ....99]
Array.from(Array(100).keys()); // [0, 1, 2, ....99]
Array.apply(null,{length: 100}).map((v, i) => i); // [0, 1, 2, ....99]
Array(100).join().split(',').map((v, i) => i); // [0, 1, 2, ....99]
'1'.repeat(100).split('').map((v, i) => i); // [0, 1, 2, ....99]
[...Array(100)].map((v, i) => i); // [0, 1, 2, ....99]
[...Array(100).keys()]; // [0, 1, 2, ....99]
Object.keys(Array.apply(null,{length: 100})); // ['0', '1', '2', ....'99']
Object.keys(Array.apply(null,{length: 100})); // ['0', '1', '2', ....'99']
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
转化为整数
var toInteger = function (value) {
var number = Number(value);
if (isNaN(number)) { return 0; }
if (number === 0 || !isFinite(number)) { return number; }
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
};
toInteger(11.1); // 11
toInteger('11.1'); // 11
toInteger(NaN); // 0
toInteger(true); // 1
toInteger('w'); // 0
toInteger(Infinity); // Infinity
2
3
4
5
6
7
8
9
10
11
12
13
Array.of(7)
, Array(7)
, Array.from({ length: 7 })
和 [...Array(7)]
的区别
Array.of(7)
创建一个具有单个元素 7 的数组。Array(7)
创建一个长度为 7 的空数组,数组中每个元素都为空,是稀疏数组。Array.from({ length: 7 })
创建一个具有 7 个元素且每个元素都是undefined
的密集数组。[...Array(7)]
创建一个具有 7 个元素且每个元素都是undefined
的密集数组。
Array.of(7); // [7]
Array(7); // [empty × 7]
Array.from({ length: 7 }); // [undefined, undefined, undefined, undefined, undefined, undefined, undefined]
[...Array(7)]; // [undefined, undefined, undefined, undefined, undefined, undefined, undefined]
2
3
4
5
6
7
Array.prototype.concat()
合并返回的数组是浅拷贝
Array.prototype.concat()
方法创建一个新的数组,它由被调用的对象中的元素组成,每个参数的顺序依次是该参数的元素(如果参数是数组)或参数本身(如果参数不是数组),返回一个浅拷贝,其中包含从原始数组组合的相同元素的副本。原始数组的元素将复制到新数组中,如下所示:
数据类型,如字符串、数字和布尔值(不是
String
,Number
和Boolean
对象):concat()
将字符串和数字的值复制到新数组中。后面值的变更不会影响其他数组的值。引用对象:
concat()
将对象引用复制到新数组中。原始数组和新数组都引用相同的对象。引用对象值的更改会影响原始数组和新数组。
var array1 = [1, 2, 3, 4],
array2 = [5, 6, [7, 8]],
array3 = array1.concat(array2); // [1, 2, 3, 4, 5, 6, [7, 8]]
// 基本数据类型
array2[0] = 9;
console.log(array2); // [9, 6, [7, 8]]
console.log(array3); // [1, 2, 3, 4, 5, 6, [7, 8]]
// 引用类型
array2[2][1] = 10;
console.log(array2); // [9, 6, [7, 10]]
console.log(array3); // [1, 2, 3, 4, 5, 6, [7, 10]]
array3[0] = 11;
console.log(array1); // [1, 2, 3, 4]
console.log(array3); // [11, 2, 3, 4, 5, 6, [7, 10]]
array3[6][0] = 12;
console.log(array2); // [9, 6, [12, 10]]
console.log(array3); // [1, 2, 3, 4, 5, 6, [12, 10]]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Array.prototype.every()
every()
方法为数组中的每个元素执行一次callback
函数,直到它找到一个使callback
返回false
(或可转换为布尔值false
的值)的元素。如果发现了一个这样的元素,every()
方法将会立即返回 false
,否则返回true
。但是有几点需要注意的:
every()
不会改变原数组。every()
遍历的元素范围在第一次调用callback
之前就已确定了。在调用every()
之后添加到数组中的元素不会被callback
访问到。- 如果数组中存在的元素被更改,则他们传入
callback
的值是every()
访问到他们那一刻的值。 - 被删除的元素或从来未被赋值的元素将不会被访问到。
- 空数组也是返回
true
。
// `every()`不会改变原数组。
var a = [1,2,3];
a.every((v,i) => v < 10); // true
console.log(a); // [1,2,3]
// `every()`遍历的元素范围在第一次调用`callback`之前就已确定了。在调用`every()`之后添加到数组中的元素不会被`callback`访问到。
a.every((v, i, arr) => {
if(i == 1){
arr.push(12);
}
return v < 10;
}); // true
console.log(a); // [1, 2, 3, 12]
// 如果数组中存在的元素被更改,则他们传入`callback`的值是`every()`访问到他们那一刻的值。
a.every((v, i, arr) => {
if(i == 1){
arr[3] = 4;
}
if(i == 3){
console.log(v); // 4
}
return v < 10;
}); // true
console.log(a); // [1, 2, 3, 4]
// 被删除的元素或从来未被赋值的元素将不会被访问到。
delete(a[3]);
console.log(a); // [1, 2, 3, empty]
a.every((v, i, arr) => {
console.log(v); // 1, 2, 3 a[3]未执行`callback`
return v < 10;
}); // true
a.every((v, i, arr) => {
if(i == 0){
delete(a[1]);
}
console.log(v); // 1, 3 a[1]未执行`callback`
return v < 10;
}); // true
// 空数组也是返回`true`。
[].every((v, i) => v > 10); // true
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
Array.prototype.filter()
筛选(搜索)filter()
方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
var allOptionList = ['apple', 'banana', 'grapes', 'mango', 'orange'],
filterItems = (query) => {
return allOptionList.filter((value) => value.toLowerCase().indexOf(query.toLowerCase()) > -1);
};
filterItems('b'); // ["banana"]
filterItems('ap'); // ["apple", "grapes"]
2
3
4
5
6
7
例子查看:Open in CodePen
查找数组中的首个质数及其索引
function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) {
return false;
}
}
return element > 1;
}
console.log([4, 6, 8, 12].find(isPrime)); // undefined
console.log([4, 5, 6, 8].find(isPrime)); // 5
console.log([4, 6, 8, 12].findIndex(isPrime)); // -1
console.log([4, 5, 6, 8].findIndex(isPrime)); // 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
从数组中找出指定元素出现的所有位置
var array = ['a', 'b', 'a', 'c', 'a', 'd'];
function getIndexOfList(array, element){
var indexOfList = [];
var index = array.indexOf(element);
while (index != -1) {
indexOfList.push(index);
index = array.indexOf(element, index + 1);
}
return indexOfList;
}
getIndexOfList(array, 'a'); // [0, 2, 4]
getIndexOfList(array, 'e'); // []
2
3
4
5
6
7
8
9
10
11
12
13
[1, 2, 3].map(parseInt)
的执行过程
要明白[1, 2, 3].map(parseInt)
的执行,首先要清楚parseInt
可以传几个参数,parseInt
接受两个参数,parseInt
函数将其第一个参数转换为字符串,解析它,并返回一个整数或NaN。如果不是NaN,返回的值将是作为指定基数(基数)中的数字的第一个参数的整数。
在基数为undefined
,或者基数为 0 或者 没有指定 的情况下,JavaScript 作如下处理:
- 如果字符串string以"0x"或者"0X"开头, 则基数是16 (16进制)。
- 如果字符串string以"0"开头, 基数是8(八进制)或者10(十进制),那么具体是哪个基数由实现环境决定。ECMAScript5 规定使用10,但是并不是所有的浏览器都遵循这个规定。因此,永远都要明确给出radix参数的值。
- 如果字符串string以其它任何值开头,则基数是10 (十进制)。
数组的map
函数有两个参数,callback
、thisArg
,callback
有3个参数element
/index
/array
,在本例中此时的callback
就是parseInt
,parseInt
接受两个参数(也就是说callback
的前两个参数),所以[1, 2, 3].map(parseInt)
实际执行过程如下:
parseInt(1, 0); // 在基数为0的时候,如果字符串string以其它任何值开头,则基数是10,所以返回 1
parseInt(2, 1); // 2不属于基数1中的字符,所以返回 NaN
parseInt(3, 2); // 3不属于基数2中的字符,所以返回 NaN
2
3
map()
方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
所以最终返回结果是[1, NaN, NaN]
。