收集js小技巧
20231206
1、判断内容是否超出元素范围
在一个设置了超出显示省略号的元素中,如何判断是否显示了省略号从而添加提示框
.ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
可根据元素的 scrollWidth 和 offsetWidth 来判断
// 获取所有使用了ellipsis样式的元素
var elements = document.querySelectorAll('.ellipsis');
// 遍历这些元素
for (var i = 0; i < elements.length; i++) {
var el = elements[i];
// 如果元素的内容超出了其容器的宽度
if (el.scrollWidth > el.offsetWidth) {
// 添加title属性
el.title = el.textContent;
同时监听元素的尺寸变化来动态调整,使用 ResizeObserver
const ro = new ResizeObserver(entries => {
for (let entry of entries) {
const {width, height} = entry.contentRect;
console.log('Element:', entry.target);
console.log(`Element size: ${width}px x ${height}px`);
// 观察一个具体的 DOM 节点
const el = document.querySelector('.ellipsis')
ro.observe(el );
// 取消监听
ro.unobserve(el)
// 取消所有监听
ro.disconnect()
20230821
1、验证图片格式和大小
checkImg(file) {
const isJPG = file.type === 'image/jpeg'
const isLt2M = file.size / 1024 / 1024 < 2
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG 格式!')
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!')
return isJPG && isLt2M
20230628
1、可插入内容的编辑框:可插入标签、可选择部分文本进行添加链接
<div class="container">
<div contenteditable id="editDiv"></div>
<span class="tag add-btn">添加标签</span>
</div>
<div class="add-link">
<input type="text" class="input">
<span class="link-btn confirm">√</span>
<span class="link-btn remove">×</span>
</div>
<script>
const editDiv = document.querySelector('#editDiv')
// 纯文本粘贴
editDiv.addEventListener('paste', function(e) {
e.preventDefault()
const text = (event.clipboardData || window.clipboardData).getData('text/plain');
const selection = document.getSelection();
if (selection.rangeCount) {
const range = selection.getRangeAt(0);
range.deleteContents();
const textNode = document.createTextNode(text);
range.insertNode(textNode);
range.setStartAfter(textNode);
selection.removeAllRanges();
selection.addRange(range);
// 显示输入链接框
editDiv.addEventListener('mouseup', showAddLink)
editDiv.addEventListener('keyup', showAddLink)
const addBtn = document.querySelector('.add-btn')
// 插入标签
addBtn.addEventListener('click', function() {
editDiv.focus()
const tag = '<span contenteditable="false" class="tag">添加标签</span>'
const el = document.createElement('div')
el.innerHTML = tag
const tagNode = el.firstChild
const selection = window.getSelection()
if (selection.rangeCount) {
const range = selection.getRangeAt(0)
range.insertNode(tagNode)
range.setStartAfter(tagNode)
range.setEndAfter(tagNode)
selection.removeAllRanges()
selection.addRange(range)
const addLink = document.querySelector('.add-link')
let globalRange = null
function showAddLink() {
const selection = window.getSelection()
if (selection.rangeCount > 0) {
const range = selection.getRangeAt(0)
if (range.toString().length > 0) {
globalRange = range
addLink.style.display = 'block'
positionAddLink()
} else {
addLink.style.display = 'none'
function positionAddLink() {
if (!globalRange) return
const rect = globalRange.getBoundingClientRect()
addLink.style.top = rect.top - addLink.offsetHeight - 15 + "px"
addLink.style.left = rect.left - (addLink.offsetWidth - rect.width) / 2 + "px"
const confirmEl = document.querySelector('.confirm')
const inputEl = document.querySelector('.input')
// 添加链接
confirmEl.addEventListener('click', function() {
const selection = window.getSelection()
selection.removeAllRanges()
selection.addRange(globalRange)
const link = document.createElement("a")
link.textContent = globalRange.toString()
link.href = inputEl.value
globalRange.deleteContents()
globalRange.insertNode(link)
addLink.style.display = 'none'
inputEl.value = ""
globalRange = null
const removeEl = document.querySelector('.remove')
// 去掉链接
removeEl.addEventListener('click', function() {
if (!globalRange) return
const selection = window.getSelection()
const anchorNode = globalRange.startContainer.parentNode
if (anchorNode.tagName === "A") {
const textNode = document.createTextNode(anchorNode.textContent)
anchorNode.replaceWith(textNode)
selection.removeAllRanges()
globalRange.selectNode(textNode)
selection.addRange(globalRange)
addLink.style.display = 'none'
</script>
<style>
margin: 0;
padding: 0;
.container {
width: 500px;
margin: 30vh auto 0;
#editDiv {
width: 100%;
min-height: 120px;
border: 1px solid #dcdfe6;
padding: 5px 15px;
line-height: 1.5;
color: #606266;
border-radius: 4px;
outline: none;
margin-bottom: 15px;
font-size: 14px;
#editDiv:hover {
border-color: #c0c4cc;
#editDiv:focus {
border-color: #1890ff;
#editDiv a {
color: #409eff;
.tag {
padding: 2px 5px;
font-size: 12px;
background: #e8f4ff;
border: 1px solid #d1e9ff;
border-radius: 4px;
color: #1890ff;
user-select: none;
margin: 0 4px;
.add-btn {
padding: 5px 10px;
font-size: 14px;
cursor: pointer;
.add-btn:hover {
background: #409eff;
border-color: #409eff;
color: #fff;
.add-btn+.add-btn {
margin-right: 4px;
.add-link {
background: #fff;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
padding: 15px;
position: fixed;
display: none;
.add-link::after {
content:"";
display:block;
position: absolute;
bottom:-20px;
left:50%;
transform:translateX(-50%);
width: 0;
height:0;
border: 10px solid transparent;
border-top-color: rgba(0, 0, 0, 0.1);
.add-link::before {
content:"";
display:block;
position: absolute;
bottom:-19px;
left:50%;
transform:translateX(-50%);
width: 0;
height:0;
border: 10px solid transparent;
border-top-color: #fff;
z-index:2;
.input {
width: 200px;
height: 36px;
font-size: 14px;
color: #606266;
border: 1px solid #dcdfe6;
outline: none;
border-radius: 4px;
padding: 0 10px;
.input:hover {
border-color: #c0c4cc;
.input:focus {
border-color: #1890ff;
.link-btn {
font-size: 16px;
color: #409eff;
padding: 5px;
cursor:pointer;
</style>
2、插入带“ ”的方法
function insertHtmlAtCursor(html) {
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
// Range.createContextualFragment() would be useful here but is
// non-standard and not supported in all browsers (IE9, for one)
var el = document.createElement("div");
el.innerHTML = html;
var frag = document.createDocumentFragment(),
node, lastNode;
while ((node = el.firstChild)) {
lastNode = frag.appendChild(node);
range.insertNode(frag);
// Preserve the selection
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
} else if (document.selection && document.selection.type != "Control") {
// IE < 9
document.selection.createRange().pasteHTML(html);
insertHtmlAtCursor(' <span contenteditable="false" class="tag">添加标签</span> ');
20230627
1、验证 url
function validURL (url) {
const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
return reg.test(url)
2、获取本地文件的 url
URL.createObjectURL(file)
3、获取音频文件的时长
let duration = 0
const audioEl = document.createElement('audio')
audioEl.src = URL.createObjectURL(file)
audioEl.addEventListener('loadedmetadata', function() {
duration = audioEl.duration
在视频/音频(audio/video)加载过程中,触发事件的顺序如下:
onloadstart=>onduratuionchange=>onloadedmetadata=>onloadeddata=>onprogress=>oncanplay=>oncanplaythrough
4、中断 forEach 循环
(1)通过抛出错误
const arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
try {
arr.forEach(i => {
console.log(i)
if (i === 'd') throw new Error('中断 forEach 循环')
} catch (e) {
console.log(e.message)
(2)使用 some() 或 every() 来终止循环,some 返回 true 可退出循环,every 返回 false 可退出循环
const arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
arr.some(i => {
console.log(i)
return i === 'd'
arr.every(i => {
console.log(i)
return i !== 'd'
5、匹配所有 span 标签并获取其内容
const regSpan = /<span[^>]*>(.*?)<\/span>/g
const title = this.$refs.imageTitle.innerHTML.replace(regSpan, (match, innerContent) => innerContent)
6、匹配所有 class 为 className 的 span 元素
const regSpan = /<span[^>]*class\s*=\s*["'](?:\s*|.*\s)?className(?:\s*|.*\s)?["'][^>]*>(.*?)<\/span>/g
7、匹配所有块级元素并替换为换行符号 \n
function matchBlockEleToWrap(htmlString, replaceStr) {
const blockElementRegex = /<(div|p|h[1-6]|ul|ol|li|table|thead|tbody|tfoot|tr|td|th|blockquote|pre|figure|figcaption|address|fieldset|legend|section|article|aside|nav|header|footer|main|figure|figcaption|canvas|audio|video|details|summary|menu|menuitem|colgroup|caption|datalist|optgroup|option|form|label|textarea|input|button|select|progress|meter|output)\b[^>]*>([\s\S]*?)<\/\1>/gi
const regBr = /<br\s*\/?>/g
while (blockElementRegex.test(htmlString)) {
htmlString = htmlString.replace(blockElementRegex, (match, tag, content) => {
const val = content.trim().replace(regBr, '')
return replaceStr + val
return htmlString
8、匹配所有空格转换为 ,并且 a 标签中空格不变
export function switchSp(val) {
const regA = /<a[^>]*>|<\/a>/gi
const regSp = / /g
return val.replace(regSp, ' ').replace(regA, (match) => match.replace(' ', ' '))
9、 String.prototype.replace()
10、粘贴为纯文本
// 监听编辑框的 paste 事件
handlepaste(e) {
// 阻止默认粘贴事件
e.preventDefault()
// 获取粘贴的文本
const text = e.clipboardData.getData('text/plain')
// 将纯文本插入到可编辑的div中
document.execCommand('insertText', false, text)
由于 document.execCommand 方法已弃用,可使用 Selection API 来实现
const editableDiv = document.getElementById('editDiv');
editableDiv.addEventListener('paste', (event) => {
// 阻止默认粘贴行为
event.preventDefault();
// 获取剪贴板中的纯文本数据
const text = (event.clipboardData || window.clipboardData).getData('text/plain');
// 使用Selection API将纯文本插入到可编辑div的当前光标位置
const selection = document.getSelection();
if (selection.rangeCount) {
const range = selection.getRangeAt(0);
range.deleteContents();
const textNode = document.createTextNode(text);
range.insertNode(textNode);
range.setStartAfter(textNode);
selection.removeAllRanges();
selection.addRange(range);
11、向 input 框插入表情
insertEmoji(emoji) {
const inputElement = this.$refs['menuName'].$el.querySelector('input')
const startPos = inputElement.selectionStart
const endPos = inputElement.selectionEnd
this.name = this.name.substring(0, startPos) + emoji + this.name.substring(endPos)
// 更新光标位置
this.$nextTick(() => {
inputElement.focus()
inputElement.selectionStart = startPos + emoji.length
inputElement.selectionEnd = startPos + emoji.length
12、计算带有表情符号的字符串长度
由于表情符号是占两个长度(length)的,如果要算作一个长度,可用 for...of 来计算
const val = 'JFK大师傅14323 '
let len = 0
let name = ''
for (let i of val) {
name += i
len++
console.log(len) // 13
13、创建唯一性的字符串
function createUniqueString () {
const timestamp = +new Date() + ''
const randomNum = parseInt((1 + Math.random()) * 65536) + ''
return (+(randomNum + timestamp)).toString(32)
20230620
1、windows 常用命令
(1)登陆服务器:ssh [email protected]
(2)退出登陆:ctrl+d
20230417
1、JavaScript 注释规范
(1)单行注释:使用双斜杠创建一个单行注释
// 注释内容
(2)多行注释
/** 方法说明
* @method 方法名
* @for 所属类名
* @param {参数类型} 参数名 参数说明
* @return {返回值类型} 返回值说明
(3)模块注释
/** 模块说明
* @module 模块名
(4)类注释
/** 类说明
* @class 类名
* @constructor
*/
2、数组随机排序
const arraySort = <T>(arr: T[]): T[] => {
const len = arr.length
if (!Array.isArray(arr) || len <= 1) return arr
for (let i = 0; i < len - 1; i++) {
let randomIndex = Math.floor(Math.random() * (len - i)) + i
const tem = arr[i]
arr[i] = arr[randomIndex]
arr[randomIndex] = tem
return arr
3、数组拆分:将一个数组按固定长度拆分为多个数组
const arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
let idx = 0
let newArr = []
while (idx < arr.length) {
newArr.push(arr.slice(idx, idx += 3))
20230224
1、日期格式化
// 对Date的扩展,将 Date 转化为指定格式的String
// 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
// 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
// 例子:
// (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
// (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
Date.prototype.Format = function (fmt) {
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length))
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)))
return fmt
// 调用: var time1 = new Date().Format("yyyy-MM-dd");var time2 = new Date().Format("yyyy-MM-dd hh:mm:ss");
2、js复制文字
火狐浏览器在非安全域时,会禁用 navigator.clipboard 对象,连 document.execCommand 也用不了(网上说能用,但下面方法还是不生效)。
function clipboardText(text) {
return new Promise((resolve, reject) => {
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(text).then(res => {
resolve(true)
}).catch(e => {
reject(e)
} else {
const textarea = document.createElement('textarea')
document.body.appendChild(textarea)
// 隐藏此输入框
textarea.style.position = 'fixed'
textarea.style.clip = 'rect(0 0 0 0)'
textarea.style.top = '10px'
// 赋值
textarea.value = text
// 选中
textarea.select()
// 复制
document.execCommand('copy', true)
// 移除输入框
document.body.removeChild(textarea)
resolve(true)
20221129
1、生成指定长度的随机整数数组并排序
const arr = new Array(5).fill(1).map(item => item * parseInt(Math.random() * 100)).sort((a, b) => b - a)
2、获取数组最大/最小值
const min = Math.min(...arr.map(item => item.value))
const max = Math.max(...arr.map(item => item.value))
20220315
1、非空判断
// 非空判断,不是null 或 空字符串
export function notNullandEmpty(value) {
return value !== null && trim(value) !== ''
// 非空判断,除0外的falsely
export function notEmpty(value) {
return !!value || value === 0
20211229
1、格式化金额
/**
* 格式化金额,如:9876.54 =》 9,876.54
* @param sum
* @returns Array:[0]=格式化的整数部分,[1]=小数部分
formatSum(sum) {
let arr: Array < string > = []
if (!sum && sum != 0) return arr
const sumArr = (+sum).toString().split('.')
const intFormat: string = sumArr[0].replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')
arr.push(intFormat)
if (sumArr[1]) arr.push(sumArr[1])
return arr
页面效果如下:
2、数字格式化: toLocaleString()
该属性可用于数字、金额、百分比等格式化,具体使用见 MDN。
const num = 11111.011187
console.log(num.toLocaleString('zh-CN', { style: 'currency', currency: 'CNY' }))
// ¥11,111.01
20211122
1、匹配手机号和固定电话,并替换
let phoneRep = /(((\+?86)|(\(\+86\)))?([1][3,4,5,7,8,9]\d{9}))/g; // 手机号匹配
let fixNum = /(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}/g; // 固定号码匹配
let replaceStr = '<span class="logistics-phone">$&</span>';
str = str.replace(phoneRep, replaceStr).replace(fixNum, replaceStr)
- $$ 直接量符号(就是当做 '$$' 字符用)
- $& 与正则相匹配的字符串
- $` 匹配字符串左边的字符
- $’匹配字符串右边的字符
- $1,$2,$,3,…,$n 匹配结果中对应的分组匹配结果
2、处理物流信息
描述:后端查到的物流信息通常放在一个 list 中,需要根据信息内容来分类物流阶段状态:已签收、已代收、待取件、派送中、运输中、已揽件、已发货、已下单,list数据如下:
分析:根据 status 中的关键词,来判断处在哪个状态,在页面中加上相应的状态和对应的图标
const deliveryMsg = [
{ status: ['已签收'], class: 'logistics-sign', text: '已签收' },
{ status: ['代收'], class: 'logistics-sign', text: '已代收' },
{ status: ['待取件'], class: 'logistics-takeparts', text: '待取件' },
{ status: ['派送中', '派件中', '派件'], class: 'logistics-delivery', text: '派送中' },
// { status: ['运输中', '已发出', '已收入', '已发往', '已经到达'], class: 'logistics-transport', text: '运输中', ref: 'transfer' },
{ status: ['已揽件', '已揽收'], class: 'logistics-solicitation', text: '已揽件' },
{ status: ['已发货'], class: 'logistics-degoods', text: '已发货' },
{ status: ['已下单'], class: 'logistics-place', text: '已下单' },
// 格式化运输信息
const getStatus = (status) => {
let curStatus: any = {}
deliveryMsg.forEach((item) => {
item.status.forEach((text) => {
if (status.indexOf(text) !== -1) {
curStatus = item
return curStatus
根据上面方法问题有,所有运输阶段的信息都会加上对应的状态及图标,而只需要最近一条添加即可,如
解决思路,运输中状态单独处理,循环 list,在运输中的信息中添加区分值:
let index = 0
res.list.forEach((list) => {
let isTransfer = ['运输中', '已发出', '已收入', '已发往', '已经到达']
isTransfer.forEach((tran) => {
if (list.status.indexOf(tran) > -1) list.trans = index++
再根据 trans 字段来判断即可
20211111
1、Javascript 判断对象中是否有某属性
(1)使用点(.)或方括号([])取值,若为undefined,则为空。局限性是若属性值为undefined,无法判断
(2)使用 in 运算符,若属性在指定对象或原型链中,则返回 true。局限性是无法区分自身属性还是原型链上的属性。
(3)使用 hasOwnProperty(),存在并且为自身属性返回 true
20211109
1、如何让同步代码休眠多少秒后再执行,实现 sleep() 函数
const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay))
const sleepLog = async () => {
await sleep(2000)
console.log(1)
await sleep(2000)
console.log(2)
await sleep(2000)
console.log(3)
sleepLog()
20211109前
1、根据 name 值获取表单中输入框的值,表单如下:
<form method='get' action='' target='_blank' name='qForm'>
<input name='q' type='text' />
</form>
<script>
var val = document.qForm.q.value
</script>
2、jquery 获取包括当前元素在内的 html :
$("#test").prop("outerHTML");
3、获取 url
/* https://test.com:8080/test/index.html#test?name=test */
var url;
url = window.location.href; /* 获取完整 URL */
url = window.location.pathname; /* 获取文件路径(文件地址)---> /test/index.html */
url = window.location.protocol; /* 获取协议 ---> https */
url = window.location.host; /* 获取主机地址和端口号 ---> test.com:8080 */
url = window.location.hostname; /* 获取主机地址 --> test.com */
url = window.location.port; /* 获取端口号 ---> 8080 */
url = window.location.hash; /* 获取锚点(“#”后面的分段)---> #test?name=test */
url = window.location.search; /* 获取属性(“?”后面的分段)---> name=test */
4、判断 a 链接是否是外链
var domainName = window.location.hostname
$(className).find('a').map(function () {
var href = $(this).attr('href')
if (href.indexOf('http') !== -1 && href.indexOf(domainName) == -1) {
$(this).attr('target', '_blank')
5、图片在父元素里居中
$('.parentEle').find('img').each(function () {
var parentH = $(this).parent().height()
var parentW = $(this).parent().width()
var parentR = parentW / parentH
var imgH = $(this).height()
var imgW = $(this).width()
var imgR = imgW / imgH
if (parentR > imgR) {
if (imgH > parentH) {
$(this).height(parentH)
$(this).width(parentH * imgR)
} else {
$(this).css('margin-top', (parentH - imgH) / 2)
} else {
if (imgW > parentW) {
$(this).width(parentW)
$(this).height(parentW / imgR)
$(this).css('margin-top', (parentH - (parentW / imgR)) / 2)
} else {
$(this).css('margin-top', (parentH - imgH) / 2)
6、信息列表添加“...”
<style>
.s3lm-lists {height: 216px;overflow: hidden;}
.s3lm-item {position: relative;}
.s3lm-item li {line-height: 36px;padding-left: 10px;background: url(icon_dotted.png) 0 16px no-repeat;}
.s3lm-item li a {display: block;width: 100%;position: relative;}
.s3lm-item li span {margin-left: 2em;}
.s3lm-item li ins {width: 30px;height: 36px;background-color: #fff;position: absolute;right: 0;}
</style>
<div class="s3lm-lists">
<ul class="s3lm-item">
<li><a href="">这是多行信息超出固定高度后添加“...”的示例<span>2020-09-07</span></a></li>
<li><a href="">这是多行信息超出固定高度后添加“...”的示例<span>2020-09-07</span></a></li>
<li><a href="">这是多行信息超出固定高度后添加“...”的示例<span>2020-09-07</span></a></li>
<li><a href="">这是多行信息超出固定高度后添加“...”的示例这是多行信息超出固定高度后添加“...”的示例这是多行信息超出固定高度后添加“...”的示例<span>2020-09-07</span></a></li>
<li><a href="">这是多行信息超出固定高度后添加“...”的示例<span>2020-09-07</span></a></li>
<li><a href="">这是多行信息超出固定高度后添加“...”的示例<span>2020-09-07</span></a></li>
</div>
<script>
* 信息列表加“...”
* @param {ele} 要处理ul的class名称
function addEllipsis(ele, isBorder) {
var curPart = $(ele).filter(function () {
return $(this).is(':visible') // 获取当前显示的列表
curPart.each(function () {
var fixedHeight = $(this).outerHeight(); // 获取列表外盒子的固定高度
var liOriginH = 0;
var liLineHeight = parseInt($(this).find("li").eq(0).css("line-height")); // 获取行高
$(this).find('li').each(function() {
var liHeight = 0
if (isBorder) {
liHeight = Math.floor($(this).outerHeight() / liLineHeight) * liLineHeight
$(this).outerHeight(liHeight)
} else {
liHeight = $(this).outerHeight(); // 获取每个li的高度
liOriginH += liHeight; // 获取当前li的总高度
if (liOriginH >= fixedHeight) {
if (liOriginH > fixedHeight) { // li的高度超过外盒子固定高度,给超过高度的li加上'...'
if ($(this).has('ins').length === 0) { // 避免重复添加
$(this).append('<ins>...</ins>');
var hideH = liOriginH - fixedHeight // 获取超出部分的高度
var t = $(this).outerHeight() - hideH - liLineHeight; // 获取'...'的定位高度
$(this).find('ins').css('top', t)
// $(this).find('span').css('bottom', hideH) // 给时间设置定位
$(this).hover(function() { // 鼠标滑过显示超出部分内容
$(this).find('ins').hide(300)
$(this).parent('ul').stop().animate({ 'top': -hideH }, 300)
// $(this).find('span').stop().animate({ 'bottom': 0 }, 300)
}, function() {
$(this).find('ins').show(300)
$(this).parent('ul').stop().animate({ 'top': 0 }, 300)
// $(this).find('span').stop().animate({ 'bottom': hideH }, 300)
return false;
</script>
7、解决父元素设置 ; 时,子元素 iframe 中 js 获取不到具体元素值的问题
场景:一个下拉列表设置隐藏,鼠标滑过其父元素时显示,下拉列表是用 iframe 嵌入的,iframe 中有 js 动态修改元素的 width
问题:设置 ; 时,子元素中 js 获取不到具体的 width 值
解决思路:
- js 方法,在鼠标滑过时刷新 iframe,网上的方法有:
- 用 iframe 的 name 属性定位
- document.frames('ifrmname').location.reload() ---》报错
- document.all.ifrmname.document.location.reload() --》报错
- 用 iframe 的 id 属性定位
- ifrmid.window.location.reload() ---》跨域(挺奇怪的,页面都在本地,还会出现跨域,希望有大神能解答下,谢谢)
- 当 iframe 的 src 为其它网站地址(跨域操作时)
- window.open(document.all.ifrmname.src,'ifrmname','') ---》可行
- js 刷新
- document.getElementById('some_frame_id').contentWindow.location.reload(); ---》跨域
- document.getElementById('gh_dorpdown_iframe').src = document.getElementById('gh_dorpdown_iframe').name ---》建议name放链接,就不会出现页面闪动的情况
- jq 刷新
- $('#iframe').attr('src', $('#iframe').attr('name')); ---》议 name 放链接,就不会出现页面闪动的情况,和 js 第二种方式类似,主要的通过改变 src 来重新加载,问题是有时会出现 iframe 没加载出来的情况,页面空白,没找到原因,希望有大神能解答下,谢谢
按需求来说,只需要鼠标滑过下拉显示,离开下拉隐藏,所以可以不用考虑 iframe 刷新,只需考虑元素隐藏显示即可
元素隐藏的方法(除开 ):
- /visible
- 浏览器对其渲染不可见,占据空间却不可点击,能继承,但子元素可设置visible来显示;transition 对hidden -> visible 无效,对 visible -> hidden 有效;设置 position:absolute/fixed 或 float:left/right,可不占空间,原理是元素脱离了文档流
- 不占据空间,不可点击,该元素及其后代一概不渲染,transition 不起作用
- opacity:0;
- 占据空间,可点击,能继承,但子元素可设置 opacity:1 或 rgba(x,x,x,1) 来显示,transition 起作用
- 不兼容 ie8
- position/float,将元素移到可视窗口外即可
- overfloat:hidden/visible
- 通过改变 width/height 实现
- transform:scale(0)
- 元素缩放无限小,元素所在的位置将保留
- <div hidden="hidden"></div>
- H5属性,效果和 ; 相同
- filter:blur(0)
- Css3 属性,将元素的模糊度设置为0
- clip-path: polygon(0px 0px, 0px 0px, 0px 0px, 0px 0px);
- 兼容性不是很好,具体看 MDN
8、标签栏切换
/**
* 栏目导航切换
* @param item // 鼠标滑过的项
* @param active // 当前的项
* @param list // 要显示的项
function switchNav(item, active, more, list) {
$(item).mouseover(function() {
if (!$(this).hasClass('on')) {
$(this).addClass(active).siblings(item).removeClass(active);
} else {
$(this).siblings(item).removeClass(active)
var index = $(this).index(item);
$(more).eq(index).removeClass("hide").siblings(more).addClass("hide");
$(list).eq(index).removeClass("hide").siblings(list).addClass("hide");
9、头部高亮、当前栏目高亮、当前位置去掉 table
// 头部高亮
$(document).ready(function () {
if ($('.current-position').find('a').length > 0) {
var currentCol = $.trim($('.current-position').find('a')[1].text)
var isHome = false
$('.nav .auto').find('a').map(function () {
$(this).removeClass('bc')
if ($.trim($(this)[0].text) === currentCol) {
isHome = true
$(this).addClass(' bc')
if (!isHome) {
$('.nav .auto').find('a').eq(0).addClass(' bc')
// 当前栏目高亮
$(document).ready(function () {
var currentCol = $.trim($('meta[name="ColumnName"]').attr('content'))
$('.column-col').find('li').map(function () {
if ($.trim($(this).find('a').eq(0)[0].text) === currentCol) {
$(this).addClass(' active').siblings('li').removeClass('avtive')
// 当前位置去掉table
$(document).ready(function() {
var currentA = ''
$('.current-position .w1200').find('a').map(function(index) {
if (index > 0) {
currentA += ' > ' + $(this)[0].outerHTML
} else {
currentA += $(this)[0].outerHTML
$('.current-position .w1200').html(currentA)
10、js 动态引入 script 标签
function loadScript(url, callback) {
var script = document.createElement('script');
var head = document.getElementsByTagName('head')[0];
script.type = 'text/javascript';
script.charset = 'UTF-8';
script.src = url;
if (script.addEventListener) {
script.addEventListener('load', function() {
callback();
}, false);
} else if (script.attachEvent) {
script.attachEvent('onreadystatechange', function() {
var target = window.event.srcElement;
if (target.readyState == 'loaded') {
callback();
head.appendChild(script);
loadScript('xxx.js', function() {
console.log('加载完成')
11、$.ajax 在 ie8、ie9 下失效的问题:
- IE 浏览器设置:“工具->Internet 选项->安全->自定义级别”->“其他”->“通过域访问数据源”->“启用”
- 设置了浏览器的安全设置后,axios、angular 的 $http 以及原生 XMLHttpRequest 请求(原生可请求成功)都可以成功请求,jq 的话还是需要设置 jQuery.support.cors = true; 才可以请求( jq 未验证)
12、将类数组转化为数组
- slice:原始方法
let arr = Array.prototype.slice.call(arguments)
// 等同于
let arr1 = [].slice.call(arguments)
- from:ES6 方法
let arr = Array.from(arguments)
- ...(扩展运算符):ES6 方法
let arr = [...arguments]
- makeArray:jquery 方法
let arr = $.makeArray(arguments)
13、swiper 2.x 版本基本使用
<!-- 引入css、js文件 -->
<link rel="stylesheet" href="images/swiper.2.x.css">
<script type="text/javascript" src="./images/swiper.2.x.min.js"></script>
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">slider1</div>
<div class="swiper-slide">slider2</div>
<div class="swiper-slide">slider3</div>
</div>
<div class="pagination"></div>
</div>
<script type="text/javascript">
$(document).ready(function() {
var mySwiper = new Swiper('.swiper-container',{
loop: true, // 无限循环切换
autoplay : 3000, // 自动切换
speed:1000, // 滑动速度
autoplayDisableOnInteraction : false, // 如果设置为false,用户操作swiper之后自动切换不会停止,每次都会重新启动autoplay
pagination : '.pagination', // 分页器
paginationClickable :true, // 分页器可点击
// 鼠标悬停停止切换、移除开始切换
$('.swiper-container').mouseenter(function() {
mySwiper.stopAutoplay();
}).mouseleave(function() {
mySwiper.startAutoplay()
// 分页器添加页码
$('.pagination').find('.swiper-pagination-switch').map(function(index,item) {
$(this).text(index + 1)
</script>