分类 前端基础 下的文章

处理bootstrap4不支持远程静态框问题


起步

我就是喜欢用新的,况且 bs4 出来也很久了,用了一段时间后发现它并不支持远程静态框了,查了一下这部分已经被移除了。

20180713114837.png

所以,以前的 <a data-toggle="modal" href="remote.html" data-target="#modal">Click me</a> 这种写法就没法用了,因此这部分要手动处理下。


响应式图片srcset属性学习笔记


介绍

以下参考了MDN,并添加了一些细节和自己的测试结论

<img/>的属性,设置srcset之后不同屏幕密度加载不同图片。

其值为:以逗号分隔的一个或多个字符串列表表明不同User Agent可能设置的图像资源。

每一个字符串由以下组成:

  1. 一个图像的 URL
  2. 可选的描述符,空格后跟以下的其一:
    • 一个宽度(w)描述符,这是一个正整数,后面紧跟 'w' 符号。该整数宽度=sizes属性给出的资源(source)大小*像素密度。该值需配合sizes使用。
    • 一个像素密度描述符,这是一个正浮点数,后面紧跟 'x' 符号。该值其实指的就是dpr。若像素密度描述符直接命中的话,就不考虑sizes和w描述符了,但是建议一般所有字符串仅用其中一个 如果没有指定描述符,那它会被指定为默认的 1x。


setInterval与settimeout模拟的区别


首先先说明下,node里面的事件循环和浏览器中的是不一致的。

这边浏览器用的是chrome 64

问题1:setInterval(fn,ms)过程,是先把fn放入timer堆,还是先执行?

问题2:setInterval 和 settimeout模拟定时 的使用场景都有哪些?

A1

看了一篇文章,里面讲到node中timers阶段的源码为

void uv__run_timers(uv_loop_t* loop) {
  struct heap_node* heap_node;
  uv_timer_t* handle;

  for (;;) {
    heap_node = heap_min((struct heap*) &loop->timer_heap);//取出timer堆上超时时间最小的元素
    if (heap_node == NULL)
      break;
    //根据上面的元素,计算出handle的地址,head_node结构体和container_of的结合非常巧妙,值得学习
    handle = container_of(heap_node, uv_timer_t, heap_node);
    if (handle->timeout > loop->time)//如果最小的超时时间比循环运行的时间还要小,则表示没有到期的callback需要执行,此时退出timer阶段
      break;

    uv_timer_stop(handle);//将这个handle移除
    uv_timer_again(handle);//如果handle是repeat类型的,重新插入堆里
    handle->timer_cb(handle);//执行handle上的callback
  }
}

里面说到对于repeat类型的handle(setInterval设置的),是先重新插入再执行callback

( 我这边测试发现chrome 64是这样的,node相反。可能node修改过实现?

测试代码

var speed = 1000
var start = Date.now()
var icounter = 0
var tcounter = 0
//t:ms
function sleep(t) {
    let d = Date.now()
    while (Date.now() - d < t) { }
}
setInterval(function () {
    var time = (Date.now() - start) / 1000
    var avg = ++icounter / time
    console.log('<td>setInterval</td><td>' + icounter + '</td><td>' + time.toFixed(3) + '</td><td>' + avg.toFixed(6) + '</td>')
    sleep(50)
}, speed)

浏览器运行效果:

setInterval=>次数:1   所用时间:1.002
setInterval=>次数:2   所用时间:2.001
setInterval=>次数:3   所用时间:3.000
setInterval=>次数:4   所用时间:4.002
setInterval=>次数:5   所用时间:5.002

node运行效果:

setInterval=>次数:1   所用时间:1.003
setInterval=>次数:2   所用时间:2.060
setInterval=>次数:3   所用时间:3.114
setInterval=>次数:4   所用时间:4.164
setInterval=>次数:5   所用时间:5.215

结果分析:

  1. 浏览器先把fn放入timer堆,再执行

  2. node先执行,再把fn放入timer堆