Js骚操作知多少
这两天学到了很多.
queryselectorall
OR: chain selectors with commas
document.querySelectorAll('div, p span');
// selects divs, and spans in ps
AND: chain selectors without whitespace
document.querySelectorAll('div.myClass');
// selects divs with the class "myClass"
NOT: :not()
-selector
document.querySelectorAll('div:not(.myClass)');
// selects divs that do not have the class "myClass"
等于有很多种:
/* <a> elements with an href containing "example" */
a[href*="example"] {
font-size: 2em;
}
/* <a> elements with an href ending ".org" */
a[href$=".org"] {
font-style: italic;
}
/* <a> elements whose class attribute contains the word "logo" */
a[class~="logo"] {
padding: 2px;
}
数组
链式调用.map().filter()实际上是两次循环, 可以用reduce做成一次循环
//原始的:
var sources = images.filter(function(img) {
if (img.src.split('.').pop() === "json") {
return false; // skip
}
return true;
}).map(function(img) { return img.src; });
//reduce版本:
var sources = images.reduce(function(result, img) {
if (img.src.split('.').pop() !== "json") {
result.push(img.src);
}
return result;
}, []);
//flatmap版本:
images.flatMap(({src}) => src.endsWith('.json') && [] || src);
//flatmap可以转化为reduce concat, 不过concat-reduce效率不高.
var arr = [1, 2, 3, 4];
arr.flatMap(x => [x, x * 2]);
// is equivalent to
arr.reduce((acc, x) => acc.concat([x, x * 2]), []);
// [1, 2, 2, 4, 3, 6, 4, 8]
promise
这三种写法基本等价, 除了reject情况的优先处理.
//写法一
const [result1, result2] = await Promise.all([task1(), task2()]);
//写法二
const t1 = task1();
const t2 = task2();
const result1 = await t1;
const result2 = await t2;
//写法三
const [t1, t2] = [task1(), task2()];
const [result1, result2] = [await t1, await t2];
async function mym(i) {
console.log('start of my script');
//这个await是必须的.
await new Promise((resolve, reject) => {
if(i>10){//这里会引起一个隐藏的bug, 就是i<10时永远也不会resolve.
chrome.tabs.create({ url: "about:blank", active: false }, tab => {
console.log('Tab created: ' + tab.id);
if (chrome.runtime.lastError) {
reject(new Error(chrome.runtime.lastError));
} else if(i>5){ //这里会引起一个隐藏的bug, 就是i<5时永远也不会resolve.
resolve(tab);
}
});
}
})
console.log('end of my script');//很可能这里永远不会执行. 因此编码时要写足resolve
}
//因此要改造成下面这样才可以:
await new Promise((resolve,reject) => {
if(ua.length=0) resolve();
chrome.tabs.query({windowId},tabs => {
if(!(tabs.length<config.tablimit)) resolve();
chrome.tabs.create({url: ua[0],active: false},tab => {
dosomething();
resolve();
});
});
})
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Using_promises
事件的target
e.currentTarget; 保证了注册事件的父元素, 而不是触发事件的子元素.
e.target
e.stopPropagation();
e.preventDefault();
element的value
//todo待验证, 到popup页面测试下.
// document.querySelector('input[name = "code"]').value = details.setting; 这种写法此处并不生效
document.querySelector('input[name = "code"][value='+details.setting+']').checked=true;
尾递归
if (condition) {
await sleep(time);
return basermain({lastpics,lasthrefs,time});//尾递归
}
这样就不会堆栈溢出了.
解构有iterator要求
//这两个写法会报错, undefined不是iterable
let ua=[...{}.url];
let ua=[...({}).url];
//这两个写法ok
let ua=[...{url:[]}.url];
let ua=[...({url:[]}).url];