DOM相关
判断浏览器是否支持placeholder属性
function placeholderSupport() {
return 'placeholder' in document.createElement('input');
}
html代码用JS动态加载进页面
<script type="text/html" id="T-pcList">
//这里面是你要放的html代码,例如放一个div的内容
</script>
把上面的js动态加入到页面中:
$(function(){
var s=$("#T-pcList").html();//获得js的html内容
$(".picScroll-left .bd").html(s);//把s的内容放到class为bd内
thisstyle();//执行某个函数
});
点击某个div区域之外,隐藏该div
$(document).bind("click",function(e){
var target = $(e.target);
if(target.closest(".city_box,#city_select a.selected").length == 0){
$(".city_box").hide();
}
})
更全的方式:
$(document).click(function(e){
var _con = $(' 目标区域 '); // 设置目标区域
if(!_con.is(e.target) && _con.has(e.target).length === 0){ // Mark 1
some code... // 功能代码
}
});
/* Mark 1 的原理:
判断点击事件发生在区域外的条件是:
1. 点击事件的对象不是目标区域本身
2. 事件对象同时也不是目标区域的子元素
*/
如何在手机上禁止浏览器的网页滚动
方法一:
<body ontouchmove="event.preventDefault()" >
方法二:
document.addEventListener('touchmove', function(event) {
event.preventDefault();
})
改变type=file默认样式,"浏览"等字体
<input type="file" id="browsefile" style="visibility:hidden" onchange="filepath.value=this.value">
<input type="button" id="filebutton" value="" onclick="browsefile.click()">
<input type="textfield" id="filepath">
JS动态创建css样式添加到head内
function addCSS(cssText){
var style = document.createElement('style');
var head = document.head || document.getElementsByTagName('head')[0];
style.type = 'text/css';
if(style.styleSheet){ //IE
var func = function(){
try{
//防止IE中stylesheet数量超过限制而发生错误
style.styleSheet.cssText = cssText;
}catch(e){ }
}
//如果当前styleSheet还不能用,则放到异步中则行
if(style.styleSheet.disabled){
setTimeout(func,10);
}else{
func();
}
}else{ //w3c
//w3c浏览器中只要创建文本节点插入到style元素中就行了
var textNode = document.createTextNode(cssText);
style.appendChild(textNode);
}
//把创建的style元素插入到head中
head.appendChild(style);
} //使用
addCSS('#demo{ height: 30px; background:#f00;}');
在IE8以及其低版本浏览器下,IE独有属性styleSheet.cssText。所以一般的兼容简单写法:
var style = document.createElement('style');
style.type = "text/css";
if (style.styleSheet) { //IE
style.styleSheet.cssText = '/*..css content here..*/';
} else { //w3c
style.innerHTML = '/*..css content here..*/';
}
document.getElementsByTagName('head')[0].appendChild(style);
为什么Image对象的src属性要写在onload事件后面?
var image=new Image();
imgae.onload = funtion;
imgae.src = 'url'
js内部是按顺序逐行执行的,可以认为是同步的。
给imgae赋值src时,去加载图片这个过程是异步的,这个异步过程完成后,如果有onload,则执行onload。
如果先赋值src,那么这个异步过程可能在你赋值onload之前就完成了(比如图片缓存,或者是js由于某些原因被阻塞了),那么onload就不会执行。
反之,js同步执行确定onload赋值完成后才会赋值src,可以保证这个异步过程在onload赋值完成后才开始进行,也就保证了onload一定会被执行到
js实现insertAfter方法
DOM里还有一个insertBefore方法用于再节点前面附件内容,通过insertBefore和appendChild我们可以实现自己的insertAfter函数:
// 'Target'是DOM里已经存在的元素
// 'Bullet'是要插入的新元素 function insertAfter(target, bullet) {
target.nextSibling ?
target.parentNode.insertBefore(bullet, target.nextSibling)
: target.parentNode.appendChild(bullet);
} // 使用了3目表达式:
// 格式:条件?条件为true时的表达式:条件为false时的表达式
上面的函数首先检查target元素的同级下一个节点是否存在,如果存在就在该节点前面添加bullet节点,如果不存在,就说明target是最后一个节点了,直接在后面append新节点就可以了。DOM API没有给提供insertAfter是因为真的没必要了——我们可以自己创建。
javascript删除元素节点
IE中有这样一个方法:removeNode(),这个方法在IE下是好使的,但是在Firefox等标准浏览器中就会报错了 removeNode is not defined,但是在核心JS中有一个操作DOM节点的方法叫:removeChild()。
我们可以先去找到要删除节点的父节点,然后在父节点中运用removeChild来移除我们想移除的节点。我们可以定义一个方法叫removeElement:
function removeElement(_element){
var _parentElement = _element.parentNode;
if(_parentElement){
_parentElement.removeChild(_element);
}
}
HTML代码:
<div><input onclick="removeElement(this)" type="text" value="点击移除该输入框" /></div>
BOM相关
JS判断当前窗口是否有父窗口
if(top.location!=self.location){ //有父窗口
top.location = "https://www.baidu.com";
}else{ //没有父窗口
window.location.href = "https://www.baidu.com";
}
- "window.location.href"、"location.href"是本页面跳转
- "parent.location.href"是上一层页面跳转
- "top.location.href"是最外层的页面跳转
- "window.location.reload()": 当前页面刷新
- "parent.location.reload()": 上一层页面刷新
- "top.location.reload()": 最外层页面刷新
使用console.time打印代码执行时间
用console.time
和console.timeEnd
中间代码执行时长来测试间隔时间。
console.time('console');
console.log('test');
console.timeEnd('console');
打印页面window.print()
function Printpart(id_str){ //id-str内容中的id
var el = document.getElementById(id_str);
var iframe = document.createElement('IFRAME');
var doc = null;
iframe.setAttribute('style', 'position:absolute;width:0px;height:0px;left:-500px;top:-500px;');
document.body.appendChild(iframe);
doc = iframe.contentWindow.document;
doc.write('<div>' + el.innerHTML + '</div>');
doc.close();
iframe.contentWindow.focus();
iframe.contentWindow.print();
if (navigator.userAgent.indexOf("MSIE") > 0){
document.body.removeChild(iframe);
}
}
参考地址:
- http://www.cnblogs.com/yeminglong/archive/2012/12/03/2799957.html
- http://www.cnblogs.com/jikey/archive/2011/06/22/2087683.html
页面刷新location.reload和location.replace的区别
reload 方法
该方法强迫浏览器刷新当前页面。
语法:
location.reload([bForceGet])
参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取当前页。true, 则以 GET 方式,从服务端取最新的页面, 相当于客户端点击 F5("刷新")
replace 方法
该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,你不能通过“前进”和“后退”来访问已经被替换的URL。
语法:
location.replace(URL)
在实际应用的时候,重新刷新页面的时候,我们通常使用: location.reload() 或者是 history.go(0) 来做。因为这种做法就像是客户端点F5刷新页面,所以页面的method="post"的时候,会出现“网页过期”的提示。那是因为Session的安全保护机制。可以想到: 当调用 location.reload() 方法的时候, aspx页面此时在服务端内存里已经存在, 因此必定是 IsPostback 的。如果有这种应用: 我们需要重新加载该页面,也就是说我们期望页面能够在服务端重新被创建, 我们期望是 Not IsPostback 的。这里,location.replace() 就可以完成此任务。被replace的页面每次都在服务端重新生成。你可以这么写:location.replace(location.href)
JS中的文档模式-document.compatMode(老版本)
IE对盒模型的渲染在 Standards Mode和Quirks Mode是有很大差别的,在Standards Mode下对于盒模型的解释和其他的标准浏览器是一样,但在Quirks Mode模式下则有很大差别,而在不声明Doctype的情况下,IE默认又是Quirks Mode。所以为兼容性考虑,我们可能需要获取当前的文档渲染方式。
document.compatMode正好派上用场,它有两种可能的返回值:BackCompat和CSS1Compat。
BackCompat:标准兼容模式关闭。浏览器客户区宽度是document.body.clientWidth;
CSS1Compat:标准兼容模式开启。 浏览器客户区宽度是document.documentElement.clientWidth。
例如:
function getViewport(){
if (document.compatMode == "BackCompat"){
return {
width: document.body.clientWidth,
height: document.body.clientHeight
}
}else{
return {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight
}
}
}
window.location属性
window.location 对象所包含的属性
属性 | 描述 |
---|---|
hash | 从井号 (#) 开始的 URL(锚) |
host | 主机名和当前 URL 的端口号 |
hostname | 当前 URL 的主机名 |
href | 完整的 URL |
pathname | 当前 URL 的路径部分 |
port | 当前 URL 的端口号 |
protocol | 当前 URL 的协议 |
search | 从问号 (?) 开始的 URL(查询部分) |
protocol 属性是一个可读可写的字符串,可设置或返回当前 URL 的协议。
语法:
location.protocol=path
实例:假设当前的 URL 是: http://example.com:1234/test.htm#part2:
document.write(location.protocol); //输出:http:
JS中的Navigator对象
Navigator 对象包含有关浏览器的信息。
注释:没有应用于 navigator 对象的公开标准,不过所有浏览器都支持该对象。
Navigator 对象属性:
属性 | 描写 |
---|---|
appCodeName | 返回浏览器的代码名。 |
appMinorVersion | 返回浏览器的次级版本。 |
appName |
返回浏览器的名称。 |
appVersion | 返回浏览器的平台和版本信息。 |
browserLanguage | 返回当前浏览器的语言。 |
cookieEnabled | 返回指明浏览器中是否启用 cookie 的布尔值。 |
cpuClass | 返回浏览器系统的 CPU 等级。 |
onLine | 返回指明系统是否处于脱机模式的布尔值。 |
platform | 返回运行浏览器的操作系统平台。 |
systemLanguage | 返回 OS 使用的默认语言。 |
userAgent |
返回由客户机发送服务器的 user-agent 头部的值。 |
userLanguage | 返回 OS 的自然语言设置。 |
在谷歌浏览器中打印Navigator对象,如图所示:
JS事件与位置坐标
跨浏览器添加事件
//跨浏览器添加事件
function addEvent(obj,type,fn){
if(obj.addEventListener){
obj.addEventListener(type,fn,false);
}else if(obj.attachEvent){//IE
obj.attchEvent('on'+type,fn);
}
}
跨浏览器移除事件
//跨浏览器移除事件
function removeEvent(obj,type,fn){
if(obj.removeEventListener){
obj.removeEventListener(type,fn,false);
}else if(obj.detachEvent){//兼容IE
obj.detachEvent('on'+type,fn);
}
}
跨浏览器阻止默认行为
//跨浏览器阻止默认行为
function preDef(ev){
var e = ev || window.event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue =false;
}
}
阻止事件冒泡
function stopPro(evt) {
var e = evt || window.event;
window.event ? e.cancelBubble = true : e.stopPropagation();
}
跨浏览器获取目标对象
//跨浏览器获取目标对象
function getTarget(ev){
if(ev.target){//w3c
return ev.target;
}else if(window.event.srcElement){//IE
return window.event.srcElement;
}
}
跨浏览器获取滚动条位置
//跨浏览器获取滚动条位置
function getSP(){
return{
top: document.documentElement.scrollTop || document.body.scrollTop,
left : document.documentElement.scrollLeft || document.body.scrollLeft;
}
}
跨浏览器获取可视窗口大小
//跨浏览器获取可视窗口大小
function getWindow () {
if(typeof window.innerWidth !='undefined') { //IE8及以下undefined
return{
width : window.innerWidth,
height : window.innerHeight
} }else{
return {
width : document.documentElement.clientWidth,
height : document.documentElement.clientHeight
}
}
}
跨浏览器获取Style
function getStyle(element, attr) {
if (typeof window.getComputedStyle != 'undefined') {//W3C
return window.getComputedStyle(element, null)[attr];
} else if (typeof element.currentStyle != 'undeinfed') {//IE
return element.currentStyle[attr];
}
}
JS获取相对于文档坐标
function getMousePos(event) {
var e = event || window.event;
var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
var x = e.pageX || e.clientX + scrollX;
var y = e.pageY || e.clientY + scrollY;
//alert('x: ' + x + '\ny: ' + y);
return { 'x': x, 'y': y };
}
js拖拽效果
<!doctype html>
<html lang="zn-CN">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title></title>
<style type="text/css">
#login{
height: 100px;
width: 100px;
border: 1px solid black;
position: relative;
top:200px;
left: 200px;
background: red;
}
</style>
</head>
<body>
<div id="login"></div>
<script type="text/javascript">
var oDiv = document.getElementById("login");
oDiv.onmousedown = function(e){
var e = e || window.event;//window.event兼容IE,当事件发生时有效 var diffX = e.clientX - oDiv.offsetLeft;//获取鼠标点击的位置到所选对象的边框的水平距离
var diffY = e.clientY - oDiv.offsetTop; document.onmousemove = function(e){ //需设为document对象才能作用于整个文档
var e = e||window.event;
oDiv.style.left = e.clientX - diffX + 'px';//style.left表示所选对象的边框到浏览器左侧距离
oDiv.style.top = e.clientY -diffY + 'px';
};
document.onmouseup = function(){
document.onmousemove = null;//清除鼠标释放时的对象移动方法
document.onmouseup = null;
}
}
</script>
</body>
</html>
offsetTop 返回的是数字,而 style.top 返回的是字符串,除了数字外还带有单位:px。
上下文菜单事件:contextmenu
当我们右击网页的时候,会自动出现 windows 自带的菜单。那么我们可以使用 contextmenu 事件来修改我们指定的菜单,但前提是把右击的默认行为取消掉。
function addEvent(obj, type, fn) { //添加事件兼容
if (obj.addEventListener) {
obj.addEventListener(type, fn);
} else if (obj.attachEvent) {
obj.attachEvent('on' + type, fn);
}
}
function removeEvent(obj, type, fn) { //移除事件兼容
if (obj.removeEventListener) {
ob j.removeEventListener(type, fn);
} else if (obj.detachEvent) {
obj.detachEvent('on' + type, fn);
}
} addEvent(window, 'load', function () {
var text = document.getElementById('text');
addEvent(text, 'contextmenu', function (evt) {
var e = evt || window.event;
preDef(e);
var menu = document.getElementById('menu');
menu.style.left = e.clientX + 'px';
menu.style.top = e.clientY + 'px';
menu.style.visibility = 'visible';
addEvent(document, 'click', function () {
document.getElementById('myMenu').style.visibility = 'hidden';
});
});
});
给table表格中的每个td绑定事件,td数量为1000+,写一下你的思路(事件委托题)
<body class="container">
<table id="table">
<tr><td>我们是@IT·平头哥联盟</td><td>,我是首席填坑官</td><td>苏南</td><td>前端开发</td><td>优秀</td></tr>
<tr><td>我们是@IT·平头哥联盟</td><td>,我是首席填坑官</td><td>苏南</td><td>前端开发</td><td>优秀</td></tr>
<tr><td>我们是@IT·平头哥联盟</td><td>,我是首席填坑官</td><td>苏南</td><td>前端开发</td><td>优秀</td></tr>
…………
</table>
<script>
let table =document.querySelector("#table");
table.addEventListener("click",(e)=>{
let {nodeName} = e.target;
if(nodeName.toUpperCase() === "TD"){
console.log(e.target);//<td>N</td>
}
},false); </script>
</body>
数组与对象
对象的判空
- 将json对象转化成json字符串,然后进行判断是否等于字符串'{}',直接写{}无法进行判断
let isObject = {};
console.log(JSON.stringify(isObject) == '{}');
- 使用for循环来判断,若不为空,则返回false
let listObject = { a: 1, b: 3, c: 4 };
function isEmptyObject() {
for(let key in listObject) {
return false;
}
return true;
}
console.log(isEmptyObject());
- 使用Object.keys()来判断,返回的是一个数组,根据数组长度来判断
function isEmptyObject2(obj) {
return Object.keys(obj).length == 0;
}
console.log(isEmptyObject2(isObject));
对这个对象中一定存在的属性进行判断
console.log(isObject.id == null);
用对象的属性查找数组里的对象
var inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
]; function findCherries(fruit) {
return function(value){
return value.name == fruit
}
}
console.log(inventory.find(findCherries('cherries'))); // { name: 'cherries', quantity: 5 }
将对象转换成数组Object.values()
Object.values()
方法返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for...in
循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。
var obj = { foo: 'bar', baz: 42 };
console.log(Object.values(obj)); // ['bar', 42] // array like object
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj)); // ['a', 'b', 'c'] // array like object with random key ordering
// when we use numeric keys, the value returned in a numerical order according to the keys
var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.values(an_obj)); // ['b', 'c', 'a'] // getFoo is property which isn't enumerable
var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });
my_obj.foo = 'bar';
console.log(Object.values(my_obj)); // ['bar'] // non-object argument will be coerced to an object
console.log(Object.values('foo')); // ['f', 'o', 'o']
Object.values()详细参考地址:《MDN:Object.values(obj)
》
将类数组对象转换成数组
- Array.prototype.slice.call(arguments)或者[].slice.call(arguments)
/* 该方法可以将类数组对象转换为数组,所谓类数组对象,就是含 length 和索引属性的对象
* 返回的数组长度取决于对象 length 属性的值,并且非索引属性的值或索引大于 length 的值都不会被返回到数组中
* Array.prototype.slice.call(obj,start,end) start:方法中slice截取的开始位置,end终止位置,默认从0开始
* */
let testObject = {
0: 'a',
1: 'b',
2: 'c',
name: 'admin',
length: 3,
}; /* 对象中必须定义length,且属性值不能为非数字,非数字无法返回 */
console.log(Array.prototype.slice.call(testObject)); /* 或者简写为[].slice.call(testObject) */
console.log([].slice.call(testObject));
- Array.from()
/* Array、Set、Map 和字符串都是可迭代对象(WeakMap/WeakSet 并不是可迭代对象)
* 这些对象都有默认的迭代器,即具有 Symbol.iterator 属性
* 所有通过生成器创建的迭代器都是可迭代对象
* 可以用 for of 循环
* */
let testObject2 = {
0: 'a',
1: 'b',
2: 'c',
name: 'admin',
length: 3,
};
console.log(Array.from(testObject2));
判断是否为数组
let temporaryArray3 = [1,2,1,2,3];
console.log(temporaryArray3 instanceof Array);
console.log(temporaryArray3.constructor == Array);
console.log(Array.isArray(temporaryArray3));
console.log(Object.prototype.toString.call(temporaryArray3) === "[object Array]");
将数组转换成键值对对象
let transformObject = Object.assign({}, temporaryArray3);
console.log(transformObject);
let transformObject2 = {...temporaryArray3};
console.log(transformObject2);
深拷贝与浅拷贝
较常用的对象深拷贝方法:
let copyObject = JSON.parse(JSON.stringify(obj));
Object.assign
- assign对对象分配赋值,实现浅拷贝,但是它有一个特殊的地方,可以处理第一层的深拷贝。
- assign(targetObject, obj, obj1) assign会改变targetObject的值,较好的做法就是将targetObject定义为空对象{}
- assign是将这个3者合并,若有相同的属性,后面的属性会覆盖前面对象的属性
let temporaryObject2 = {a: 1, d: {e: 3}};
let temporaryObject3 = {b: 1,a: 2};
let mergeObject = Object.assign({}, temporaryObject2, temporaryObject3);
console.log(mergeObject);
/* mergeObject.d.e不会改变temporaryObject2里a的值,但会改变temporaryObject2里e的值 */
mergeObject.a = 5;
mergeObject.d.e = 5;
console.log(mergeObject);
数组slice浅拷贝
let copyArray1 = copyArray.slice(0);
数组concat浅拷贝
let copyArray2 = copyArray.concat();
...扩展运算符
const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;
上面的两种写法,a2
都是a1
的克隆。
生成由随机整数组成的数组,数组长度和元素大小可自定义
const genNumArr = (length, limit) =>
Array.from({ length }, _ => Math.floor(Math.random() * limit)); genNumArr(10, 100);
JS 将有父子关系的数组转换成树形数据
data.forEach(ele => {
let parentId = ele.parentId;
if (parentId === 0) {
//是根元素的hua ,不做任何操作,如果是正常的for-i循环,可以直接continue.
} else {
//如果ele是子元素的话 ,把ele扔到他的父亲的child数组中.
data.forEach(d => {
if (d.id === parentId) {
let childArray = d.child;
if (!childArray) {
childArray = []
}
childArray.push(ele);
d.child = childArray;
}
})
}
});
//去除重复元素
data = data.filter(ele => ele.parentId === 0);
console.log('最终等到的tree结构数据: ', data);
使用sort方法根据数组中对象的某一个属性值进行升序或者降序排列
/**数组根据数组对象中的某个属性值进行排序的方法
* 使用例子:newArray.sort(sortBy('number',false)) //表示根据number属性降序排列;若第二个参数不传递,默认表示升序排序
* @param attr 排序的属性 如number属性
* @param rev true表示升序排列,false降序排序
* */
sortBy: function(attr,rev){
//第二个参数没有传递 默认升序排列
if(rev == undefined){
rev = 1;
}else{
rev = (rev) ? 1 : -1;
} return function(a,b){
a = a[attr];
b = b[attr];
if(a < b){
return rev * -1;
}
if(a > b){
return rev * 1;
}
return 0;
}
}
Object.create()的不完整polyfilll
没有 Object.create、Object.setPrototypeOf 的早期版本中,new 运算是唯一一个可以指定 [[prototype]] 的方法(当时的 mozilla 提供了私有属性 __proto__,但是多数环境并不支持),所以,当时已经有人试图用它来代替后来的 Object.create,我们甚至可以用它来实现一个 Object.create 的不完整的 polyfill,见以下代码:
Object.create = function(prototype){
function F(){};
F.prototype = prototype;
return new F();
}
这段代码创建了一个空的构造函数作为类,并把传入的原型挂在了它的 prototype,最后创建了一个它的实例,根据 new 的行为,这将产生一个以传入的第一个参数为原型的对象。
注:这个函数无法做到与原生的 Object.create 一致,一个是不支持第二个参数,另一个是不支持 null 作为原型,所以放到今天意义已经不大了。
日期对象Date
获取当前日期
var calculateDate = function(){
var date = newDate();
var weeks = ["日","一","二","三","四","五","六"];
return date.getFullYear()+"年"+(date.getMonth()+1)+"月"+
date.getDate()+"日 星期"+weeks[date.getDay()];
}
$(function(){
$("#dateSpan").html(calculateDate());
})
时间倒计时(固定倒计时的结束时间)
functioncountdown(){
var endtime = newDate("Jan 18, 2015 23:50:00");
var nowtime = newDate();
if (nowtime >= endtime) {
document.getElementById("_lefttime").innerHTML = "倒计时间结束";
return;
}
var leftsecond = parseInt((endtime.getTime() - nowtime.getTime()) / 1000);
if (leftsecond < 0) {
leftsecond = 0;
}
__d = parseInt(leftsecond / 3600 / 24);
__h = parseInt((leftsecond / 3600) % 24);
__m = parseInt((leftsecond / 60) % 60);
__s = parseInt(leftsecond % 60);
document.getElementById("_lefttime").innerHTML = __d + "天" + __h + "小时" + __m + "分" + __s + "秒";
}
countdown();
setInterval(countdown, 1000);
js获取某年某月的哪些天是周六和周日
function time(y,m){
var tempTime = newDate(y,m,0);
var time = newDate();
var saturday = newArray();
var sunday = newArray();
for(var i=1;i<=tempTime.getDate();i++){
time.setFullYear(y,m-1,i);
var day = time.getDay();
if(day == 6){
saturday.push(i);
}elseif(day == 0){
sunday.push(i);
}
}
var text = y+"年"+m+"月份"+"<br />"
+"周六:"+saturday.toString()+"<br />"
+"周日:"+sunday.toString();
document.getElementById("text").innerHTML = text;
} time(2014,7);
内置对象Math
随机产生lowwer - upper之间的随机数
function selectFrom(lower, upper) {
var sum = upper - lower + 1; //总数-第一个数+1
return Math.floor(Math.random() * sum + lower);
};
正则表达
保留后端传递到前端页面的空格
var objt = {
name:' aaaa 这是一个空格多的标签 这是一个空格多的标签'
}
objt.name = objt.name.replace(/\s/g,' ');
console.log(objt.name);
用firebug查看结果:
JS replace()方法全局替换变量
简单替换字符:string.replace("a","b"); (把 a 替换成 b)
全局替换字符:string.replace(/a/g,"b");(全局把a替换成b)
但是如果是全局替换一个变量内容,如下,给一个电话号码中间加*号:
var phone = "15512345678";
var sliceNumber = phone.slice(3,phone.length - 3);
var newPhone = phone.replace(new RegExp(sliceNumber,'g'),'****');
console.log(newPhone); //155****678
正则表达式中的RegExp.$1
RegExp
是javascript
中的一个内置对象。为正则表达式。RegExp.$1
是RegExp的一个属性,指的是与正则表达式匹配的第一个子匹配(以括号为标志)字符串,以此类推,RegExp.2, RegExp.3, ..RegExp.$99总共可以有99个匹配。
例如:
var r= /^(\d{4})-(\d{1,2})-(\d{1,2})$/; //正则表达式 匹配出生日期(简单匹配)
r.exec('1985-10-15');
s1=RegExp.$1;
s2=RegExp.$2;
s3=RegExp.$3;
console.log(s1+" "+s2+" "+s3)//结果为1985 10 15
用JS将 386485473.88 转换为 386,485,473.88(千位分割符)
//方法1:
var separator=(num)=>{
if(!num){
return '0.00';
};
let str = parseFloat(num).toFixed(2);
return str && str
.toString()
.replace(/(\d)(?=(\d{3})+\.)/g, function($0, $1) {
return $1 + ",";
});
} separator(386485473.88) //"386,485,473.88" //方法2:
(386485473.88).toLocaleString('en-US') // "386,485,473.88" 由 (sRect)补充
函数
求两个数的和 并以二进制输出
var m=3;
var n=5;
var sum=m+n;
var result = sum.toString(2);
console.log(result); //
二进制输出:toString
函数
使用 Proxy 实现观察者模式
观察者模式(Observer mode)指的是函数自动观察数据对象,一旦对象有变化,函数就会自动执行。
const person = observable({
name: '张三',
age: 20
}); function print() {
console.log(`${person.name}, ${person.age}`)
} observe(print);
person.name = '李四';
// 输出
// 李四, 20
上面代码中,数据对象person
是观察目标,函数print
是观察者。一旦数据对象发生变化,print
就会自动执行。
下面,使用 Proxy 写一个观察者模式的最简单实现,即实现observable
和observe
这两个函数。思路是observable
函数返回一个原始对象的 Proxy 代理,拦截赋值操作,触发充当观察者的各个函数。
const queuedObservers = new Set(); const observe = fn => queuedObservers.add(fn);
const observable = obj => new Proxy(obj, {set}); function set(target, key, value, receiver) {
const result = Reflect.set(target, key, value, receiver);
queuedObservers.forEach(observer => observer());
return result;
}
上面代码中,先定义了一个Set
集合,所有观察者函数都放进这个集合。然后,observable
函数返回原始对象的代理,拦截赋值操作。拦截函数set
之中,会自动执行所有观察者。
在firefox, chrome等浏览器里,完美模拟new操作
function A( name ){
this.name = name;
} function ObjectFactory(){
var obj = {},
Constructor = Array.prototype.shift.call( arguments );
obj.__proto__ = typeof Constructor.prototype === 'number' ? Object.prototype : Constructor.prototype;
var ret = Constructor.apply( obj, arguments );
return typeof ret === 'object' ? ret : obj;
}
var a = ObjectFactory( A, 'mr mo' );
console.log ( a.name ); //mr mo
form表单
form表单提交时设置编码格式
<form name="form" method="post" action="XXXX" accept-charset="utf-8" onsubmit="document.charset='utf-8';">
//内容
</form>
jQuery操作
JS,Jquery获取各种屏幕的宽度和高度
Javascript:
- 文档可视区域宽: document.documentElement.clientWidth
- 文档可视区域高: document.documentElement.clientHeight
- 网页可见区域宽: document.body.clientWidth
- 网页可见区域高: document.body.clientHeight
- 网页可见区域宽: document.body.offsetWidth(包括边线的宽)
- 网页可见区域高: document.body.offsetHeight (包括边线的高)
- 网页正文全文宽: document.body.scrollWidth
- 网页正文全文高: document.body.scrollHeight
- 网页被卷去的高: document.body.scrollTop
- 网页被卷去的左: document.body.scrollLeft
- 网页正文部分上: window.screenTop
- 网页正文部分左: window.screenLeft
- 屏幕分辨率的高: window.screen.height
- 屏幕分辨率的宽: window.screen.width
- 屏幕可用工作区高度: window.screen.availHeight
- 屏幕可用工作区宽度: window.screen.availWidth
JQuery:
$(document).ready(function(){
alert($(window).height()); //浏览器当前窗口可视区域高度
alert($(document).height()); //浏览器当前窗口文档的高度
alert($(document.body).height());//浏览器当前窗口文档body的高度
alert($(document.body).outerHeight(true));//浏览器当前窗口文档body的总高度 包括border padding margin alert($(window).width()); //浏览器当前窗口可视区域宽度
alert($(document).width());//浏览器当前窗口文档对象宽度
alert($(document.body).width());//浏览器当前窗口文档body的宽度
alert($(document.body).outerWidth(true));//浏览器当前窗口文档body的总宽度 包括border padding margin
})
jQuery取得select选择的文本与值
jquery获取select选择的文本、值、索引:
//获取select 选中的 text :
$("#ddlregtype").find("option:selected").text(); //获取select选中的 value:
$("#ddlregtype ").val(); //获取select选中的索引:
$("#ddlregtype ").get(0).selectedindex;
设置select选中的索引、选中的value:
//设置select 选中的索引:
$("#ddlregtype ").get(0).selectedindex=index;//index为索引值 //设置select 选中的value:
$("#ddlregtype ").attr("value","normal“);
$("#ddlregtype ").val("normal");
$("#ddlregtype ").get(0).value = value;
jquery获得select中option的索引实例:
html代码:
<select class="select-green">
<option value="0">高级客户经理</option>
<option value="1">中级客户经理</option>
</select>
jquery代码:
$(".select-green").change(function(){
var _indx = $(this).get(0).selectedIndex;
$(".selectall .selectCon").hide();
$(".selectall .selectCon").eq(_indx).fadeIn();
});
注:其中(this).get(0)与(this)[0]等价
jquery中带命名空间的事件(namespaced events)
带命名空间的事件(namespaced events)在jQuery 1.2就被加入了,但是没有几个人用,举例:
$('a').on('click', function() {
// Handler 1
});
$('a').on('click', function() {
// Handler 2
});
如果我们想要移除第二个handler, 使用$(‘a’).off(‘click’)确会把两个handler都移除掉!
但是如果使用带命名空间的事件,就可以搞定:
$('a').on('click.namespace1', function() {
//Handler 1
});
$('a').on('click.namespace2', function() {
//Handler 2
});
使用如下代码移除:
$('a').off('click.namespace2');
jquery对文本框只读状态与可读状态的相互转化
$('input').removeAttr('Readonly');
$('input').attr('Readonly','true');
移动端
js强制手机页面横屏显示
<script>
// Bind an event to window.orientationchange that, when the device is turned,
// gets the orientation and displays it to on screen.
$( window ).on( "orientationchange", function( event ) {
//alert (event.orientation )
if (event.orientation=='portrait') {
$('body').css('transform', 'rotate(90deg)');
} else {
$('body').css('transform', 'rotate(0deg)');
}
}); // You can also manually force this event to fire.
$( window ).orientationchange();
</script>
其它代码
JS判断用户访问的是PC还是mobile或者微信浏览器
var browser = {
versions:function(){
var u = navigator.userAgent.toLowerCase();
return {
trident: u.indexOf('trident') > -1,
presto: u.indexOf('presto') > -1,
isChrome: u.indexOf("chrome") > -1 && u.indexOf("safari") > -1 && !(u.indexOf("qqbrowser") > -1),
qqbrowser: u.indexOf("qqbrowser") > -1,
isFirefox: u.indexOf('firefox') > -1,
isSafari: !(u.indexOf("chrome") > -1) && (/webkit|khtml/).test(u) && u.indexOf('safari') > -1,
webKit: u.indexOf('applewebkit') > -1,
gecko: u.indexOf('gecko') > -1 && u.indexOf('khtml') == -1,
mobile: !!u.match(/applewebkit.*mobile.*/),
ios: !!u.match(/\(i[^;]+;( u;)? cpu.+mac os x/),
android: u.indexOf('android') > -1 || u.indexOf('linux') > -1,
iPhone: u.indexOf('iphone') > -1,
iPad: u.indexOf('ipad') > -1,
iWinPhone: u.indexOf('windows phone') > -1,
isWeiXin:!!u.match(/MicroMessenger/i)
}
}
}
if(browser.versions.mobile || browser.versions.iWinPhone){
console.log('手机');
}else{
console.log('pc');
}
js判断变量是否未定义的代码
一般如果变量通过var声明,但是并未初始化的时候,变量的值为undefined,而未定义的变量则需要通过 "typeof 变量"的形式来判断,否则会发生错误。
实际应用:
variable有的页面我们不定义,但有的页面定义了,就可以需要这样的判断方法,没有定义的就不执行。
if("undefined" != typeof variable){
if(variable=="abc"){
console.log('成功');
}
}
JS加入收藏代码
function addFavorite(title, url) {
url = encodeURI(url);
try {
window.external.addFavorite(url, title);
}
catch (e) {
try {
window.sidebar.addPanel(title, url, "");
}
catch (e) {
alert("加入收藏失败,Ctrl+D进行添加");
}
}
}
addFavorite(document.title,window.location);
获取上传文件的大小
html代码:
<input type="file" id="filePath" onchange="getFileSize(this)"/>
js代码:
//兼容IE9低版本获取文件的大小
function getFileSize(obj){
var filesize;
if(obj.files){
filesize = obj.files[0].size;
}else{
try{
var path,fso;
path = document.getElementById('filePath').value;
fso = new ActiveXObject("Scripting.FileSystemObject");
filesize = fso.GetFile(path).size;
}
catch(e){
//在IE9及低版本浏览器,如果不容许ActiveX控件与页面交互,点击了否,就无法获取size
console.log(e.message); //Automation 服务器不能创建对象
filesize = 'error'; //无法获取
}
}
return filesize;
}
限制上传文件的类型
如果是高版本浏览器,一般在HTML代码中写就能实现,如:
<input type="file" name="filePath" accept=".jpg,.jpeg,.doc,.docxs,.pdf">
如果限制上传文件为图片类型,如下:
<input type="file" class="file" value="上传" accept="image/*"/>
但是在其它低版本浏览器就不管用了,需要js来判断。
html代码:
<input type="file" id="filePath" onchange="limitTypes()"/>
js代码:
/* 通过扩展名,检验文件格式。
*@parma filePath{string} 文件路径
*@parma acceptFormat{Array} 允许的文件类型
*@result 返回值{Boolen}:true or false
*/
function checkFormat(filePath,acceptFormat){
var resultBool= false,
ex = filePath.substring(filePath.lastIndexOf('.') + 1);
ex = ex.toLowerCase();
for(var i = 0; i < acceptFormat.length; i++){
if(acceptFormat[i] == ex){
resultBool = true;
break;
}
}
return resultBool;
}; function limitTypes(){
var obj = document.getElementById('filePath');
var path = obj.value;
var result = checkFormat(path,['bmp','jpg','jpeg','png']);
if(!result){
alert('上传类型错误,请重新上传');
obj.value = '';
}
}
js 异步加载和同步加载
异步加载也叫非阻塞模式加载,浏览器在下载js
的同时,同时还会执行后续的页面处理。
在script
标签内,用js
创建一个script
元素并插入到document
中,这种就是异步加载js
文件了:
(function() {
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = 'http://yourdomain.com/script.js';
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
})();
同步加载,平常默认用的都是同步加载。如:
<script src="http://yourdomain.com/script.js"></script>
同步模式又称阻塞模式,会阻止流览器的后续处理。停止了后续的文件的解析,执行,如图像的渲染。浏览器之所以会采用同步模式,是因为加载的js
文件中有对dom
的操作,重定向,输出document
等默认行为,所以同步才是最安全的。
通常会把要加载的js
放到body
结束标签之前,使得js
可在页面最后加载,尽量减少阻塞页面的渲染。这样可以先让页面显示出来。
同步加载流程是瀑布模型,异步加载流程是并发模型。
跨域的几种方式
首先了解下浏览器的同源策略
同源策略/SOP(Same origin
policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSRF等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
那么怎样解决跨域问题的呢?
1 通过jsonp跨域
1.)原生实现:
<script>
var script = document.createElement('script');
script.type = 'text/javascript'; // 传参并指定回调执行函数为onBack
script.src = 'http://www.....:8080/login?user=admin&callback=onBack';
document.head.appendChild(script); // 回调执行函数
function onBack(res) {
alert(JSON.stringify(res));
}
</script>
2、 document.domain + iframe跨域
此方案仅限主域相同,子域不同的跨域应用场景。
1.)父窗口:(http://www.domain.com/a.html) <iframe id="iframe" src="http://child.domain.com/b.html"></iframe>
<script>
document.domain = 'domain.com';
var user = 'admin';
</script>
2.)子窗口:(http://child.domain.com/b.html) <script>
document.domain = 'domain.com';
// 获取父窗口中变量
alert('get js data from parent ---> ' + window.parent.user);
</script> 弊端:请看下面渲染加载优化 3、 nginx代理跨域
4、 nodejs中间件代理跨域
5、 后端在头部信息里面设置安全域名
更多跨域的具体内容请看《跨域详解》
纯前端JS读取与解析本地文本类文件
var reader = new FileReader();
reader.onload = function (event) {
// event.target.result就是文件文本内容
// 然后你就可以为所欲为了
// 例如如果是JSON数据可以解析
// 如果是HTML数据,可以直接插入到页面中
// 甚至字幕文件,各种滤镜,自定义文件格式,都可以……
};
reader.readAsText(file);
详细参考地址:小tips: 纯前端JS读取与解析本地文本类文件
前端通过Blob下载文件流
先看下网上一个简单的代码片段:
let blob = new Blob([res], {
type: `application / pdf` //word文档为msword,pdf文档为pdf
});
let objectUrl = URL.createObjectURL(blob);
let link = document.createElement("a");
let fname = `我的文档`; //下载文件的名字
link.href = objectUrl;
link.setAttribute("download", fname);
document.body.appendChild(link);
link.click();
全面:
/**
* @param {String} resource 文件流
* @param {String} fileType 文件类型
* @param {String} fileName 文件名
* */
var downloadBlob=function(resource,fileType,fileName){
var data = new Blob([resource],{
type:fileType
});
if('download' in document.createElement('a')){ //非IE
var downloadUrl = window.URL.createObjectURL(data);
var anchor = document.createElement("a");
anchor.href = downloadUrl;
anchor.download = fileName;
anchor.style.display = 'none';
document.body.appendChild(anchor);
anchor.click();
window.URL.revokeObjectURL(anchor.href);
document.body.removeChild(anchor);
}else{ //IE10+下载
navigator.msSaveBlob(data, fileName);
} }
调用方式:
downloadBlob(res,'application/pdf','文档名称')
使用html2canvas保存页面为图片并下载
html2canvas官网:http://html2canvas.hertzen.com/
<script type="text/javascript" src="js/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="js/html2canvas.min.js"></script>
<script type="text/javascript">
$(function(){
$('#button').on('click',function(){
html2canvas(document.querySelector("#capture")).then(canvas => {
document.body.appendChild(canvas);
let base64 = canvas.toDataURL('images/png');
let a = document.createElement('a');
a.href = base64;
a.download = 'download';
a.click();
});
})
})
</script>
vue给文本输入框聚焦位置添加内容
/**
* 文本聚焦位置添加新文本
* @param {Object} myField聚焦的DOM对象
* @param {String} myValue文本框初始值
* @result {String} 返回文本框的value值
* */
function insertTextFromFocus(myField,myValue){
//IE 浏览器
if (document.selection) {
myField.focus();
var sel = document.selection.createRange();
sel.text = myValue;
sel.select();
}
//FireFox、Chrome等
else if (myField.selectionStart || myField.selectionStart == '0') {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
// 保存滚动条
var restoreTop = myField.scrollTop;
myField.value = myField.value.substring(0, startPos) + myValue + myField.value.substring(endPos, myField.value.length);
if (restoreTop > 0) {
myField.scrollTop = restoreTop;
}
myField.focus();
myField.selectionStart = startPos + myValue.length;
myField.selectionEnd = startPos + myValue.length;
} else {
myField.value += myValue;
myField.focus();
}
return myField.value
}
调用方式:
this.dialogRepTemp.content = insertTextFromFocus(this.$refs.content.$el.children[0],data.variable)
TweenMax.js用法总结
markdown语法经常遗忘操作记录
删除线:~~ ~~
包裹的文字会显示删除线 删除线
web常用状态码整理
200:OK 请求成功。一般用于GET与POST请求
204:No Content 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
304:Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
400:Bad Request 客户端请求的语法错误,服务器无法理解
403:Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
404:Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
小tips
检查加载性能
一个网站加载性能如何主要看白屏时间和首屏时间。
- 白屏时间:指从输入网址,到页面开始显示内容的时间。
- 首屏时间:指从输入网址,到页面完全渲染的时间。
将以下脚本放在 </head>
前面就能获取白屏时间。
<script>
new Date() - performance.timing.navigationStart
</script>
首屏时间比较复杂,得考虑有图片和没有图片的情况。
如果没有图片,则在 window.onload
事件里执行 new Date() - performance.timing.navigationStart
即可获取首屏时间。
如果有图片,则要在最后一个在首屏渲染的图片的 onload
事件里执行 new Date() - performance.timing.navigationStart
获取首屏时间