Skip to content

js常见问题总结与分析 #18

@willson-wang

Description

@willson-wang
  1. 去掉数值的小数部分
console.log(parseInt(10.23));
console.log(~~10.23);
console.log(10.23 >> 0);
console.log(10.23 | 0);
  1. 数组最大值、最小值(不包含引用类型的值)
// 第一种方法
var maxArr = function (arr){
	return Math.max.apply(null, arr);
}

var minArr = function (arr){
	return Math.min.apply(null, arr);
}

// 第二种方法
arr.sort(function(a,b){return a - b;});//小到大
console.log(arr[arr.length - 1])//最大值
console.log(arr[0])//最小值
  1. 获取随机色
var getRandomColor = function (){
	return '#'+Math.random().toString(16).substr(2,6);
}
  1. 深拷贝(简单深拷贝)
var deepCopy = function (obj){
        //注意函数不能使用该方法进行深拷贝,因为stringify方法无法对函数进行转换
	return JSON.parse(JSON.stringify(obj));
}
  1. 类型检测
var util = (function (){
	var classtype;
	
	var init = function (){
		classtype = {};
		"Boolean Number String Function Array Date RegExp Object Error".split(" ").forEach(function (item, index){
				classtype["[object " + item + "]"] = item.toLowerCase();
		});
	}
	 return {
	 		checkType: function (obj){
	 			 if(!classtype){
	 			 		 init();
	 			 }
	 			 
	 			 if(obj == null){
				 		return obj + "";
				 }
	 			 
	 			 return typeof obj === "object" || typeof obj === "function" ? classtype[Object.prototype.toString.call(obj)] || "object" : typeof obj;
		 		}
		 }
})();
  1. 去空格
// 去两边空格
function trim(str) {
	return str.replace(/(^\s+)|(\s+$)/g, "");
}

// 去所有空格
function removeAllSpace(str) {
	return str.replace(/\s+/g, "");
}
  1. 替换对象内某个key对应的值
常规方法是遍历整个对象,然后对对象的某个key对应的value进行更改,现在使用JSON.stringify方法,先将对象转化成字符串,然后了利用正则来进行转化
var a = {
    name: 'jack',
    isRequired: true
}

JSON.parse(JSON.stringify(a).replace(/true/g, 1));

当对象内需要替换的属性值相同的较多时,而只需要替换某一个key对应的value,则上面的方法就不适用了

var b = {
    name: 'jack',
    isRequired: true,
    isShow: true
}
var str = JSON.stringify(b, (key, value) => {
  if ( key === 'isRequired') {
     return value ? 1 : 0;
  }
  return value;
})

JSON.parse(str);

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
  1. 设置日期的最大值与最小值
一般在使用日历插件的时候,需要设置最大日期与最小日期
最小日期一般很好获取,要么是个定值要么是当前值
const START_END_TIME = 7;
获取YYYY-MM-DD的日期格式
utilFormatDate(date) {
    const year = date.getFullYear();
    let month = date.getMonth() + 1;
    let day = date.getDate();
    let fixMonth = month >= 10 ? month : '0' + month;
    let fixDay = day >= 10 ? day : '0' + day;
    let newDate = `${year}-${fixMonth}-${fixDay}`;
    return newDate;
},

getStartAndEndDate() {
    const date = new Date();
    const startDate = this.utilFormatDate(date);
    // 设置相隔START_END_TIME天数,如7获取7天后的月日,-1获取昨天的月日等等
    date.setDate(date.getDate() + START_END_TIME)
    const endDate = this.utilFormatDate(date);
    console.log(startDate, endDate);
    return {
        startDate,
        endDate
    }
}

const {startDate, endDate} = this.getStartAndEndDate();
  1. focus/blur与focusin/focusout的区别与联系

    1. focus/blur不冒泡,focusin/focusout冒泡
    2. focus/blur兼容性好,focusin/focusout在除FireFox外的浏览器下都保持良好兼容性,如需使用事件托管,可考虑在FireFox下使用事件捕获elem.addEventListener('focus', handler, true)
    3. 可获得焦点的元素:
      1. window
      2. 链接被点击或键盘操作
      3. 表单空间被点击或键盘操作
      4. 设置tabindex属性的元素被点击或键盘操作
  2. mouseover/mouseout与mouseenter/mouseleave的区别与联系

    1. mouseover/mouseout是标准事件,所有浏览器都支持;mouseenter/mouseleave是IE5.5引入的特有事件后来被DOM3标准采纳,现代标准浏览器也支持
    2. mouseover/mouseout是冒泡事件;mouseenter/mouseleave不冒泡。需要为多个元素监听鼠标移入/出事件时,推荐mouseover/mouseout托管,提高性能标准事件模型中event.target表示发生移入/出的元素,vent.relatedTarget对应移出/如元素;在老IE中event.srcElement表示发生移入/出的元素,event.toElement表示移出的目标元素,event.fromElement表示移入时的来源元素
  3. cookie及其操作

    1. cookie是web浏览器存储的少量数据,最早设计为服务器端使用,作为HTTP协议的扩展实现。cookie数据会自动在浏览器和服务器之间传输。
    2. 通过读写cookie检测是否支持
      1. cookie属性有名,值,max-age,path, domain,secure;
      2. cookie默认有效期为浏览器会话,一旦用户关闭浏览器,数据就丢失,通过设置max-age=seconds属性告诉浏览器cookie有效期
      3. cookie作用域通过文档源和文档路径来确定,通过path和domain进行配置,web页面同目录或子目录文档都可访问
      4. 通过cookie保存数据的方法为:为document.cookie设置一个符合目标的字符串如下
      5. 读取document.cookie获得'; '分隔的字符串,key=value,解析得到结果
document.cookie = 'name=qiu; max-age=9999; path=/; domain=domain; secure';
document.cookie = 'name=aaa; path=/; domain=domain; secure';
  1. sessionStorage,localStorage,cookie区别

    1. 都会在浏览器端保存,有大小限制,同源限制
    2. cookie会在请求时发送到服务器,作为会话标识,服务器可修改cookie;web storage不会发送到服务器
    3. cookie有path概念,子路径可以访问父路径cookie,父路径不能访问子路径cookie
    4. 有效期:cookie在设置的有效期内有效,默认为浏览器关闭;sessionStorage在窗口关闭前有效,localStorage长期有效,直到用户删除
    5. 共享:sessionStorage不能共享,localStorage在同源文档之间共享,cookie在同源且符合path规则的文档之间共享
    6. localStorage的修改会促发其他文档窗口的update事件
    7. cookie有secure属性要求HTTPS传输
    8. 浏览器不能保存超过300个cookie,单个服务器不能超过20个,每个cookie不能超过4k。web storage大小支持能达到5M
    9. storage与cookie的读写操作方法不一样
  2. javascript跨域通信

    1. 同源:两个文档同源需满足
      1. 协议相同
      2. 域名相同
      3. 端口相同
    2. 跨域通信:js进行DOM操作、通信时如果目标与当前窗口不满足同源条件,浏览器为了安全会阻止跨域操作。
    3. 跨域通信通常有以下方法
      1. 如果是log之类的简单单项通信,新建,<script>,,<iframe>元素,通过src,href属性设
        置为目标url。实现跨域请求
      2. 如果请求json数据,使用<script>进行jsonp请求
      3. 现代浏览器中多窗口通信使用HTML5规范的targetWindow.postMessage(data, origin);其中data是需要发送的对象,origin是目标窗口的origin。window.addEventListener('message', handler, false);handler的event.data是postMessage发送来的数据,event.origin是发送窗口的origin,event.source是发送消息的窗口引用
      4. 内部服务器代理请求跨域url,然后返回数据(nginx代理跨域、nodejs中间件代理跨域)
      5. 跨域请求数据,现代浏览器可使用HTML5规范的CORS功能,只要目标服务器返回HTTP头部**Access-Control-Allow-Origin: ***即可像普通ajax一样访问跨域资源
通过jsonp跨域
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));
}

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)

document.domain = 'domain.com';
// 获取父窗口中变量
alert('get js data from parent ---> ' + window.parent.user);
  1. 什么闭包,闭包有什么用

    1. 闭包就是函数,一个能够读取其他函数内部变量的函数。
    2. 闭包作用域链通常包括三个部分:
      1. 函数本身作用域。
      2. 闭包定义时的作用域。
      3. 全局作用域。
    3. 闭包的特性
      1. 函数内再嵌套函数
      2. 内部函数可以引用外层的参数和变量
      3. 参数和变量不会被垃圾回收机制回收
    4. 闭包的理解
      1. 使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。在js中,函数即闭包,只有函数才会产生作用域的概念;闭包 的最大用处有两个,一个是可以读取函数内部的变量,让这些变量始终保持在内存中,另一个用处,是封装对象的私有属性和私有方法,好处:能够实现封装和缓存等;坏处:就是消耗内存、不正当使用会造成内存溢出的问题
      2. 使用闭包的注意点,由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露,解决方法是,在退出函数之前,将不使用的局部变量全部删除
  2. ===运算符判断相等的流程是怎样的

    1. 如果两个值不是相同类型,它们不相等
    2. 如果两个值都是null或者都是undefined,它们相等
    3. 如果两个值都是布尔类型true或者都是false,它们相等
    4. 如果其中有一个是NaN,它们不相等
    5. 如果都是数值型并且数值相等,他们相等, -0等于0
    6. 如果他们都是字符串并且在相同位置包含相同的16位值,那它们相等;
    7. 如果在长度或者内容上不等,它们不相等;两个字符串显示结果相同但是编码不同==和===都认为他们不相等
    8. 如果他们指向相同对象、数组、函数,它们相等;如果指向不同对象,他们不相等
  3. ==运算符判断相等的流程是怎样的

    1. 如果两个值类型相同,按照===比较方法进行比较
    2. 如果类型不同,使用如下规则进行比较
    3. 如果其中一个值是null,另一个是undefined,它们相等
    4. 如果一个值是数字另一个是字符串,将字符串转换为数字进行比较
    5. 如果有布尔类型,将true转换为1,false转换为0,然后用==规则继续比较
    6. 如果一个值是对象,另一个是数字或字符串,将对象转换为原始值然后用==规则继续比较
      其他所有情况都认为不相等
  4. <,>,<=,>=的比较规则
    所有比较运算符都支持任意类型,但是比较只支持数字和字符串,所以需要执行必要的转换然后进行比较,转换规则如下:

    1. 如果操作数是对象,转换为原始值:如果valueOf方法返回原始值,则使用这个值,否则使用toString方法的结果,如果转换失败则报错
      经过必要的对象到原始值的转换后,如果两个操作数都是字符串,按照字母顺序进行比较(他们的16位unicode值的大小)
      否则,如果有一个操作数不是字符串,将两个操作数转换为数字进行比较
  5. 函数内部arguments变量有哪些特性,有哪些属性,如何将它转换为数组

    1. arguments所有函数中都包含的一个局部变量,是一个类数组对象,对应函数调用时的实参。如果函数定义同名参数会在调用时覆盖默认对象
    2. arguments[index]分别对应函数调用时的实参,并且通过arguments修改实参时会同时修改实参
    3. arguments.length为实参的个数(Function.length表示形参长度)
    4. arguments.callee为当前正在执行的函数本身,使用这个属性进行递归调用时需注意this的变化
    5. arguments.caller为调用当前函数的函数(已被遗弃)
    6. 转换为数组:var args = Array.prototype.slice.call(arguments, 0);
  6. iframe有那些缺点?

    1. iframe会阻塞主页面的Onload事件
    2. 搜索引擎的检索程序无法解读这种页面,不利于SEO
    3. iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载
    4. 使用iframe之前需要考虑这两个缺点。如果需要使用iframe,最好是通过javascript动态给iframe添加src属性值,这样可以绕开以上两个问题
  7. This指向的理解

    1. 事件函数内的this
    2. 对象方法内的this
    3. new构造函数时构造函数内的this
    4. 普通函数调用时,函数内的this
    5. call,apply调用时,函数内的this
    6. 箭头函数内的this
  8. Ajax原理
    Ajax的原理简单来说是在用户和服务器之间加了—个中间层(AJAX引擎),通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。使用户操作与服务器响应异步化。这其中最关键的一步就是从服务器获得请求数据

var xhr = null;
    xhr = new XMLHttpRequest()
    // 2. 连接服务器
    xhr.open('get', url, true)
    // 3. 发送请求
    xhr.send(null);
    // 4. 接受请求
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            if(xhr.status == 200){
                success(xhr.responseText);
            } else { // fail
                fail && fail(xhr.status);
            }
        }
    }
  1. 异步加载JS的方式有哪些?

    1. defer,只支持IE
    2. async:
    3. 创建script,插入到DOM中,加载完毕后callBack
  2. defer和async的区别

    1. defer并行加载js文件,会按照页面上script标签的顺序执行
    2. async并行加载js文件,下载完成立即执行,不会按照页面上script标签的顺序执行
  3. 说说你对AMD和CommonJs的理解
    CommonJS是服务器端模块的规范,Node.js采用了这个规范。CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范则是非同步加载模块,允许指定回调函数
    AMD推荐的风格通过返回一个对象做为模块对象,CommonJS的风格通过对module.exports或exports的属性赋值来达到暴露模块对象的目的

  4. 严格模式常见的限制

    1. 变量必须声明后再使用
    2. 函数的参数不能有同名属性,否则报错
    3. 不能使用with语句
    4. 禁止this指向全局对象
  5. addEventListener 兼容ie9+,所以如果项目是在ie9+以上浏览器内运行,直接就可以用,不用考虑兼容性

  6. 判断js内某个字符串全是数字

    1. 使用isNaN;
    2. 使用正则/\d+/g
  7. 如何获取浏览器滚动条高度

    1. 在ie、firefox、chrome下都是使用document.documentElement.scrollTop 而不是document.body.scrollTop,jquery下是使用$(window).scrollTop
  8. forEach,map, forin不能遍历dom合集,要遍历dom集合需要使用for or 将dom集合转换成数组

var oLis = document.getElmentsByTagName('li');

// 使用for循环遍历
for (var i = 0; i < oLis.length; i++) {}

// 将合集转换成数组,然后在遍历
var arrOlis = Array.prototype.slice.call(oLis);
var arrOlis = Array.from(oLis);
var arrOlis = [...oLis];
  1. Object.assign

    1. 合并or拷贝对象,并不是深拷贝,是披着深拷贝外衣的浅拷贝。最多也是Object.assign会深拷贝第一层的值,对于第一层的值都是深拷贝,而到第二层的时候就是复制引用。类似的情况还有,slice方法和concat方法等。
  2. addClass removeClass hasClass toggleClass

function hasClass (dom, className) {
     var reg = new RegExp('(^|\\s)' + className+ '(\\s|$)');
     return reg .test(dom.className);
}

function addClass (dom, clsName) {
    if (!hasClass(dom, clsName)) {
        let classStr = dom.getAttribute('class');
        dom.className = classStr.trim() + ' ' + clsName;
    }
};

function removeClass (dom, clsName) {
    if (hasClass(dom, clsName)) {
        let classStr = dom.getAttribute('class');
        let newClassStr = classStr.replace(clsName, '');
        dom.className = newClassStr;
    }
}

function toggleClass (dom, clsName) {
    if (hasClass(dom, clsName)) {
        removeClass(dom, clsName);
    } else {
        addClass(dom, clsName);
    }
};
  1. appendChild方法插入的元素怎么样去使用transition动画

  2. requestAnimationFrame方法可以在什么样的场景下使用

  3. elementsFromPoint方法的作用是什么

  4. apply 与 call

    1. 非常相似,不同之处在于提供参数的方式。apply 使用参数数组而不是一组参数列表。apply 可以使用数组字面量(array literal),如 fun.apply(this, ['eat', 'bananas']),或数组对象, 如 fun.apply(this, new Array('eat', 'bananas'))。
    2. 需要注意的是,指定的this值并不一定是该函数执行时真正的this值,如果这个函数处于非严格模式下,则指定为null和undefined的this值会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象。
  5. 为什么ES5及以下的JS无法完美继承数组,最优的方式是什么

  6. throw语句

    1. throw语句用来抛出一个用户自定义的异常。当前函数的执行将被停止(throw之后的语句将不会执行),并且控制将被传递到调用堆栈中的第一个catch块。如果调用者函数中没有catch块,程序将会终止,语法为throw expression; expression可以是字符串,数字,布尔值
    2. 一般可用来捕获异常or中断循环,如forEach循环也是可以被中断的,条件是forEach遍历是放在try catch内的,因为不放在try catch语句内,直接throw是会抛出一个异常终止程序执行的
try {
   throw '__break__';
} catch (e) {
   这里的e就是throw后面的内容
}
  1. propertyIsEnumerable

    1. propertyIsEnumerable方法返回一个布尔值,表示指定的属性是否可枚举。
  2. forEach方法

    1. forEach方法对数组的每个元素执行一次提供的函数。返回值为undefined;即forEach() 为每个数组元素执行callback函数;不像map() 或者reduce() ,它总是返回 undefined值,并且不可链式调用,没有办法中止或者跳出 forEach 循环,除了抛出一个异常。
  3. undefined与void 运算符

    1. undefined并不是保留词(reserved word),它只是全局对象的一个属性,在低版本 IE 中能被重写,undefined 在 ES5 中已经是全局对象的一个只读(read-only)属性了,它不能被重写。但是在局部作用域中,还是可以被重写的
    2. void 运算符 对给定的表达式进行求值,然后返回 undefined。void 运算符通常只用于获取 undefined的原始值,一般使用void(0)(等同于void 0)
  4. for...in语句

    1. for...in语句以任意顺序遍历一个对象的可枚举属性(包括原型上继承的)。对于每个不同的属性,语句都会被执行,另外for in遍历不是按顺序来进行遍历的,它跟每个浏览器自身的实现有关,for in出问题会包含两个条件其一是在 IE < 9 浏览器中(又是万恶的 IE!!),其二是被枚举的对象重写了某些键,如重写了toString属性,chrome下能够正常返回,ie8则不会弹出,因为IE 8 将 toString "内定" 成了不可枚举属性(尽管已经被重写)
  5. 0.1 +0.2===0.30000000000000004的原因

    1. EcmaScrpt规范定义Number的类型遵循了IEEE754-2008中的64位浮点数规则定义的小数后的有效位数至多为52位导致计算出现精度丢失问题!所以可以使用toFixed() 方法来解决这个问题,兼容ie9+
      numObj.toFixed(digits) 方法使用定点表示法来格式化一个数,返回值为所给数值的定点数表示法的字符串形式。 digits小数点后数字的个数;介于 0 到 20 (包括)之间,实现环境可能支持更大范围。如果忽略该参数,则默认为 0。digits具体值取决于传入参数)位数字。该数值在必要时进行四舍五入,另外在必要时会用 0 来填充小数部分,以便小数部分有指定的位数。 如果数值大于 1e+21,该方法会简单调用 Number.prototype.toString()并返回一个指数记数法格式的字符串。
var numObj = 12345.6789;
numObj.toFixed();         // 返回 "12346":进行四舍五入,不包括小数部分
numObj.toFixed(1);        // 返回 "12345.7":进行四舍五入
numObj.toFixed(6);        // 返回 "12345.678900":用0填充
(1.23e+20).toFixed(2);    // 返回 "123000000000000000000.00"
  1. Babel的相关知识

    1. Babel默认只转换新的JavaScript句法(syntax),而不转换新的API,比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的方法(比如Object.assign)都不会转码。举例来说,ES6在Array对象上新增了Array.from方法。Babel就不会转码这个方法。如果想让这个方法运行,必须使用babel-polyfill,为当前环境提供一个垫片

    2. babel-preset-env 的工作方式类似 babel-preset-latest,唯一不同的就是 babel-preset-env 会根据配置的 env 只编译那些还不支持的特性。即babel-preset-env包含了babel-preset-2015,babel-preset-2016等,但不包括babel-polyfill及babel-preset-stag

  2. babel-polyfill的正确使用方式

  3. beforeunload事件

    1. beforeunload事件用于页面关闭与刷新前,阻止页面是否进行关闭or刷新,在ie10下a也标签会触发beforeunload,解决办法是1.去掉a标签上的href属性,2.把a标签换成其它span标签替代;另外在解决改问题的时候在a标签的click事件里面进行阻止默认行为没有用;
  4. encodeURIComponent

  5. JSbarcode二维码生成插件

    1. JSbarcode生成的图片是基于base64的,生成的图片质量较差在ie下打印非常模糊,所以换成jquery-barcode插件,这个插件主要是以css也就是在一个div内生成数个div用样式来生成条码,所以不存在各个浏览器打印样式的差异,所以如果不考虑ie打印的话建议用JSbarcode,否则用jquery-barcode
  6. base64的图片

    1. base64的图片不能通过js转换成链接的图片,要转换成链接的图片的话要与后端交互,需要后端返回对应的链接,js只能报图片转换成base64显示,转换成Base64的好处就是可以减少请求次数,坏处就是不能换成,另外ie8及以上的浏览器都已经较好的支持base64位图片展示
  7. input file属性提交本地文件

    1. input file属性提交本地文件在ie下会存在双击才能弹出选择文件框而不是单机进行选择,解决办法是让含有file属性的input文本框足够的打,能够充斥整个父容器
input[type='file'] {
    position: absolute;
    z-index: 999;
    height: 34px;
    left: 0;
    top: 0;
    width: 100%;
    padding: 0;
    background: none;
    border: 0;
    opacity: 0;
    filter: alpha(opacity=0);
    font-size: 100px;
    cursor: pointer;
}
  1. 生成表格单元格的方法

    1. 生成表格单元格的方法传了传统的通过createElement方法来创建td与tr之外还可以通过insertRow(index)生成tr,index当前行的行号,表示在第几行后插入行,insertCell生成单元格,注意一定要是填充单元格到tr内,不然tr不能正常显示deleteRow(index)删除行,index为行的下标,行数index从0开始,并且随着行数的变化而动态变化
  2. jquery removeClass

    1. 该方法删除某个元素的class类,如果插入类名表示删除该类,如果不传参表示删除该元素上的所有类样式
  3. jquery end

    1. 该方法返回最近一次破坏性操作之前的元素,破坏性操作值获取了新的元素集合or获取了某组数据,如find,child,parent,next,nextAll,offset等方法
  4. jquery closest("选择器")

    1. 获取当前元素的含有传入选择器的最近一个父元素
  5. jquery data

    1. 该方法无法获取动态赋值之后的data值,要获取动态赋值之后的data值需要用attr方法获取,另外data方法也不能动态设置data属性,如果要动态设置的话要使用attr方法来进行动态设置
  6. font-family设置字体类型

    1. font-family设置字体类型时,值可以是加双引,与单引,不加效果都是一样的,但是用jquery的css()方法取值的时候,在chrome下不管你加不加引号取出来的值都是加引号的字符串,而ie浏览器下取出来的值根据设置font-family的值时是否带引号有关,如果带引号那么会将引号也算进去并且进行转义("'ArvoBold'"),所以为了兼容性设置font-family的时候值都不要加引号
  7. 关于iframe引入页面进行打印的小结

    1. 当在父页面调用iframe页面内的打印方法时,如果iframe页面没有进行focus操作,那么打印就是打印父页面的内容,也包括ifame的内容,如果iframe页面内进行了fouse操作,那么只会打印iframe里面的内容,注意了这里打印ifame里面的内容宽高,与打印机的标签纸张大小有关,与iframe及iframe内的元素宽高无关,当iframe内的内容宽高小于打印纸张的宽高时,内容会全部打印出来,当内容的宽高大于纸张的宽高时只会打印出纸张视图内的内容,所以打印最好的方式就是显示一个元素,打印一个元素,然后删除一个元素,注意这里用setTimeout而不是setInterval,原因是setInterval会根据执行的快慢来调整执行的时机,即不一定按时间间隔来准确执行,而setTimeout会按准确的时间间隔来执行
  8. 原生js及jquery,父页面获取iframe页面的window对象,document对象,及元素的方式,iframe页面获取父页面window对象,document对象,及元素的方法

    1. 关键是先获取window对象(注意通过window点出来的直接就是iframe的window对象了,而通过先获取iframe元素的话,就需要通过元素的contentWindow属性来获取window对象),然后再通过window对象获取到document对象,然后通过document对象来获取元素
js获取iframe元素的window对象 window.iframes["name名字"]  兼容chrome,ff,ie9+   
document.getElementById("iframeid").contentWindow  or this.contentWindow

 jquery获取iframe元素的window对象  
$("iframe")[0].contentWindow

js获取iframe的document对象   window.iframes["name名字"].document   or document.getElementById("iframeid").contentWindow.document  or  this.contentWindow.document

jquery获取iframe的document对象  $("iframe")[0].contentWindow.document  or $(this.contentWindow.document)

js获取获取iframe的元素   
window.iframes["name名字"].document.getElementById("test")

jquery获取获取iframe的元素   $($("iframe")[0].document).find("#test")  or $(this.contentWindow.document).find(".ui-label-content-body")

js iframe获取父页面的window对象
window.parent  or parent

jquery获取iframe元素的window对象  
$(window.parent) or $(parent)

js获取iframe的document对象   
window.parent.document

jquery获取iframe的document对象  
$(window.parent.document) or $(parent.document)
 
 js获取获取iframe的元素   
window.parent.document.getElementById("test") or parent.document.getElementById("test")

 jquery获取获取iframe的元素   $("#test", parent.document)  or $(window.parent.document).find("#test"); or $(parent.document).find("#test");
  1. 当动态创建多个iframe时,怎么去保证当前iframe里面的值就是创建当前iframe时主页面中的值

    1. 试了数组的方式,也试了在iframe元素上加属性的方式,效果都是不特别好,可能会出现iframe内的值,不是创建时需要取的值,解决方法就是在主页面创建一个key-value的对象,然后在iframe内通过key来获取值。这样可以保证每个iframe内取值时,取得就是当前iframe创建时候的值,不会出现错误,另外需要注意的是,iframe内是无法获取到当前iframe元素上的属性值的,唯一的方法就是在父页面内定义一个方法,然后在iframe页面内进行调用
  2. 浏览器输出的对象的key值不是按后台返回的key值顺序来显示

    1. js里面在定义对象时,对象的key是没有顺序的,但是当输出的时候,浏览器就好根据key的ascii来进行从小到大的排序,所以如果输出的内容不需要进行排序的话,可以使用对象直接输出,如果需要对key进行排序的话,就需要使用数组包对象来进行输出,然后利用sort方法来进行排序
  3. 同名的函数与变量函数的提示在变量之后,即先找变量,找到a,然后将a赋值为undefined,然后找函数,发现函数有同名变量,然后会去覆盖同名变量a

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions