Audio播放时报错

今天遇到一个怪异的问题,有个Audio元素,在执行play函数时,声音并没有正常播放,打开控制台后有报错: Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first. 但开启控制台之后,刷新页面,音频播放正常。根据控制台的报错,似乎是浏览器限制了音频的自动播放动作,而音频恰恰就是在页面加载完毕后,由js脚本控制播放的。 试探性的使用timeout尝试了一下,果然,如果延迟500ms执行播放音频的动作,就不会再有报错,但如果延迟时间间隔太短,仍然会报错。 这应该是Chrome限制自动播放的策略导致的。…

node_modules中的js编译问题

昨晚遇到一个很奇怪的问题,在node_modules中引入一个第三方库react-svg-joystick,公司的电脑上编译没有问题,但在家里的电脑上却会编译报错,报错内容如下 Module parse failed: /Users/hoyt/vscode/FEngine/node_modules/_react-svg-joystick@1.0.0@react-svg-joystick/src/index.js Unexpected token (10:19) You may need an appropriate loader to handle this file type. 仔细查看了报错信息,很快就找到了问题,npm对node_modules中的库进行了link处理,编译器解析时访问的路径实际上是node_modules/_react-svg-joystick,库的名字带了一个下划线,正是因为npm的这个link行为,导致编译器实际上在处理_react-svg-joystick@1.…

NodeList研究

先来看一段代码 const hchild = document.head.childNodes const bchild = document.body.childNodes const hsize = hchild.length const bsize = bchild.length document.head.appendChild(bchild[0]) console.log(`${hchild.length === hsize} and ${bchild.length === bsize}`) 浏览器中执行后,输出是什么呢? 答,输出是false和false 第一个false还稍微容易理解一些,hchild是指向head.childNodes的指针,调用appendChild后,长度增加了1 。 第二个false一开始让我懵逼了,为什么bchild.length也发生了变化呢?因为body.childNodes返回的并不是数组,而是一个NodeList。 Although NodeList…

React缓冲池的性能抖动

上上周在进行团队分享时,有人提出了对React缓冲池性能的质疑。 起初我坚持认为,空间换时间,缓冲池对性能肯定是有提升效果的,但通过几组对照实验,发现缓冲池在一定情况下,的确有一定的性能提升,但当数据规模增大时,不但不会提升性能,反而会更加慢。 细想一下,还是能想明白,缓冲池本身的适用情景,频繁需要使用某种对象,但是是循环利用的情况。比如运行阶段一共需要用到10000次某种类的实例,缓冲池大小满足峰值需要,假设峰值为100,同时尽可能的串行请求该对象,避免新的内存申请。这种情况下,由于极大的复用了现有的内存对象,理论上讲肯定是有性能提升的。但实际项目中这样的情况或许并不多,所以不见得能体现出缓冲池的提升效果。 而更有甚者,某些情况下,还可能导致缓冲池性能抖动,我总结了一下,大概有以下几种: 缓冲池poolSize设置过小,而同一时刻需要用到的实例数很多。比如缓冲池大小只有10,而同时需要的实例数量为10000,这时缓冲池形同虚设 js虚拟机在内存管理时做了一定的优化,导致大量创建实例的开销下降,反而优于使用缓冲池的情况。一般来说,对象创建之后随机销毁,这样的测试例子达到一定规模时,时间开销就会小于使用了缓冲池的情况 缓冲池对象的Pooler过程开销较大,甚至超过了new的开销 不能迷信过去的知识,时代在变化,js的执行引擎越来越牛逼了。…

SVG图标的Sprite处理

svg正在越来越广泛的应用在前端领域,由于矢量图缩放对图像质量无损,越来越多的图标、图片都开始使用svg。但svg文件一旦多起来,就需要对这些资源进行集中管理。webpack的svg-loader只是简单的将svg文件替换成了文本内容,增加了bundle文件的体积,灵活性也不高,如果能将svg文件处理成类似于jpg/png图片一样,做成sprite就好了。而这正是svg-sprite-loader要做的事情。 viewBox 在svg文件中,可以创建若干个view,view包含一个名为viewBox的属性,viewBox允许我们定义一个矩形区域,通过四个参数 left, top, width和height,可以通过设置id来对view进行标示。 当定义view之后,在引入svg文件时,就可以指定显示某个view,如下所示 <img src="sprite.svg#svgView(viewBox(0, 0, 32, 32))" alt=""> .icon-clock { background: url(sprite.svg#icon-clock-view)…

CSS中的单位

CSS中有很多关于尺寸的单位,包括:px,pt,%,em,cm等,根据其性质可以分为两类:绝对尺寸单位和相对尺寸单位。 绝对尺寸 绝对尺寸就是物理世界的度量单位,CSS中的绝对度量单位见下表 CSS中的绝对尺寸单位 符号名称备注 in英寸1 in = 2.54cm cm厘米 mm毫米 pc派卡印刷行业使用的长度单位。1 pc = 1/6 in = 4.512 mm pt磅1pt = 1/72 in = 0.352 777 mm, 1 in = 72pt 使用绝对尺寸的好处在于我们可以直观的理解尺寸的大小,但是,现在的页面往往要求支持在多终端下浏览,为了保证在手机、平板等设备上显示友好,绝对尺寸显然无法实现这一点,因此,最好通过相对尺寸单位来进行大小设置。 #相对尺寸 相对尺寸并不是一个确切的固定值,而是与当前屏幕的尺寸有关,…

NodeType

nodeType 属性可用来区分不同类型的节点,比如 元素, 文本 和 注释。 NodeType值及其含义 常量 值 描述 状态 Node.ELEMENT_NODE 1 一个 元素 节点,例如 <p> 和 <div> ☑️ Node.ATTRIBUTE_NODE 2 元素 的耦合属性 。在 DOM4 规范里Node 接口将不再实现这个元素属性 ✖️ Node.TEXT_NODE 3 Element 或者 Attr 中实际的文字 ☑️ Node.CDATA_SECTION_NODE 4…

Bootstrap中tab不能二次响应的问题

今天遇到一个非常奇怪的问题,有一个用bootstrap中的tab做的页面,页面上有一个元素,第一次点击时,能够正常进行对应tab的切换,但是切换成功后,先切换到其他tab,再试图通过点击那个页面元素进行切换时,居然不能正常响应了! <li title="讨论" data-toggle="tooltip"><span class="glyphicon glyphicon-pencil" data-toggle="tab" data-target="#target">iconText</span></li> 这个问题让我百思不得其解,第一次能够切换成功,但是第二次就不可以-_-#,单步调试发现即便手动调用tab方法,都不能触发shown.bs.…

jQuery中的proxy的实现

当某一个事件由一个元素触发,但与此同时又需要另外一个对象进行关联动作的时候,就非常适合使用代理。jQuery的proxy方法,可以将回调函数绑定在特定的context上。比如,点击某个按钮,让另外一个元素显示,就可以通过如下代码来实现。 $(someSelector).click($.proxy($(targetSelector), 'show'))); proxy的实现机制是怎样的呢?其源码如下: jQuery.extend({ // 全局的id计数器 guid: 1, proxy: function( fn, context ) { var tmp, args, proxy; /* * 正常情况下,fn是待执行的函数 * 如果context是字符串,那么proxy会认为fn是一个对象,fn[content]是实际需要执行的函数,这种情况下将两者进行交换,以便后续代码一致 */ if ( typeof context === "string" ) { tmp = fn[ context ]; context = fn; fn = tmp; } // 如果fn不是函数,…

jQuery.parseHTML详解

parseHTML是jQuery内部解析html字符串的方法 jQuery.parseHTML = function( data, context, keepScripts ) { // data必须是字符串,否则返回空数组 if ( typeof data !== "string" ) { return []; } // 如果context是布尔值,则用来指示 if ( typeof context === "boolean" ) { keepScripts = context; context = false; } var base, parsed, scripts; // 如果context为空 if ( !context ) { // 如果支持crheateHTMLDocument ,则创建一个,并设置base为当前document的href if ( support.createHTMLDocument ) { context = document.implementation.createHTMLDocument( "" ); base = context.createElement( "base" ); base.href = document.location.href;…