前端小问题总结(一)

时间:2021-12-10 15:13:30

旨在记录自己在实际项目中遇见的一些小问题,简单做个记录。以便以后翻阅。

document.domain

通常,解决跨域问题的方法有:

  1. document.domain
  2. jsonp
  3. iframe
  4. 代理
  5. CORS

用document.domain来指定域,是可以的,但是有局限性,也就是一级域名一致才可以。
参考document.domain

拖动

ondragstart 事件在用户开始拖动元素或选择的文本时触发。

PS:

  1. 为了让元素可拖动,需要使用 HTML5 draggable=true 属性。
  2. 链接和图片默认是可拖动的,不需要 draggable 属性。
  3. Internet Explorer 8 及更早 IE 版本或 Safari 5.1 及更早版本的浏览器不支持 drag 事件。
    在拖放的过程中会触发以下事件:
    在拖动目标上触发事件 (源元素):
  • ondragstart - 用户开始拖动元素时触发
  • ondrag - 元素正在拖动时触发
  • ondragend - 用户完成元素拖动后触发

释放目标时触发的事件:

  • ondragenter - 当被鼠标拖动的对象进入其容器范围内时触发此事件
  • ondragover - 当某被拖动的对象在另一对象容器范围内拖动时触发此事件
  • ondragleave - 当被鼠标拖动的对象离开其容器范围内时触发此事件
  • ondrop - 在一个拖动过程中,释放鼠标键时触发此事件

关于drag的一个demo

bind()

bind() 方法的主要作用就是将函数绑定至某个对象,bind() 方法会创建一个函数,函数体内this对象的值会被绑定到传入bind() 函数的值

1. 原理

Function.prototype.bind = function(context) {
 var self = this; // 保存原函数
 return function() { // 返回一个新函数
  return self.apply(context, arguments); // 执行新函数时,将传入的上下文context作为新函数的this
 }
}

2. bind的应用场景

实现对象继承

var A = function(name) {
 this.name = name;
}
 
var B = function() {
 A.bind(this, arguments);
}
 
B.prototype.getName = function() {
 return this.name;
}
 
var b = new B("hello");
console.log(b.getName()); // "hello"

事件处理

var paint = {
 color: "red",
 count: 0,
 updateCount: function() {
  this.count++;
  console.log(this.count);
 }
};
 
// 事件处理函数绑定的错误方法:
document.querySelector('button')
 .addEventListener('click', paint.updateCount); // paint.updateCount函数的this指向变成了该DOM对象
 
// 事件处理函数绑定的正确方法:
document.querySelector('button')
 .addEventListener('click', paint.updateCount.bind(paint)); // paint.updateCount函数的this指向变成了paint

时间间隔函数

var notify = {
 text: "Hello World!",
 beforeRender: function() {
  console.log(this.text);
 },
 render: function() {
 
  // 错误方法:
  setTimeout(this.beforeRender, 0); // undefined
 
  // 正确方法:
  setTimeout(this.beforeRender.bind(this), 0); // "Hello World!"
 }
};
 
notify.render();

借用Array的原生方法

var a = {};
Array.prototype.push.bind(a, "hello", "world")();
 
console.log(a); // "hello", "world"

3. 与call/apply的区别

共同点:

都可以改变函数执行的上下文环境;

不同点:

bind: 不立即执行函数,一般用在异步调用和事件; call/apply: 立即执行函数。

console

  1. console.assert(expression, obj[, obj...])

接收至少两个参数,第一个参数的值或返回值为false的时候,将会在控制台上输出后续参数的值. eg:

console.assert(1 == 1, object); // 无输出,返回 undefined  
console.assert(1 == 2, object); // 输出 object
  1. console.error(obj[, obj...])

用于输出错误信息,用法和常见的console.log一样,不同点在于输出内容会标记为错误的样式,便于分辨。

  1. console.dir(obj)

将传入对象的属性,包括子对象的属性以列表形式输出. eg:

var obj = { name: 'classicemi', college: 'HUST', major: 'ei'};  
console.dir(obj);
  1. console.group()

能够让控制台输出的语句产生不同的层级嵌套关系,每一个console.group()会增加一层嵌套,相反要减少一层嵌套可以使用console.groupEnd()方法。和console.group()相似的方法是console.groupCollapsed()作用相同,不同点是嵌套的输出内容是折叠状态,在有大段内容输出的时候使用这个方法可以使输出版面不至于太长吧.

  1. console.info(obj[, obj...])
    与之前说到的console.error一样,用于输出信息,没有什么特别之处。

  2. console.table()

可将传入的对象,或数组以表格形式输出,相比传统树形输出,这种输出方案更适合内部元素排列整齐的对象或数组,不然可能会出现很多的 undefined。实际中感觉用得少。

  1. console.profile([profileLabel])

借助控制台以及console.profile()方法我们可以很方便地监控运行性能。

  1. console.time(name)

将成对的console.time()和console.timeEnd()之间代码的运行时间输出到控制台上,name参数可作为标签名。

  1. console.trace()

console.trace()用来追踪函数的调用过程。在大型项目尤其是框架开发中,函数的调用轨迹可以十分复杂,console.trace()方法可以将函数的被调用过程清楚地输出到控制台上。

  1. console.warn(object[, object...])

输出参数的内容,作为警告提示。

console对象上的五个直接输出方法,console.log(),console.warn(),console.error(),console.exception()(等同于console.error())和console.info(),都可以使用占位符。支持的占位符有四种,分别是字符(%s)、整数(%d或%i)、浮点数(%f)和对象(%o)。 eg:

console.log('%s是%d年%d月%d日', '今天', 2014, 4, 15);
console.log('圆周率是%f', 3.14159);
var obj = { name: 'classicemi'}
console.log('%o', obj);

还有一种特殊的标示符%c,对输出的文字可以附加特殊的样式,当进行大型项目开发的时候,代码中可能有很多其他开发者添加的控制台语句。开发者对自己的输出定制特别的样式就可以方便自己在眼花缭乱的输出结果中一眼看到自己需要的内容。 eg:

console.log('%cMy name is classicemi.', 'color: #fff; background: #f40; font-size: 24px;');