JS常用方法
简述
整理常用的JS方法,做此记录
获取两个数组中不同的部分
js
function getdifferent(arrData1, arrData2) {
return arrData1.concat(arrData2).filter((v, i, arr) => arr.indexOf(v) === arr.lastIndexOf(v));
}将文件保存到本地
图片
js
const aTag= document.createElement('a'); // 创建a标签
aTag.download = 'test' + "." + 'jpg'; // 文件名和文件类型,可从File中获取
aTag.href =base64; // 文件地址,图片base64也可
aTag.click(); // 触发文本
js
const aTag = document.createElement('a') // 创建a标签
aTag.download = 'style' + '.' + 'json' // 文件名和文件类型,可从File中获取
aTag.href = 'data:text/plain;charset=utf-8,' + escape(JSON.stringify(style))
aTag.click() // 触发PS 2022.5.16 使用保存文本发生乱码问题,没有排查处哪里有问题,于是百度到了另一种方式,两者都保留,重复使用时,可以按情况都试一试
js
const aTag = document.createElementNS("http://www.w3.org/1999/xhtml", "a"); // 创建a标签
aTag.download = "test1" + "." + "txt"; // 文件名和文件类型,可从File中获取
aTag.href = window.URL.createObjectURL(new Blob([JSON.stringify(newData)]))
aTag.click(); // 触发json文件
js
function saveAs(blob, fileName){
// 创建隐藏的可下载链接
const eleLink = document.createElement('a');
eleLink.download = fileName;
eleLink.style.display = 'none';
// 字符内容转变成blob地址
eleLink.href = URL.createObjectURL(blob);
// 触发点击
document.body.appendChild(eleLink);
eleLink.click();
// 然后移除
document.body.removeChild(eleLink);
}
const blob = new Blob([JSON.stringify(res)], {
type: "text/plain;charset=utf-8",
});
saveAs(blob, "fileName.json");pdf文件
由于pdf文件会在部分浏览器上以直接打开的方式代替了原有的a标签下载的逻辑,所以上述触发a标签下载的方式并不适用全部浏览器
js
// url 为 pdf 地址
axios.get(url, {
responseType: 'blob',
headers: {
'Content-Type': 'application/octet-stream',
},
}).then((res) => {
const blob = new Blob([res.data], { type: 'application/pdf' })
const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob)
downloadElement.href = href
downloadElement.download = 'xxx.pdf' // 下载后文件名
document.body.appendChild(downloadElement)
downloadElement.click() // 点击下载
setTimeout(() => {
document.body.removeChild(downloadElement) // 下载完成移除元素
window.URL.revokeObjectURL(href) // 释放掉blob对象
}, 1000);在ios系统上,可能会出现Safari下载问题:无法完成操作。(webkitblobresource错误%1。) 所以需要在移出释放时添加一个延迟
导入本地文件
input标签获取FileList,取file
参考:FileReader
js
const fileReader = new FileReader();
fileReader.readAsDataURL(file); // 将读取以 base64 返回 如果是文本文件,则使用readAsText
fileReader.onload=(e)=>{
// do 异步读取后进行业务操作
}校验颜色值
校验以#、rgb、argb开头的颜色值是否标准
js
function checkColor(color){
const color1 = /^#([0-9a-f]{6}|[0-9a-f]{3})$/i
const color2 = /^rgb\(([0-9]|[0-9][0-9]|25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9])\,([0-9]|[0-9][0-9]|25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9])\,([0-9]|[0-9][0-9]|25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9])\)$/i
const color3 = /^rgba\(([0-9]|[0-9][0-9]|25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9])\,([0-9]|[0-9][0-9]|25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9])\,([0-9]|[0-9][0-9]|25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9])\,(1|1.0|0.[0-9])\)$/i
return color1.test(color) || color2.test(color) || color3.test(color);
}hex值转rgb
该方法将0x开头的hex值转为rgb值,因为css color并不能直接使用这类值
js
const hexRgb = (value) => {
let hex = value;
hex = Math.floor(hex);
const color = { r: '', g: '', b: '' };
color.r = (hex >> 16 & 255);
color.g = (hex >> 8 & 255);
color.b = (hex & 255);
return `rgb(${color.r},${color.g},${color.b})`;
}scrollTo 兼容问题
在移动端浏览器中,scrollTo有的并不生效,需要做兼容处理
js
if (!window.scrollTo) {
window.scrollTo = (option) => {
window.scrollLeft = option.left;
window.scrollTop = option.top;
};
}
if (!document.body.scrollTo) {
Element.prototype.scrollTo = (option) => {
this.scrollLeft = option.left;
this.scrollTop = option.top;
};
}经反复测试,上述方法不一定是问题原因的所在,最简的判别办法是给scrollTop加一个延时处理,如果延时能够缩放,那上述方法并不管用,尽管在vue的nextTick中调用它,但他仍有可能在某些浏览器上失效,所以最好的办法是加一个100-200毫秒的延迟 造成这个的原因,个人猜测是nextTick(vue2)在某些浏览器中并不是所有文档流加载完成。
js监听屏幕横竖屏变化
js
//通过监听窗口尺寸变化,判断是否是横竖屏,从而知道是否发生变化
window.addEventListener('resize', () => {
const orientation = (window.innerWidth > window.innerHeight) ? 'landscape' : 'portrait';
if (orientation === 'portrait') {
console.log('竖屏');
} else {
console.log('横屏');
}
}, false);js
// 也可以用这个方法获取横竖屏状态,但是该方法处于实验性技术,兼容较差
var orientation = window.screen.orientation;判别一些监听事件浏览器是否支持
js
// 利用监听事件是否是为undefined判断
// 比如scrollend在safari里不支持,就可以使用这个去判别
// 要注意的是,没有监听但支持的事件会返回null,用addEventLisnter去监听的返回的也会是null
window.onxxx === undefined; // true 为支持 // false为不支持
// 这里window可以换成其他element
getEventListeners(window) // 返回一个当前正在监听的事件,支持但没有监听的不会显示滚动到指定位置
考虑到移动端的各种情况,如果直接使用dom元素计算高度可能会出现各种问题,所以建议采用直接获取到要滚动的元素的offsetTop
我的功能场景如下:
- 横竖屏切换后定位仍是正确的
- 图片的宽高比不一
- 适配各机型浏览器
- 一进入页面就要定位
js
// 监听当前浏览的是哪个元素,并在滚动结束事件时记录下来
// 这样在横竖屏切换时仍能正确找到
window.addEventListener('scrollend', () => {
this.viewElement = document.elementFromPoint(window.innerWidth / 2, window.innerHeight / 2)
})
// 由于safari浏览器不支持scrollend,需要自己实现
if (window.onscrollend === undefined) {
let scrollTime;
window.addEventListener('scroll', () => {
if (this.resizeing) return;
if (scrollTime) {
clearTimeout(scrollTime);
}
scrollTime = setTimeout(() => {
this.viewElement = document.elementFromPoint(window.innerWidth / 2, window.innerHeight / 2)
}, 200)
})
}
// 监听横竖屏切换,也可以监听orientationchange
window.addEventListener('resize', () => {
const orientation = (window.innerWidth > window.innerHeight) ? 'landscape' : 'portrait';
if (orientation !== this.orientation) {
this.orientation = orientation;
this.resizeing = true;
// 为了兼容safari浏览器,需要加延迟
setTimeout(() => {
this.resizeing = false;
const height = this.viewElement.offsetTop
window.scrollTo({
top: height - 44,
behavior: 'smooth',
});
}, 500)
}
}, false);js
const height = document.getElementsByClassName('bgImg')[index].offsetTop;
// 在一些手机浏览器中需要加上延迟,哪怕在vue中写在nextTick里
setTimeout(() => {
this.viewElement = document.elementFromPoint(window.innerWidth / 2, window.innerHeight / 2)
console.log(height)
window.scrollTo({
top: height,
behavior: 'smooth',
});
}, 200)说几个问题,首先是安卓一系列浏览器,这些都没什么大问题,scrollend支持,所以获取没什么问题,但是safari浏览器没有这个监听事件,需要自己去实现,本子案例
移动端web页面按钮点击会变色
css
-webkit-tap-highlight-color:transparent;不换行省略号
如果不达预期,可以用span包裹
css
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;多行省略号
css
display: -webkit-box;
text-overflow: -o-ellipsis-lastline;
text-overflow: ellipsis;
line-clamp: 2;
-webkit-line-clamp: 2; // 如果是3行改为3,以此类推
-webkit-box-orient: vertical;
overflow: hidden;