前端面试每日-31-第145天

今天的知识点 (2019.09.08) —— 第145天[html] 说说你对表单属性type="hidden"的理解,它的运用场景有哪些?[css] css怎样使每个字符宽度一样?[js] 原生Math的方法有哪些?请列举并描述其功能[软技能] 为什么提倡利用多个域名来存储网站的资源?《论语》,曾子曰:“吾日三省吾身”(我每天多次反省自己)。 前端面试每日3+1题,以面试题来驱动学习,每天进步一点! 让努力成为一种习惯,让奋斗成为一种享受!相信 坚持 的力量!!!欢迎在 Issues 和朋友们一同讨论学习! 项目地址:前端面试每日3+1 【推荐】欢迎跟 jsliang 一起折腾前端,系统整理前端知识,目前正在折腾 LeetCode,打算打通算法与数据结构的任督二脉。GitHub 地址 微信公众号欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎点个Star, 同时欢迎微信扫码关注 前端剑解 公众号,并加入 “前端学习每日3+1” 微信群相互交流(点击公众号的菜单:进群交流)。 学习不打烊,充电加油只为遇到更好的自己,365天无节假日,每天早上5点纯手工发布面试题(死磕自己,愉悦大家)。希望大家在这浮夸的前端圈里,保持冷静,坚持每天花20分钟来学习与思考。在这千变万化,类库层出不穷的前端,建议大家不要等到找工作时,才狂刷题,提倡每日学习!(不忘初心,html、css、javascript才是基石!)欢迎大家到Issues交流,鼓励PR,感谢Star,大家有啥好的建议可以加我微信一起交流讨论!希望大家每日去学习与思考,这才达到来这里的目的!!!(不要为了谁而来,要为自己而来!)交流讨论欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎点个[Star] https://github.com/haizlin/fe...

September 8, 2019 · 1 min · jiezi

写一个BUI折叠菜单插件

写一个BUI折叠菜单插件效果预览 控件分析控件结构一个点击显示隐藏的效果, 并且点击的时候, 会先把展开进行隐藏, 再展开自己的. 从界面上我们来看看结构的设计.<!-- 一般控件最外层就是控件的容器名 --><div class="bui-foldmenu"> <div class="bui-foldmenu-item">菜单</div> <div class="bui-foldmenu-content">内容</div> <div class="bui-foldmenu-item">菜单2</div> <div class="bui-foldmenu-content">内容2</div></div>这里我们采用的是并列同级的方式, 那结构写起来有点麻烦, 其实这个结构跟 dl,dt,dd 是一致的, 那我们完全可以优化成以下结构.<!-- 一般控件最外层就是控件的容器名 --><dl class="bui-foldmenu"> <dt>菜单</dt> <dd>内容</dd> <dt>菜单2</dt> <dd>内容2</dd></dl>bui的设计是基于按钮的原型撑开容器的方式, 这样可以保持每个容器都是一致的标准高度, 所以我们再对结构进行优化.<!-- 一般控件最外层就是控件的容器名 --><dl class="bui-foldmenu"> <dt class="bui-btn">菜单</dt> <dd>内容</dd> <dt class="bui-btn">菜单2</dt> <dd>内容2</dd></dl>像刚刚效果图,菜单的点击还会有图标的切换, 再结合布局来得到以下结构, 一切皆布局, 一切皆容器.<!-- 一般控件最外层就是控件的容器名 --><dl class="bui-foldmenu"> <dt class="bui-btn bui-box"><div class="span1">菜单</div><i class="icon-foldmenu"></i></dt> <dd>内容</dd> <dt class="bui-btn bui-box"><div class="span1">菜单2</div><i class="icon-foldmenu"></i></dt> <dd>内容2</dd></dl>控件样式一般作为插件的独立样式引入, bui-foldmenu.css文件 .bui-foldmenu {}.bui-foldmenu>dt,.bui-foldmenu>[class*=bui-btn] { border: 0; border-bottom: 1px solid #eee;}/* 默认隐藏内容 */.bui-foldmenu>dd { display: none; border: 0; overflow-y: auto; border-bottom: 1px solid #eee; background: #fff;}/* 图标 */.bui-foldmenu .icon-foldmenu { -webkit-transition: -webkit-transform 0.3s ease-in-out 0s; transition: transform 0.3s ease-in-out 0s;}.bui-foldmenu .icon-foldmenu:before { content: "\e649";}/* 激活的时候显示block */.bui-foldmenu>.active+dd { display: block;}/* 激活的二级菜单的时候,把箭头翻转 */.bui-foldmenu>.active .icon-foldmenu { -webkit-transform: rotate(-180deg); transform: rotate(-180deg);}样式里面就默认隐藏内容标签(dt相邻的dd),由控件初始化, 其它都是一些修饰, 设置激活状态的时候,箭头翻转.控件脚本1.5.4 新增 bui.extend 方法,可以用来扩展插件, 并且保持跟 bui原本的使用方式一致.bui.extend 控件参数是一个对象, 其中包含以下参数name string 控件名称config object 控件默认参数callback function 控件的逻辑最简单的版本// 最简单的版本bui.extend({ name: "foldmenu", config: { id: "" }, callback: function(opt) { // that 指向插件的抛出的公共方法, option widget 等 let that = this; // this.config 为已经跟初始化参数合并以后的结果; let param = this.config; // 缓存选择器 let $id = null; // 要抛给开发者的方法 that.init = function(option) { // 对直接调用init方法的参数进行合并 param = $.extend(true, {}, param, option); // 单页多页选择器,如果是单页,这个插件只能在模块里面用, 不能在bui.ready $id = bui.$(param.id); // 绑定事件,点击的时候增加激活样式 $id.children("dt").click(function(e) { var hasActive = $(this).hasClass("active"); if (hasActive) { $(this).removeClass("active"); } else { // 加上样式以后会自动对箭头及下一层级展示处理; $(this).addClass("active"); } }) return that; } // 如果有依赖bui控件,应该在这里写,这样方便外部调用 // that.widgets.loading = ui.loading({ // appendTo: opt.id // }); // 如果需要销毁的生命周期,则在这里加上. // that.beforeDestroy = function() { // // return that; // } // 必须传id if (!param.id) { // 抛出错误 bui.showLog("必须传id参数.") return that; } // 默认先初始化一次 return this.init(opt); }});控件使用<dl id="folder" class="bui-foldmenu"> <dt class="bui-btn">菜单</dt> <dd>内容</dd> <dt class="bui-btn">菜单2</dt> <dd>内容2</dd></dl> // 初始化 var uiFloder = bui.foldmenu({id:"#folder"}) // uiFloder.config 可以拿到一些实例的参数插件预览在线预览bui.folder插件 ...

September 8, 2019 · 3 min · jiezi

解析移动端滚动穿透

滚动穿透在移动端开发中是一个很常见的问题,产生诡异的交互行为,影响用户体验,同时也让我们的产品看起来不那么“专业”。虽然不少产品选择容忍了这样的行为,但是作为追求极致的工程师,应该去了解为什么会产生以及如何去解决。 什么是滚动穿透移动端开发中避免不了会在页面上进行弹窗、加浮层等这种操作。一个最常见的场景就是整个页面上有一个遮罩层,上面画着各种各样的东西,具体是什么就不讨论。实现这样一个遮罩层可难不住即使是一个刚开始写前端的小白。但是这里有一个问题就是如果不对遮罩层做任何处理,当用户在上面滑动时会发现遮罩层下方的页面居然也在滚动,这就很 interesting 了。就如下面的例子,一个名为mask长宽都是屏幕大小的遮罩层,我们在上面滑动时,下面的内容也在跟随滚动,即滚动“穿透”到了下方,这就是滚动穿透(scroll-chaining)。 上方 demo 的遮罩层底部是一个逐渐变蓝的内容容器,但是滑动上面遮罩层时,底部也跟随滚动了,这只是一个最简单的场景,后面我们会讨论更复杂的情况。 为什么会出现目前 Google 上搜滚动穿透会出现一大堆教你如何解决的文章,但是它们都是在告诉你怎么解决怎么 hack 掉这种交互异常。并没有告诉读者为什么会产生这种行为,甚至认为这是浏览器的一个 bug。对于我来说这个是难以理解的,因为就算解决了问题,其实也并不知道问题的根本是怎样的。 认知误区有一个误区就是我们设置了一个和屏幕一样大小的遮罩层,盖住了下面的内容,按理说我们应该能屏蔽掉下方的所有事件也就是说不可能触发下面内容的滚动。那么我们就去看一下规范,什么时候会触发滚动。 // https://www.w3.org/TR/2016/WD...When asked to run the scroll steps for a Document doc, run these steps: For each item target in doc’s pending scroll event targets, in the order they were added to the list, run these substeps:If target is a Document, fire an event named scroll that bubbles at target.Otherwise, fire an event named scroll at target.Empty doc’s pending scroll event targets.通过规范我们可以明白的 2 点是,首先滚动的 target 可以是 document 和里面的 element。其次,在 element 上的 scroll 事件是不冒泡的,document 上的 scroll 事件冒泡。 ...

September 7, 2019 · 2 min · jiezi

小白科普悲观锁和乐观锁

转自:码农翻身(微信号:coderising) 1、无锁旺财和小强生活在一个网上商城的系统中, 是一对儿线程好基友。 星期一刚上班,旺财接到领导电话说,要把一个商品的库存减少20, 旺财不敢怠慢,赶快把库存取出来一看,哦,现在有1000个。 与此同时,小强也接到电话说要把同一商品的库存减少30, 他一看,哦,现在有1000个。 旺财计算出最新的库存值980, 保存! 小强也计算出最新的库存值970, 保存 ! 旺财的数据被小强覆盖了! 领导一看,本来卖出了50个商品,现在库存只扣了30个,这样持续下去就天下大乱了。 旺财和小强, 各打二十大板, 长长记性! 2、悲观锁小强说:“哥,要不我们还是想个办法吧,再这样下去要被打死的。” 旺财悲催地说: “这样, 以后我们每次访问库存之前,都要先加锁,加了锁,就禁止别人再进入访问,只能等待持有锁的人来释放。” 星期二, 领导让旺财再次把库存减少20 , 旺财这次万分小心,先把库存给锁住,然后慢慢修改。 小强也接到了把库存减少的指令, 但是旺财哥已经把库存锁住了, 不能操作,小强只好去阻塞车间喝茶聊天,然后到就绪车间等待调度运行。 好不容易等到可以再次执行了,小强一看,这库存怎么还锁着呢!? 只好再次去阻塞车间喝茶。 领导一看, 小强你怎么回事, 老是喝茶聊天? ! 还干不干活了? 小强争辩说旺财哥一直锁着库存,我没法操作。 领导不管这些, 把小强和旺财又打了二十大板。 (备注: 这种加锁的方式就是悲观锁了,悲观锁正如其名,每次取读写数据时候总认为数据会被别人修改,所以将数据加锁,置于锁定状态, 不让别人再访问。缺点是如果持有锁的时间太长,其他用户需要等待很长时间。) 3、乐观锁旺财说: “兄弟,这一次哥对不住你啊,处理得慢了一些, 不过哥刚才挨打的时候想了一个好办法:乐观锁。” 小强说:“拉倒吧你,屁股都快被打烂了还乐观?” “你听我说嘛, 我们在那个库存字段的旁边,再加上一个版本(version)的字段, 例如刚开始的时候(库存= 1000, 版本=1), 每次你去读的时候不仅要读出库存,还要读出版本号, 等到你修改了库存,往回写的时候一定要检查一下版本号,看看和你读的时候是否一样。” “如果不一样呢?” 小强问 “那就放弃这次写的操作,重新读取库存和版本号, 重新来过。” “如果一样呢? ” “那就放心大胆地把新的库存值写回去。把版本号也加1” “我似乎有点明白了,我们试试,不过你要想好,我可不想再挨板子了。” 星期三, 旺财奉命把库存减去30, 他先读到了(库存= 1000, 版本=1); 小强也要改库存了,他要把库存减去50, 于是他也读到了(库存= 1000, 版本=1)。 ...

September 7, 2019 · 1 min · jiezi

WebGL2系列之采样器对象

前言在WebGL1中,纹理的图片和采样信息都是写在纹理对象之中. 采样信息告诉GPU如何去读取贴图上图片的信息。如果我们希望从同一个图片多次读取像素信息,但是每次读取的时候使用的过滤方式不一样, 此时我们需要创建两个不同的纹理对象。 "你说这样是不是很烦啊" WebGL: “。。。”采样器对象在WebGL2中,引入了采样器对象,使用采样器对象,可以把纹理的过滤方式封装到采样器对象上面,而原本的纹理对象可以不用在指定过滤方式,因此一张图片可以只用创建一个纹理对象,对于不同的过滤方式,创建多个采样器;在使用纹理对象的时候,可以绑定纹理对象和采样器对象来实现图源和读取方式的指定。纹理对象和采样方式被分开,一个纹理对象可以和多个采样器对象关联; 多个纹理对象也可以和一个采样器关联。如果使用采样器对象,一些WebGL的引擎就会需要产生代码上的变动。 创建采样器对象通过方法gl. createSampler可以创建采样器对象,比如: var samplerA = gl.createSampler();gl.createSampler方法以下是gl.createSampler的签名 WebGLSampler gl.createSampler();该方法没有参数,返回一个创建好的采样器对象。 指定采样器参数通过方法gl. samplerParameteri可以指定采样器的参数。 gl. samplerParameteri方法以下是gl. samplerParameteri的签名 void gl.samplerParameteri(sampler, pname, param);void gl.samplerParameterf(sampler, pname, param);第一个参数是sampler 对象,第一个参数是需要指定的参数名,第三个参数是参数值,其中参数名如下这些参数包括 gl.TEXTURE_MIN_FILTERgl.TEXTURE_MAG_FILTERgl.TEXTURE_WRAP_Sgl.TEXTURE_WRAP_Tgl.TEXTURE_COMPARE_MODEgl.TEXTURE_COMPARE_FUNC可以看出就是原本的WebGL1中需要指定的纹理对象上的参数,只是现在移到了采样器对象上。 绑定采样器到纹理单元通过函数 gl.bindSampler(unit, sampler),可以把采样器绑定到指定的纹理单元,函数签名: void gl.bindSampler(unit, sampler);比如如下代码片段: gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D, texture);gl.bindSampler(0, samplerA);此时相当于把texture对象和samplerA对象绑定到了一起,此时对于纹理单元0的读取,数据源来自texture对象,而过滤方式来自原samplerA。 删除采样器对象通过gl. deleteSampler方法可以删除指定的采样器对象,函数签名如下: void gl.deleteSampler(sampler);参数指定要删除的采样器对象,比如代码: gl.deleteSampler(sampler);一个示例代码片段下面是使用采样器的一个示例代码片段 var samplerA = gl.createSampler();gl.samplerParameteri(samplerA, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);gl.samplerParameteri(samplerA, gl.TEXTURE_MAG_FILTER, gl.NEAREST);gl.samplerParameteri(samplerA, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);gl.samplerParameteri(samplerA, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);var samplerB = gl.createSampler();gl.samplerParameteri(samplerB, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);gl.samplerParameteri(samplerB, gl.TEXTURE_MAG_FILTER, gl.LINEAR);gl.samplerParameteri(samplerB, gl.TEXTURE_WRAP_S, gl.MIRRORED_REPEAT);gl.samplerParameteri(samplerB, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT);// ...gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D, texture);gl.bindSampler(0, samplerA);gl.activeTexture(gl.TEXTURE1);gl.bindTexture(gl.TEXTURE_2D, texture);gl.bindSampler(1, samplerB);欢迎关注公众号“ITman彪叔”。彪叔,拥有10多年开发经验,现任公司系统架构师、技术总监、技术培训师、职业规划师。在计算机图形学、WebGL、前端可视化方面有深入研究。对程序员思维能力训练和培训、程序员职业规划有浓厚兴趣。欢迎关注公众号“ITman彪叔”。彪叔,拥有10多年开发经验,现任公司系统架构师、技术总监、技术培训师、职业规划师。熟悉Java、JavaScript、Python语言,熟悉数据库。熟悉java、nodejs应用系统架构,大数据高并发、高可用、分布式架构。在计算机图形学、WebGL、前端可视化方面有深入研究。对程序员思维能力训练和培训、程序员职业规划有浓厚兴趣。 ...

September 7, 2019 · 1 min · jiezi

敏捷开发详解含义原则目标机制

我们理解东西习惯从已知连接未知,首先我们来对比一下。我们最先了解到的是瀑布模型,那么它就是不敏捷的。瀑布开发模式把开发分成一系列阶段,如需求、设计、开发、测试,就像下图它画出来的,看起来很像瀑布,所以叫瀑布开发。问题是需求的交付难道不都是要经历这些阶段吗? 瀑布开发的本质问题并不是阶段,而是批量。需求批量地在一起进行设计,然后是批量地开发,批量地测试、交付等等。批量有什么问题? 首先,批量让价值交付延迟,所有需求在最后的阶段才能交付,价值交付比较晚。Google执行董事长施密特提出过反摩尔定律,表述为:“如果18个月之后我们只能卖出跟今天一样的东西,我们就只能得到一半的收入。”价值的交付时间将直接影响收入。 敏捷的目标1:敏捷开发有第一个目标就是更快的交付价值,这里的快指的不是绝对速度,而是更早的交付。在项目结束的时候,一定是对产品和项目的知识理解最充分的时候。这显而易见,我们在项目进程中积累了知识,特别是当向用户交付产品后,用户反馈:“我要的不是这个啊,我说的明明是……”,这时候你瞬间狂涨知识,并感叹道“你怎么不早说呢?”。这中间可能有沟通问题,但更多可能的是,用户这时才清楚或能够描述他们要的是啥,更有甚者,我们可能一开始连用户是谁也未必能准确地定义。产品和业务开发本来就是一个探索的过程,开始时一定是最无知的时刻。项目中的大部分决策也一定是在项目开始的时刻做出的,这将有一个重大的悖论,在最无知的时刻,做出了最重要而且是绝大部分的决策,并把它作为随后执行的依据。面对不确定的技术、市场环境,传统开发模式已无法适应要求,悖论越发突出。敏捷开发将通过迭代应对这一问题,只做初始决策,定大致的方向。通过市场反馈不断修正对产品的认知,增量的决策和调整。 敏捷的目标2:产品开发过程中,技术环境、市场环境、竞品策略、团队认知都会发生变化。面对变化的环境,我们必须承认自己的无知,在开发过程主动有效地学习,不断地汲取反馈,灵活地调整。这也是敏捷的第二个业务目标,有效学习和灵活响应变化。 敏捷开发工具敏捷过程敏捷开发是一种以人为核心,以迭代方式循序渐进开发的方法,其软件开发的过程称为“敏捷过程”。 在这一过程中,软件项目的构建被切分成多个子项目,各个子项目的成功都经过测试,具备集成和可运行的特征。 在2001年年初,一些业界专家成立了敏捷联盟,起草了敏捷软件开发宣言。该宣言针对一些企业的现状,提出了让软件开发团队具有快速工作、快速应变能力的若干价值观和原则,其中包括4个简单的价值观以及敏捷开发方法应遵循的12条原则。 敏捷开发的价值观1.个人和交互胜过过程和工具。2.可以运行的软件胜过面面俱到的文档。3.客户合作胜过合同谈判。4.响应变化胜过遵循计划。 敏捷开发应遵循的12条原则1.通过尽早的、不断地提交有价值的软件来使客户满意。2.即使到了开发的后期,也欢迎改变需求。敏捷过程利用变化来为客户创造竞争优势。3.以从几个星期到几个月为周期,尽快、不断地提交可运行的软件。4.在整个项目开发期间,业务人员和开发人员必须天天都在一起工作。5.以积极向上的员工为中心,建立项目组,给他们提供所需的环境和支持,并对他们的工作予以充分的信任。6.在团队内部,最有效、效率最高的传递信息的方法,就是面对面的交流。7.测量项目进展的首要依据是可运行软件。8.敏捷过程提倡可持续的开发,责任人、开发者和用户应该为能够保持一个长期的、恒定的开发速度而努力。9.时刻关注技术上的精益求精和好的设计,以增强敏捷能力。10.简单是最根本的。11.最好的构架、需求和设计出于自组织的团队。12.每隔一定时间,团队要反省如何才能更有效地工作,然后相应地调整自己的行为。 敏捷组织提出的敏捷开发模型的整体框架主要有三个:Scrum、XP(eXtreme Programming)、OpenUP 这3个敏捷实践。 敏捷开发的原则1.凝聚人的力量,紧密协(合)作。包括业务负责人、开发团队、客户、管理者之间的关系,所有这些关系在以前都是造成项目危机的原因之一,那么,在敏捷时代,我们需要这些角色 紧密合作,最大限度的发挥各个角色的力量.2.聚焦客户价值,消除浪费(如何聚焦用户价值,即频繁的交付用户可工作的软件,快速收到用户反馈) 敏捷团队运作机制1.一个团队有自己的代办事项,对代办事项进行拆小。2.按客户价值进行优先级排序,产品经理负责价值排序。3.小而稳定,跨职能团队。4.多个团队松耦合(依赖性比较低),对齐迭代时间和战略目标。 关键的团队角色产品负责人Scrum主管(流程主管)开发团队 产品负责人(Product Owner)负责管理产品backlog(代办事项)的唯一负责人代表客户/项目如责任人定义产品的所有特性负责产品的投入产出负责最大化产品和开发团队工作的价值 Scrum Master(流程主管)起到教练的职责,领导团队完成Scrum的实践以及体现其价值。排除团队遇到的困难,使得团队紧密合作,使得团队个人具有多方面职能的工作能力。确保团队能胜任其工作,并保持高效的生产率。保护团队不受到外来无端影响 关键的团队活动每日例会:每日5分钟左右的一个简单例会,尽可能多的开发人员参与进来对紧要问题的讨论。评审会:需要在迭代周期的最后一天召开,1个小时左右就可以了,需要客户出席,如果客户不能出席,则需要产品经理出席迭代回顾会:迭代回顾会是在每个迭代结束时进行,总结工作中的经验和教训,时间维持在30-60分钟内,整个团队都需要参加(Scrum Master、Product Owner、开发团队以及客户)。迭代回顾会包括两部分,第一部分是定量分析,第二部分是定性分析。其中定量分析又包含团队是否完成了迭代目标,收集并评审迭代度量指标(包括速率、迭代燃尽图、迭代计划故事和实际完成故事、计划发布日期与实际发布日期、客户满意度、团队满意度、生产环境Bug数、生产Bug解决时间、用户故事等)。定性分析包含哪些工作良好(应该继续保持),哪些做的不好(应该停止)?哪些可以改进(团队选出1-2条在下一个迭代实现)?

September 7, 2019 · 1 min · jiezi

前端面试每日-31-第144天

今天的知识点 (2019.09.07) —— 第144天[html] SGML(标准通用标记语言)和HTML(超文本标记语言),XML(可扩展标记语言)和HTML的之间有什么关系?[css] 说下你对background-size的理解,它有什么运用场景?[js] 什么是词法分析?请描述下js词法分析的过程?[软技能] W3C是什么?请说说你对它的理解《论语》,曾子曰:“吾日三省吾身”(我每天多次反省自己)。 前端面试每日3+1题,以面试题来驱动学习,每天进步一点! 让努力成为一种习惯,让奋斗成为一种享受!相信 坚持 的力量!!!欢迎在 Issues 和朋友们一同讨论学习! 项目地址:前端面试每日3+1 【推荐】欢迎跟 jsliang 一起折腾前端,系统整理前端知识,目前正在折腾 LeetCode,打算打通算法与数据结构的任督二脉。GitHub 地址 微信公众号欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎点个Star, 同时欢迎微信扫码关注 前端剑解 公众号,并加入 “前端学习每日3+1” 微信群相互交流(点击公众号的菜单:进群交流)。 学习不打烊,充电加油只为遇到更好的自己,365天无节假日,每天早上5点纯手工发布面试题(死磕自己,愉悦大家)。希望大家在这浮夸的前端圈里,保持冷静,坚持每天花20分钟来学习与思考。在这千变万化,类库层出不穷的前端,建议大家不要等到找工作时,才狂刷题,提倡每日学习!(不忘初心,html、css、javascript才是基石!)欢迎大家到Issues交流,鼓励PR,感谢Star,大家有啥好的建议可以加我微信一起交流讨论!希望大家每日去学习与思考,这才达到来这里的目的!!!(不要为了谁而来,要为自己而来!)交流讨论欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎点个[Star] https://github.com/haizlin/fe...

September 7, 2019 · 1 min · jiezi

好物分享

好物分享去年做了一个“帮我记”。帮我记录了很多事情,从此很少错过重要的时刻。 这一年,工作一直比较忙,很多时候来不及打开“帮我记”记下需要提醒我的事情,有时忙一周下来已经忘了周一周二都干了啥,甚至会突然想不起接下来要做什么。周报都是到deadline时被提醒才想起来,内容也要想半天去总结。 一直在思考怎么提高个人效率(生活,工作等),所以上周末两天又开发了一个网站(https://www.qbian.me/efficient),按照项目和日常两种纬度去创建任务,可设置定时任务提醒,可自定义时间范围统计已完成任务,可自定义任务清单推送时间,实现自动发日报、周报。 使用了一周,每天要做的事一目了然,重要的事没有错过,周报也被定时发送。 欢迎大家体验,多提建议;

September 7, 2019 · 1 min · jiezi

前端技术日志-在生产环境中使用原生-JavaScript-模块

本期刊专注于 Web 前端前沿技术,收集的内容来自于国外各大前端技术周刊,这里把自己感兴趣的,并值得分享的内容做了整理。部分链接可能无法直接打开,你需要通过科学上网的方式来解决。 本期热文在生产环境中使用原生 JavaScript 模块归功于打包技术的发展,现在,你可以将生产代码部署为 ES2015 模块了——包括静态和动态导入,而且比目前的非模块方式能获得更好的性能。 https://philipwalton.com/arti... PHILIP WALTON Web Template Studio 2.0Web Template Studio 是来自微软的 Visual Studio Code 的一个扩展,可以从 VS Code 以“向导”式风格生成新的全栈应用程序。 支持 Angular,Vue 和 React。 https://blogs.windows.com/win... LEA AKKARI (MICROSOFT) 2019年8月的 JavaScript 框架状态(视频)每隔半年,Tracy Lee 就会与几位不同框架的代表坐下来,来简单了解他们的工作状况。这一小时的剧集包含了 Evan You(Vue.js),Minko Gechev(Angular),Michael Dawson(Node.js),Jen Weber(Cardstack),Manu Mtz.-Almeida(Ionic)和 Marvin Hagemeister(Preact)。 https://www.youtube.com/watch... TRACY LEE 你应该知道的 React 中的 JavaScript在学习和使用 React 时,您应该要熟悉的 JavaScript 特性示例。 https://kentcdodds.com/blog/j... KENT C DODDS Node v12.9.0 发布,推出了 V8 7.6升级到 V8 7.6 后开辟了一些新机会,比如 Promise.allSettled()、JSON.parse 和 frozen/sealed 的数组性能改进,BigInt 现在有一个 toLocaleString 的方法可用于大数字的本地格式化。 ...

August 28, 2019 · 2 min · jiezi

HTML5实时语音通话聊天MP3压缩传输3KB每秒

自从Recorder H5 GitHub开源库优化后,对边录边转码成小语音片段文件实时上传服务器这种操作支持非常良好,因此以前不太好支持的H5语音通话已经有了更好的突破空间。因此花了两晚时间打造了一个H5语音通话聊天的demo。欢迎在线把玩:https://xiangyuecn.github.io/Recorder/ 一、把玩方法准备局域网内两台设备(Peer A、Peer B)用最新版本浏览器(demo未适配低版本)分别打开demo页面(也可以是同一浏览器打开两个标签)勾选页面中的H5版语音通话聊天,在Peer A中点击新建连接把Peer A的本机信手动复制传输给Peer B,粘贴到远程信息中,并点击确定连接把Peer B自动生成的本机信息手动复制传输给Peer A,粘贴到远程信息中,并点击确定连接双方P2P连接已建立,使用页面上方的录音功能,随时开启录音,音频数据会实时发送给对方局域网H5版对讲机????二、技术特性(1)数据传输github demo中考虑到减少对服务器的依赖,因此采用了WebRTC P2P传输功能,无需任何服务器支持即可实现局域网内的两个设备之间互相连接,连接代码也算简单。有服务器支持可能就要逆天了,不过代码也会更复杂。 如果正式使用,可能不太会考虑使用WebRTC,用WebSocket通过服务器进行转发可能是最佳的选择。 WebRTC局域网P2P连接要点(实际代码其实差不多,只不过多做了点兼容): /******Peer A(本机)******/var peerA=new RTCPeerConnection(null,null)//开启会话,等待远程连接peerA.createOffer().then(function(offer){ peerA.setLocalDescription(offer); peerAOffer=offer;});var peerAICEList=[......] //通过peerA.onicecandidate监听获得所有的ICE连接信息候选项,如果有多个网络适配器,就会有多个候选//创建连接通道对象,A端通过这个来进行数据发送var peerAChannel=peerA.createDataChannel("RTC Test");/******Peer B(远程)******/var peerB=new RTCPeerConnection(null,null)//连接到Peer ApeerB.setRemoteDescription(peerAOffer);//开启应答会话,等待Peer A确认连接peerB.createAnswer().then(function(answer){ peerB.setLocalDescription(answer); peerBAnswer=answer;});//把Peer A的连接点都添加进去peerB.addIceCandidate(......peerAICEList)var peerBICEList=[......] //通过peerB.onicecandidate监听获得所有的ICE连接信息候选项,如果有多个网络适配器,就会有多个候选var peerBChannel=... //通过peerB.ondatachannel得到连接通道对象,B端通过这个来进行数据发送/*******最终完成连接********///连接到Peer BpeerA.setRemoteDescription(peerBAnswer);//把Peer B的连接点都添加进去peerA.addIceCandidate(......peerBICEList)/*peerA peerB分别等待peerA/BChannel.onopen回调即完成P2P连接,然后通过监听peerA/BChannel.onmessage获得对方发送的信息,通过peerA/BChannel.send(data) 发送数据。*/(2)音频采集和编码由于是在我的Recorder库中新加的demo,因此音频采集和编码都是现成的,Recorder库有好的兼容性和稳定性,因此节省了最大头的工作量。 编码最佳使用MP3格式,因为此格式已优化了实时编码性能,可做到边录边转码,16kbps 16khz的情况下可做到2kb每秒的文件大小,音质还可以,实时传输时为3kb每秒,15分钟大概3M的流量。 用wav格式也可以,不过此格式编码出来的数据量太大,16位 16khz接近50kb每秒的实时传输数据,15分钟要37M多流量。其他格式由于暂未对实时编码进行优化,使用中会导致明显卡顿。 降噪、静音检测等高级功能是没有的,毕竟是非专业人员???? 要求高点可以,但不要超出范围太多啦。 (3)音频实时接收和播放接收到一个音频片段后,本应该是立即播放的,但由于编码、网络传输导致的延迟,可能上个片段还未播放完(甚至未开始播放),因此需要缓冲处理。 因为存在缓冲,就需要进行实时同步处理,如果缓冲内积压了过多的音频片段,会导致语音播放滞后太多,因此需要适当进行对数据进行丢弃,实测发现网络正常、设备性能靠谱的情况下基本没有丢弃的数据。 然后就是播放了,本应是播完一个就播下一个,测试发现这是不靠谱的。因为结束一个片段后再开始播放下一个发出声音,这个过程会中断比较长时间,明显感觉得出来中间存在短暂停顿。因此必须在片段未播完时准备好下一个片段的播放,并且提前开始播放,达到抹掉中间的停顿。 我写了两个播放方式: 实时解码播放双Audio轮换播放最开始用一个Audio停顿感太明显,因此用两个Audio轮换抹掉中间的停顿,但发现不同格式Auido播放差异巨大,播放wav非常流畅,但播放mp3还是存在停顿(后面用解码的发现是得到的PCM时长变长了,导致事件触发会出现误差,为什么会变长?怪异)。 因此后面写了一个解码然后再播放,mp3这次终于能正常连续播放了,wav格式和双Audio的播放差异不大。实时解码里面也用到了双Audio中的技巧,其实也是用到了两个BufferSource进行类似的轮换操作,以抹掉两个片段间的停顿。 不过最终播放效果还是不够好,音质变差了点,并且多了点噪音。如果有现成的播放代码拿过来用就就好了。 三、应用场景数据传输改成WebSocket,做个仿微信语音通话H5版还是可以的(受限于Recorder浏览器支持)局域网H5版对讲机(前端玩具)......没有想到完。

August 28, 2019 · 1 min · jiezi

xss攻击执行原理分析

什么是XSS?xss全称跨站脚本(Cross-site scripting),是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。这类攻击通常包含了HTML以及用户端脚本语言。 危害XSS带来的危害有:窃取用户cookies,窃取个人信息;劫持会话,操纵用户网络数据;发起ddos攻击; 篡改页面、弹出广告等。 类型1、非持久型 1.1 反射型 用户将带有xss攻击的代码作为用户输入传给服务端,服务端没有处理用户输入直接返回给前端。 1.2 DOM-based型 DOM-based xss是由于浏览器解析机制导致的漏洞,服务器不参与。因为不需要服务器传递数据,xss代码会从url中注入到页面中,利用浏览器解析script、某些标签的属性和方法触发xss 。 2、持久型 用户含有xss代码的输入被存储到数据库或者存储文件上。 xss执行原理造成xss代码执行的根本原因就在数据渲染到页面过程中,html解析触发执行了xss脚本。 脚本的注入分两类: 1、直接注入script脚本。 2、通过某些标签的属性和事件。比如: <img src="aaa.png" onerror="javascript:alert('xss');"><a href="javascript:alert('xss');">xss</a>等 直接注入script脚本:我们可能经常使用jquery,通过html()方法去操作页面。这个时候就会触发xss,因为jquery的html()方法设计初衷就是让js脚本执行。 原因是:jquery解析到script就会通过createElement('script')创建一个script节点,而此时浏览器就会去执行这个script; 同样的原生js的api,innerHTML也会把含有script脚本的字符串当成标签解析到浏览器,只不过因为浏览器加载js的原则:只会在页面加载时执行一次。所以通过innerHTML无法触发xss。 text()、innerText等方法都是把含xss字符串当作文本节点,所以无法被解析成html节点,也就不会触发xss。 通过属性和事件: <img src="aaa.png" onerror="javascript:alert('xss')">因为img标签未闭合所以会触发 onerror事件,导致xss脚本执行。通过属性和事件触发是依赖html标签注入到页面,在这个过程中会被chrome浏览器的XSS Auditor拦截。 防御请记住一句:不要相信用户的输入。 XSS防御的总体思路是:对输入(和URL参数)进行过滤,对输出进行转义。

August 28, 2019 · 1 min · jiezi

你不知道WebSocket吗

什么是WebSocket?WebSocket是一种在单个TCP连接上进行全双工通信的协议。这里我们发现了一个有趣的词:”全双工”,那我们就来简单了解下通信方式有哪些! 单工通信双方中,一方固定为发送端,一方则固定为接收端。信息只能沿一个方向传输。例如计算机与打印机之间的通信是单工模式 说的简单些就是:我打你你只能忍着! 半双工允许数据在两个方向上传输,但是同一时间数据只能在一个方向上传输,其实际上是切换的单工。例如HTTP协议:客户端向服务器发送请求(单向的),然后服务器响应请求(单向的) 说的简单些就是:我打你,你忍完后可以打我,我忍着… 全双工允许数据在两个方向上同时传输。例如手机通话,WebSocket就是这个样子! 说的简单些就是:两个人同时可以互相打对方 说了这么多其实目的就是让大家知道,WebSocket是支持双向通信的!双向通信的优点为什么要支持双向通信?单向通信有什么问题?还是从HTTP说起,我们知道HTTP协议是半双工的,而且服务器不能主动推送消息给浏览器!这个就是他的缺陷。假若我希望实现一个股票交易系统,可能股价每秒钟都有变化,但是价格变化了如何通知我们的客户端? 咱们来看看以前是怎么实现的! 轮询什么叫轮询?就是不停的轮番询问!说的直白些就是客户端定期发送请求给服务端。 短轮询配段代码,Talk is cheap,show me your code. const express = require("express");const app = express();// express 静态服务中间件用来返回静态文件app.use(express.static(__dirname));// 当前价格是100元let currentPrice = 100;// 获取最新价格接口app.get("/getPrice", (req, res, next) => { res.send('¥'+currentPrice * Math.random());});app.listen(3000);客户端不停的发送请求,去服务端获取最新价格。 <div>当前交易价格: <span id="price"></span></div><script> setInterval(() => { fetch('/getPrice'). then(res=>res.text()). then(data=>price.innerHTML = data) }, 1000);</script>很快我们就看出了这样编写代码的缺陷!如果数据变化的不快呢,那就会发送很多无意义的请求。每次发送请求都会有HTTP的Header会消耗大量流量,同时也会消耗CPU的利用率!长轮询长轮询是对短轮询的改进版,就是当第一个请求回来时再发送下一个请求! (function poll(){ fetch('/getPrice'). then(res=>res.text()). then(data=>{price.innerHTML = data;poll()})})()问题依旧是显而易见的!如果服务端数据变化很快,那么请求数目会更多;如果变化很慢,可能ajax会出现超时的问题。Iframe方式我们并不希望每次都创建一个新的请求,此时就可以使用Iframe来实现长连接 app.get("/getPrice", (req, res, next) => { setInterval(()=>{ // 不能使用end 否则会中断请求,我们要实现的是长连接 res.write(` <script> parent.document.getElementById('price').innerHTML = ${currentPrice * Math.random()} </script> `); },1000);});<body> <div>当前交易价格: <span id="price"></span></div> <iframe src="/getPrice" frameborder="0"></iframe></body>现在确实可以利用Iframe实现了长连接通信,但是页面的状态一直是加载态!EventSource流EventSource 接口用于接收服务器发送的事件。它通过HTTP连接到一个服务器,以text/event-stream 格式接收事件, 不关闭连接。 ...

August 28, 2019 · 2 min · jiezi

前端面试每日-31-第134天

今天的知识点 (2019.08.28) —— 第134天[html] Web Worker线程的限制是什么?[css] transition、animation、transform三者有什么区别?[js] [请写出如下代码运行的结果并解释为什么?[代码]](https://github.com/haizlin/fe... var type = 'images'; var size = {width: 800, height: 600}; var format = ['jpg', 'png']; function change(type, size, format){ type = 'video'; size = {width: 1024, height: 768}; format.push('map'); } change(type, size, format); console.log(type, size, format);[软技能] 你在工作中有用到过websocket吗?用它来解决什么问题?《论语》,曾子曰:“吾日三省吾身”(我每天多次反省自己)。 前端面试每日3+1题,以面试题来驱动学习,每天进步一点! 让努力成为一种习惯,让奋斗成为一种享受!欢迎在 Issues 和朋友们一同讨论学习! 项目地址:前端面试每日3+1 【推荐】欢迎跟 jsliang 一起折腾前端,系统整理前端知识,目前正在折腾 LeetCode,打算打通算法与数据结构的任督二脉。GitHub 地址 微信公众号欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎点个Star, 同时欢迎微信扫码关注 前端剑解 公众号,并加入 “前端学习每日3+1” 微信群相互交流(点击公众号的菜单:进群交流)。 学习不打烊,充电加油只为遇到更好的自己,365天无节假日,每天早上5点纯手工发布面试题(死磕自己)。希望大家在这浮夸的前端圈里,保持冷静,坚持每天花20分钟来学习与思考。在这千变万化,类库层出不穷的前端,不建议大家等到要找工作时,才狂刷题,提倡每日学习!(不忘初心,html、css、javascript才是基石!)欢迎大家到Issues交流,鼓励PR,感谢Star,大家有啥好的建议可以加我微信一起交流讨论!交流讨论欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎点个[Star] 前端面试每日3+1

August 28, 2019 · 1 min · jiezi

前端20个灵魂拷问-彻底搞明白你就是中级前端工程师-下篇

不知不觉,已经来到了最后的下篇 其实我写的东西你如果认真去看,跟着去写,应该能有不少的收获。最近一些跨平台技术,React-native和flutter之类的,比较火。但是,我还是不准备把它们放进来,因为那是为做App而生,我想把Electron这个桌面端跨平台的技术放进来。理由是什么,后面说 这是上篇和中篇,如果你是第一次看这个系列文章,欢迎去从头开始学习: 前端20个灵魂拷问 彻底搞明白你就是中级前端工程师 【上篇】前端20个灵魂拷问 彻底搞明白你就是中级前端工程师 【中篇】 以及一些比较不错的文章: 从零编写一个React框架 我们为什么要熟悉这些通信协议 单页面应用SPA原理 9102年:手写一个React脚手架 【优化极致版】 性能优化不完全手册 Electron跨平台入门系列 上面的文章,gitHub上,都有对应的源码。进入正题一千个人眼里有一千个哈姆雷特,我们做不到完美每个人评判的标准不一样,我们唯有拿出碾压这个层级的能力的时候,才能堵住质疑者的嘴。当然,我们不做技术杠精,技术本身没有好坏。不喜欢就不理会 最后问题,我准备如下内容:前端的性能优化方向从传输层面去优化的方向预解析地址 首次请求解析地址如果没有缓存 那么可能消耗60-120ms 性能优化不完全手册这里面有介绍 preload预请求必要内容,prefetch预请求可能需要内容 这种请求方式不会阻塞浏览器的解析,而且能将预请求的资源缓存起来,而且可以设置crossorgin进行跨域资源的缓存,不会推迟首屏的渲染时间,还会加快后面的加载时间,因为后面的本身需要的资源会直接从缓存中读取,而不会走网络请求。 使用 preload 前,在遇到资源依赖时进行加载: 使用 preload 后,不管资源是否使用都将提前加载: 可以看到,preload 的资源加载顺序将被提前: 使用 preload 后,Chrome 会有一个警告: preload 和 prefetch 混用的话,并不会复用资源,而是会重复加载。若不确定资源是必定会加载的,则不要错误使用 preload,以免本末倒置,给页面带来更沉重的负担。 preload 加载页面必需的资源如 CDN 上的字体文件,与 prefetch 预测加载下一屏数据,兴许是个不错的组合。 preload和prefetch详解 这篇文章写得很棒 感谢作者 减少传输次数部分图片base64处理,然后使用雪碧图。多张图拼成一张传输 当然base64这个东西慎用,实际开发中它表现并那么好 减少传输体积例如后端返回数据:“该用户没有拥有权限” 可以改成:0 约定优于配置的思想一定要有 使用probbuffer协议ProtoBuffer是由谷歌研发的对象序列化和反序列化的开源工具 它的本质就是将一段数据序列化,转变成二进制形式传输 然后另外的服务器端或者客户端接受到之后 反序列化,转换成对应的数据格式(json) 好像还有人没有听说这个传输协议 其实它传输过程就是2进制流的形式 用得最多的是和GRPC配合Go语言或者服务器之间传输数据 ...

August 28, 2019 · 3 min · jiezi

技术型产品既要轻速度也要重壁垒

轻速度在打磨产品的过程中,很容易陷入技术的思维怪圈. 既想要快速的完成功能的开发,也想要性能的稳定和优化. 这大概是完美主义在作祟,加上一点点代码洁癖的影响. 在尝试开发各种类型的产品之后. 才发现,没有必要一开始就尽善尽美, 快速开发,小步迭代,才是王道. 在最快的时间开发出一款最小应用. 有着最基本的功能和反馈系统. 剩下的再合理分配时间,逐步添加和调整功能. 如小程序,自身有着完善的生态体系, 集成了登录,支付,分享等一些常用的API APP,在很多公司依旧采用着混合开发的方式. PC客户端,就拿Electron和PyQt来说, 初期的产品根本用不着原生的写法,直接套用网页即可. 体验需要增加的地方,留到后面在单独分离出来开发. 现在的前端相比以前 无论是在功能上还是体验上,都有很大的提升. 后端也可以尝试ServerLess,后端云服务 解决数据和运维相关的问题 总而言之,从时间上考虑 能够复用的页面和功能,就不要用多种语言重新开发 能够使用第三方产品和服务的,就不要自己造轮子. 前期开发,留给后期修改的空间即可. 重壁垒如果说互联网的产品有一大半是建立在数据的基础上 那么,物联网的产品就是建立在其硬件模块上. 5G到来,势必会重新刺激一度混乱的物联网市场. 物联网的本质其实还是互联网 只不过比起互联网,多了硬件成本 要想了解和学习互联网 还需要学习一些内容,如: 数电模电、单片机编程,嵌入式开发网络技术,也就是互联网的客户端和服务端无线技术,即通信协议,wifi,蓝牙等传感器技术,各类对应传感器的使用...... 现在的物联网,还没有一套业界公认的规范和协议 编程语言和通信协议等都是各自为政,很难互通 再加上硬件上的多种多样性,开发的难度可想而知. 重点是,要想入门物联网,要投入远比互联网多几倍的时间和精力 如果不是兴趣使然和拥有一个百折不挠爱折腾的心态 怕是很难接受,幸辛苦苦好几天,就只是点亮一个灯...... 但是,越是混乱,越是困难,壁垒越高 普通人很容易望而生畏,也很难提起兴趣 因为没有足够的即时反馈 互联网的产品很容易复制,模仿UI开发或者爬取数据 只要竞争者烧更多的钱和投入更多地资源 那么你的产品,就失败了,因为你能做,别人也能 甚至比你做的更好. 抄袭?不存在的,你说了我也不认. 但是物联网不一样,成本越高,越难入局 小结 轻速度和重壁垒开起来是两个相反的方向 但也存在相互交叉包含的场景 在互联网应用里找到属于自己的专利和功能 在物联网应用里找到最快速开发的方法和技术 先速度,后壁垒,先功能,后优化.

August 28, 2019 · 1 min · jiezi

第三篇-仿写Vue生态系列枚举与双向绑定

( 第三篇 )仿写'Vue生态'系列___" '枚举' 与 '双向绑定' " 本次任务 对'遍历'这个名词进行死磕.对defineProperty进行分析.实现cc_vue的数据双向绑定.为下一篇 Proxy 代替 defineProperty 做预热.一. 'forEach' vs 'map'很多文章都写过他们两个的区别 forEach没有返回值, map会返回一个数组map利于压缩, 因为毕竟只有三个字母.但是这些区别只是表面上的, 我来展示一个有趣的???? <div id="boss"> <div>1</div> <div>2</div> <div>3</div></div><script> let oD = document.getElementById('boss'); // 正常执行 oD.childNodes.forEach(element => {console.log(element); }); // 报错 oD.childNodes.map(element => { console.log(element); });</script>oDs.childNodes 并不是个数组, 他仍然是伪数组, 但是他可以使用forEach, 这个挺唬人的, 第一反应是这两个遍历方法在实现的方式上是不是有什么不同, 但转念一想感觉自己想歪了, 答案其实是 oDs.childNodes这个伪数组形成的时候, 往身上挂了个forEach... 通过上面的问题我有了些思考 map既然返回新数组, 那就说明他空间复杂度会大一些.某些系统提供的伪数组, 本身会挂载forEach但不会挂载map.综上所述, 还是用forEach保险! 但是就想用map怎么办那?1: slice的原理就是一个一个的循环放入一个新数组; let slice = Array.prototype.slice;slice.call(oD.childNodes).map(()=>{})2: 扩展运算符原理不太一样, 但他一样可以把所有元素都拿出来, 接下来我们就对他进行死磕. ...

August 27, 2019 · 5 min · jiezi

好快-1分钟开发好一个下拉刷新滚动加载列表

好快, 1分钟写好下拉刷新,滚动加载自动分页列表前言欢迎关注BUI Webapp专栏 或者 bui神速微信公众号. 以往文章: 2019开发最快的Webapp框架--BUI交互框架微信Webapp开发的各种变态路由需求及解决办法!【BUI实战篇】BUI数据驱动做的拼图游戏 Webapp移动适配版,基于vuejs拼图游戏改造webapp结合Dcloud平台打包图文教程一张脑图看懂BUI Webapp移动快速开发框架【上】--框架与工具、资源一、观看实操视频 点击观看视频实录 安装完以下环境后, 从0到1, 手把手教, 你也可以做到!二、开发准备安装buijs cli命令行工具(需要先安装node环境, 建议使用node 8.x);如何安装使用buijs?安装bui-fast 快速编辑器插件(推荐vscode);如何安装使用bui-fast?打开跨域的chrome浏览器;如何打开跨域的Chrome浏览器?三、开发过程使用 buijs 构建工程 1.创建Webapp工程buijs create demo2.安装依赖cd demo/npm installwindows 推荐使用淘宝的 cnpm install3.运行预览npm run dev使用bui-fast编辑器插件生成控件视频里使用的是vscode 可以在安装插件那里找到 bui-fast. xxx 假设为控件名生成规则1: 在html里, 使用 ui-xxx 生成控件结构ui-list生成以下结构 <div id="uiList" class="bui-scroll"> <div class="bui-scroll-head"></div> <div class="bui-scroll-main"> <ul class="bui-list"> </ul> </div> <div class="bui-scroll-foot"></div></div>在js里, 使用 bui-xxx 生成控件的初始化代码bui-list生成以下初始化代码 // 列表控件 js 初始化:var uiList = bui.list({ id: "#uiList", url: "http://rap2api.taobao.org/app/mock/84605/example/getNews", pageSize: 5, data: {}, //如果分页的字段名不一样,通过field重新定义 field: { page: "page", size: "pageSize", data: "data" }, callback: function(e) {}, template: function(data) { var html = ""; data.forEach(function(el, index) { html += `<li class="bui-btn bui-box"> <div class="bui-thumbnail"><img src="${el.image}" alt=""></div> <div class="span1"> <h3 class="item-title">${el.name}</h3> <p class="item-text">${el.address}</p> <p class="item-text">${el.distance}公里</p> </div> <span class="price"><i>¥</i>${el.price}</span> </li>` }); return html; }});保存就会自动预览四、从bui.list看自动分页设计原理 ...

August 27, 2019 · 2 min · jiezi

如何把-alibaba-Rax-组件转换到-React-下

背景最近接手公司的一个移动端项目,是通过 Rax 作为 dsl 开发的,在发布的时候构建多分代码,在 APP 端编译为能够运行在 weex 上的代码,在 H5(跑在浏览器或者 webview 里面,不管什么技术我们统称 H5) 端使用降级的 weex 这一套开发体系,看起来很完美,一次开发,三端运行。但是真实在开发的时候,就不是这么完美了。由于毕竟是跑在 weex 上的,而不是浏览器。所以在开发方式上也很难直接从 web 端的开发方式平移过去,为了实现跨端运行,所以在样式上只实现了 Css 的子集, DOM API 也是如此,开发的时候,在浏览器里面调试的时候,一切正常,但是等发布到 APP 端用 weex 跑的时候又是各种问题,开发体验很不流畅。 当然,有人会说那是因为你对 weex 的 api 不了解,也对,一直以来对与这种自己搞一套非标准体系来实现各种魔法功能的东西都不怎么感兴趣 但是如果了解它的成本大于了它带来的收益,那么对我们来说,就没有必要做这件事情。 weex 相对于 H5 ,最大的优点在于交互性能上要更好一点。 而随着手机性能的提升,以及 webview 的不断优化,H5 的页面也越来越流畅了,尤其是纯展示形页面上。而且相较于 H5 ,weex 天生不具备 seo 能力,同时存在分享传播困难的缺点,这样看来,使用 weex 的理由就更少了。而且我们在一个新业务上使用 H5 开发了一个页面,借助同构以及提前缓存的能力,已经把首屏打开速度做到了全球秒开,而且业务数据也达到预期,所以我们打算把现有的存量业务都迁移到 H5 上。 这就是我为什么要把基于 Rax 开发的模块代码转换为 React 代码,也就有了本篇文章。本文针对的 rax 版本是 0.6.8 ,1.x 的版本改动很大,不在本文讨论范围内。 期望的目标对于一个 rax 模块,我们期望通过编译后: ...

August 21, 2019 · 9 min · jiezi

极简爬虫攻防战纪要

极简爬虫攻防战纪要     爬虫是构建搜索引擎的基础, 负责抓取网页信息并对网页识别、分类及过滤。我们熟识的电商、搜索、新闻及各大门户网站都有强大的爬虫集群在每天高负荷运转: 京东 v.s. 淘宝 v.s. 拼多多相互之间"友好地"价格监控, 头条 v.s. 网易 v.s. 腾讯相互之间"和谐地"新闻消息聚合借鉴, Google / 百度 / 搜狗纷纷尽职地做网页信息的搜索优化以及各大研究机构卖力地进行数据集构建。<br />     然而, 各大网站是不太会对非搜索引擎的爬虫网开一面、任其予取予求的,毕竟无论什么时候,内容的价值都是显而易见的,所以就有了下面的爬虫方与反爬方的混战大戏~<br />     各个巨头之间的爬虫与反爬虫的攻防战斗没有一刻放松, 反爬网站要想制定反爬策略, 就要根据爬虫的特性针对性选择方案, 那么爬虫有什么特点? 脚本 + 自动化。因此反爬方的毁灭性大招无非两个: 非脚本访问 => 浏览器真实性检测非自动化访问 => 访问用户真实性检测惨烈的战斗即将打响! 非战斗人员迅速撤离! Round One: Are you Really a Browser?     浏览器由于其运行环境及运行原理, 会自带一些特有的属性: 存在Headers用于协议negotiation、可执行JavaScript代码片段。那么反爬方的第一个堡垒就基于浏览器的真实性检测开始构建。<br />     战役伊始, 反爬虫方率先祭出User-Agent, Content-Type, Application/*,iAccept-Encoding, Accept-Language, X-Forwarded-For, Referer等headers电网, 第一批与正常浏览器headers不同的爬虫纷纷触发, 瞬间毙命。然而, 爬虫方也不是吃素的! 他们用了一招漂亮的瞒天过海, 迅速通过伪造headers的方式突破防线! <br />     反爬方丝毫不慌, 在html中添加了一段JavaScript脚本地雷, 己方浏览器由于提前知道了地雷的位置,可以安全绕过, 不会影响正常的网页显示, 爬虫方却不明就里, 纷纷中招, 非死即伤,直到大杀器Node.js出现,可以直接执行JavaScript,爬虫方终于奋起反击,再下一城!![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2019/png/88875/1565271756288-b128de6c-0efa-42bb-9b56-8fdc09caaf77.png#align=left&display=inline&height=178&name=image.png&originHeight=178&originWidth=984&size=194086&status=done&width=984)<br />     反爬方一计不成又生一计, 采用了迷宫式防御 — 单页应用 — 的方式重铸了堡垒,爬虫方费尽了心机却由于单页应用巧妙的构筑方式而解析不到任何数据,一时间被绕得晕头转向,束手无策,单页应用统治了战场!反爬方开始了单方面的屠杀,爬虫方的士气一蹶不振…...**千军坐镇,百将舍身,十年磨剑,一鸣惊人!**终于,这场战役的终结者出现了,他就是,Headless Chrome技术!新技术一出现,爬虫方的武器库焕然一新:Selenium,Puppeteer, PhantomJS, CasperJS等重装攻城杀器不断建功,反爬方一溃千里。爬虫方终于锁定了第一场战役的胜局! ...

August 21, 2019 · 1 min · jiezi

第二篇-仿写Vue生态系列模板小故事

( 第二篇 )仿写'Vue生态'系列___'模板小故事.' 本次任务 承上: 完成第一篇未完成的'热更新'配置.核心: 完成'模板解析'模块的相关编写, 很多文章对模板的解析阐述的都太浅了, 本次我们一起来深入讨论一下, 尽可能多的识别用户的语句.启下: 在结构上为'双向绑定'、watch、dep等模块的编写打基础. 最终效果图 一. 模板页面我们既然要开发一个mvvm, 那当然要模拟真实的使用场景, 相关的文件我们放在:'cc_vue/use'路径下, 代码如下: 'cc_vue/use/1:模板解析/index.html', 本篇专门用来展示模板解析的页面'cc_vue/use/1:模板解析/index.js', 本篇专门用来展示模板解析的逻辑代码本来要展示html文件的信息, 但是内容冗长而且没有什么技术可言, 所以不在此展示了. function init(){ new C({ el: '#app', data: { title: '努力学习', ary: [1, 2, 3], obj: { name: '金毛', type: ['幼年期', '成熟期', '完全体'] }, fn() { return '大家好我是: ' + this.obj.name; } } });}export default init;一. 配置文件与简易的热更新之所以说它是简易的, 原因是我们并不会去做到很细致, 比如本次不会去追求每一次的精准更新, 而是每一次都会对整体采取更新, 毕竟本次工程热更新只是一个知识点, 我们还有很多很多更重要的事要做emmmm 一些自己的观点热更新并不是算很神奇, 我之前配置过vuex的热更新相关, 后来总结了一下, 它与回调函数概念差不多, 原理就是当编辑器, 或者是serve检测到你的文件有相应变化的时候, 执行一个回调函数, 这个回调函数里面就是一些重新渲染, 更新dom等等的操作, 你可能会有疑问, vue的热更新做的那么好, 也没看见有什么热更新的回调函数啊, 其实这都归功于'vue-loader', css 热更新考的是css-loader, 他们在处理文件的阶段就把热更新的回调代码注入了js文件里面, 所以我们才会是无感的, 所以没有'loader'帮助我们注入热更新, 那本次我们就自己手动实现.???? ...

August 21, 2019 · 5 min · jiezi

js监听用户进入和离开当前页面

VisibilityChange 事件;用于用户是否离开当前页面 // 页面的 visibilityState属性可能返回三种状态 prerender,visible 和 hidden // 监听 visibility change 事件 document.addEventListener('visibilitychange', function() { // 页面变为不可见时触发 if (document.visibilityState == 'hidden') { document.title = '离开'; } // 页面变为可见时触发 if (document.visibilityState == 'visible') { document.title = '回来'; } });// 页面的 hidden属性,false,true;document.addEventListener('visibilitychange',function(){ var isHidden = document.hidden; if(isHidden){ document.title = '离开'; } else { document.title = '回来'; }});

August 21, 2019 · 1 min · jiezi

Web-Components-系列教程

Web Components 开始不添加任何依赖来构建自己的定制组件带有样式,拥有交互功能并且在各自文件中优雅组织的 HTML 标签 https://developer.mozilla.org... Web Components是一套不同的技术,允许您创建可重用的定制元素(它们的功能封装在您的代码之外)并且在您的web应用中使用它们。 示例 https://github.com/mdn/web-co... polyfill https://www.webcomponents.org... https://github.com/webcompone... https://unpkg.com/browse/@web... npm install @webcomponents/webcomponentsjs <!-- load webcomponents bundle, which includes all the necessary polyfills --><script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script><!-- load the element --><script type="module" src="my-element.js"></script><!-- use the element --><my-element></my-element>Web Component 是一系列 web 平台的 API,它们可以允许你创建全新可定制、可重用并且封装的 HTML 标签定制的组件基于 Web Component 标准构建,可以在现在浏览器上使用,也可以和任意与 HTML 交互的 JavaScript 库和框架配合使用。 它赋予了仅仅使用纯粹的JS/HTML/CSS就可以创建可重用组件的能力。如果 HTML 不能满足需求,我们可以创建一个可以满足需求的 Web Component。 举个例子,你的用户数据和一个 ID 有关,你希望有一个可以填入用户 ID 并且可以获取相应数据的组件。HTML 可能是下面这个样子: <user-card user-id="1"></user-card>Web Component 的四个核心概念HTML 和 DOM 标准定义了四种新的标准来帮助定义 Web Component。这些标准如下:定制元素(Custom Elements):web 开发者可以通过定制元素创建新的 HTML 标签、增强已有的 HTML 标签或是二次开发其它开发者已经完成的组件。这个 API 是 Web Component 的基石。HTML 模板(HTML Templates):HTML 模板定义了新的元素,描述一个基于 DOM 标准用于客户端模板的途径。模板允许你声明标记片段,它们可以被解析为 HTML。这些片段在页面开始加载时不会被用到,之后运行时会被实例化。Shadow DOM:Shadow DOM 被设计为构建基于组件的应用的一个工具。它可以解决 web 开发的一些常见问题,比如允许你把组件的 DOM 和作用域隔离开,并且简化 CSS 等等。HTML 引用(HTML Imports):HTML 模板(HTML Templates)允许你创建新的模板,同样的,HTML 引用(HTML imports)允许你从不同的文件中引入这些模板。通过独立的HTML文件管理组件,可以帮助你更好的组织代码。组件的命名定制元素的名称必须包含一个短横线。所以 <my-tabs> 和 <my-amazing-website> 是合法的名称, 而 <foo> 和 <foo_bar> 不行。在 HTML 添加新标签时需要确保向前兼容,不能重复注册同一个标签。 ...

August 21, 2019 · 11 min · jiezi

前端面试每日-31-第127天

今天的知识点 (2019.08.21) —— 第127天[html] html的button中的reset有什么作用?[css] 说说你对min-width和max-width的理解,它们有什么运用场景?[js] JavaScript有几种类型值?能否画出它们的内存图?[软技能] 说说你对移动端和web前端开发的主要区别是什么?项目地址: 前端面试每日3+1 【推荐】欢迎跟 jsliang 一起折腾前端,系统整理前端知识,目前正在折腾 LeetCode,打算打通算法与数据结构的任督二脉。GitHub 地址 微信公众号欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎点个Star, 同时欢迎微信扫码关注 前端剑解 公众号,并加入 “前端学习每日3+1” 微信群相互交流(点击公众号的菜单:进群交流)。 《论语》,曾子曰:“吾日三省吾身”(我每天多次反省自己)。 前端面试每日3+1题,以面试题来驱动学习,每天进步一点! 让努力成为一种习惯,让奋斗成为一种享受!相信 坚持 的力量!!!学习不打烊,充电加油只为遇到更好的自己,365天无节假日,每天早上5点纯手工发布面试题(死磕自己,愉悦大家)。希望大家在这浮夸的前端圈里,保持冷静,坚持每天花20分钟来学习与思考。在这千变万化,类库层出不穷的前端,建议大家不要等到找工作时,才狂刷题,提倡每日学习!(不忘初心,html、css、javascript才是基石!)欢迎大家到Issues交流,鼓励PR,感谢Star,大家有啥好的建议可以加我微信一起交流讨论!希望大家每日去学习与思考,这才达到来这里的目的!!!(不要为了谁而来,要为自己而来!)交流讨论欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎分享! 项目地址: 前端面试每日3+1

August 21, 2019 · 1 min · jiezi

前端面试每日-31-第126天

今天的知识点 (2019.08.20) —— 第126天[html] 请说说Canvas和SVG图形的区别是什么?[css] 说说你对hasLayout的理解,触发hasLayout的方式有哪些?[js] 保护js代码的方式有哪些?分别说说他们的原理是什么?[软技能] 你有了解opengl吗?它有哪些作用?项目地址: 前端面试每日3+1 【推荐】欢迎跟 jsliang 一起折腾前端,系统整理前端知识,目前正在折腾 LeetCode,打算打通算法与数据结构的任督二脉。GitHub 地址 微信公众号欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎点个Star, 同时欢迎微信扫码关注 前端剑解 公众号,并加入 “前端学习每日3+1” 微信群相互交流(点击公众号的菜单:进群交流)。 《论语》,曾子曰:“吾日三省吾身”(我每天多次反省自己)。 前端面试每日3+1题,以面试题来驱动学习,每天进步一点! 让努力成为一种习惯,让奋斗成为一种享受!相信 坚持 的力量!!!学习不打烊,充电加油只为遇到更好的自己,365天无节假日,每天早上5点纯手工发布面试题(死磕自己,愉悦大家)。希望大家在这浮夸的前端圈里,保持冷静,坚持每天花20分钟来学习与思考。在这千变万化,类库层出不穷的前端,建议大家不要等到找工作时,才狂刷题,提倡每日学习!(不忘初心,html、css、javascript才是基石!)欢迎大家到Issues交流,鼓励PR,感谢Star,大家有啥好的建议可以加我微信一起交流讨论!希望大家每日去学习与思考,这才达到来这里的目的!!!(不要为了谁而来,要为自己而来!)交流讨论欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎分享! 项目地址: 前端面试每日3+1

August 20, 2019 · 1 min · jiezi

微信小程序-webview-与-h5-通过-postMessage-实现实时通讯的实现

原文:https://pantao.parcmg.com/pre... 在做 React Native 应用时,如果需要在 App 里面内嵌 H5 页面,那么 H5 与 App 之间可以通过 Webview 的 PostMessage 功能实现实时的通讯,但是在小程序里面,虽然也提供了一个 webview 组件,但是,在进行 postMessage 通讯时,官方文档里面给出了一条很变态的说明: 网页向小程序 postMessage 时,会在特定时机(小程序后退、组件销毁、分享)触发并收到消息。e.detail = { data },data 是多次 postMessage 的参数组成的数组这里面已经说的很明白了,不管我们从 H5 页面里面 postMessage 多少次,小程序都是收不到的,除非: 用户做了回退到上一页的操作组件销毁用户点击了分享这里面其实我没有完全说对,官方其实说的是 小程序后退,并没有说是用户做回退操作,经过我的实测,确实人家表达得很清楚了,我们通过微信官方的SDK调起的回退也是完全可行的: wx.miniProgram.navigateBack()大体思路从上面的分析和实测中我们可以知道,要实现无需要用户操作即可完成的通讯,第三种情况我们是完全不需要考虑了的,那么来仔细考虑第 1 和第 2 种场景。 第 1 种方式:回退当我们想通过网页向小程序发送数据,同时还可以回退到上一个页面时,我们可以在 wx.miniProgram.postMessage 之后,立马调用一次 wx.miniProgram.navigateBack(),此时小程序的操作是: 处理 postMessage 信息回退到上一页我们在处理 postMessage 的时候做一些特殊操作,可以将这些数据保存下来 第 2 种方式:组件销毁这是我感觉最合适的一种方式,可以让小程序拿到数据,同时还保留在当前页面,只需要销毁一次 webview 即可,大概的流程就是: 小程序 postMessage小程序 navigateTo 将小程序页面导向一个特殊的页面小程序的那个特殊页面立马回退到 webview 所在的页面webview 所在的页面的 onShow 里面,做一次处理,将 webview 销毁,然后再次打开触发 onMessage 拿到数据H5 页面再次被打开这种方式虽然变态,但是至少可以做到实时拿到数据,同时还保留在当前 H5 页面,唯一需要解决的是,在做这整套操作前,H5 页面需要做好状态的缓存,要不然,再次打开之后,H5 的数据就清空了。 ...

August 20, 2019 · 4 min · jiezi

基于原生JS验证表单组件xyform

原生form表单form表单元素大家可能都用到过,除了可以提交表单外,还有一些内置的表单校验,比如require、minlength、maxlength,还有各种类型的input,比如type=email可以校验是否是邮箱类型,如果不满足还可以使用pattern进行正则校验。 原生的表单验证大概如下 虽然丑陋,功能却很强大,基本可以满足一般的需求,不过ui终究过于原生,而且也不方便自定义,所以很多情况下这种默认的表单验证并不使用。 下面来看看xy-form下的效果 结构基本和原生类似,也不需要额外的js逻辑 可以说丑小鸭立马变成白天鹅了。 xy-formxy-form是xy-ui新增了一类组件,主要用于表单提交和表单验证,完全可以取代原生form表单,下面简单介绍一下主要属性和方法,建议阅读在线文档,可以实时交互。 使用方式使用方式很简单 npmnpm i xy-uicdn<script type="module" src="https://unpkg.com/xy-ui/components/xy-form.js"></script><!--或者--><script type="module"> import 'https://unpkg.com/xy-ui/components/xy-form.js'</script>或者直接从github拷贝源码。<script type="module" src='./node_modules/xy-ui/components/xy-form.js'></script><!--或者--><script type="module"> import './node_modules/xy-ui/components/xy-form.js';</script>使用 <xy-form> ...</xy-form>表单默认行为属性xy-form内置了以下属性,基于html5规范。 这里的默认行为指的是,点击submit按钮或者回车,表单首先对表单元素进行格式校验,如果有误则会将有误的地方标识出来,全部正确后才能进行提交。 表单地址action值为URL,规定向何处发送表单数据。 回车键会触发表单。 请求方式method规定请求方式,默认为get,可选post。 验证novalidate如果使用该属性,则提交表单时不进行验证。 方法提交submit当表单内包含htmltype="submit"的按钮时,点击该按钮可以触发表单提交。 可通过form.submit()主动触发。 清空reset当表单内包含htmltype="reset"的按钮时,点击该按钮可以清空表单。 可通过form.reset()主动触发。 下面是一个最账号密码的登录框 <xy-form action="/login" method="post"> <xy-form-item legend="user"> <xy-input name="user" required placeholder="user"></xy-input> </xy-form-item> <xy-form-item legend="password"> <xy-input name="password" required type="password" placeholder="password" minlength="6"></xy-input> </xy-form-item> <xy-form-item> <xy-button type="primary" htmltype="submit">login</xy-button> <xy-button htmltype="reset">reset</xy-button> </xy-form-item></xy-form>渲染如下 首先输入框均设置了required属性,表示必填项,如果不输入在submit时会提示以下信息 其次,密码框规定了minlength属性,表示最小字符长度,如果不满足格式,会提示以下信息 当全部满足要求才能进行提交,可在控制台查看提交的表单数据,格式为formData,可转换json。 自定义表单自定义表单提交当表单带有action属性时,回车键可以触发表单提交,如果包含htmltype="submit"的按钮时,点击该按钮可以触发表单提交。 如果想手动通过ajax提交,可以去除action属性,这样就不会触发默认表单提交效果了。 可通过form.formdata获取表单的值。 sumbitBtn.onclick = function(){ fetch('/login', { method: 'POST', body: form.formdata, }) .then(function(data){ // })}自定义表单验证默认情况下,如果验证失败,表单则不会提交。 ...

August 19, 2019 · 1 min · jiezi

手把手教你使用Hexo和github搭建免费个人博客网站

俗话说的好“吃水不忘挖井人”,当自己体验过Hexo搭建个人网站后,也来分享一下搭建过程遇到的乐趣以及遇到的坑! 准备工作(电脑配置工具)在搭建Hexo博客之前,首先需要简单在你电脑安装一些工具以及依赖包(具体安装方法相信大家都会,就省略了) 首先要有一个github账号其次安装node.js,npm依赖然后安装git工具(当然电脑自身的cmd工具也是可以用的)创建github网站(username.github.io的github仓库)新建一个名为“你的用户名.github.io”的仓库,比如说,如果你的github用户名是mengnn,那么你就新建"mengnn.github.io"的仓库(必须是你的用户名,其它名称无效),将来你的网站访问地址就是 mengnn.github.io了,对的,就是这么方便。 <!--more--> 当然,一个github账户下只能创建一个以此命名的仓库,用来直接访问。 点击New repository输入Repository name,必需为username.github.io格式。username替换为用户名点击按钮Create repository进入仓库username.github.io,点击setting,找到GitHub Pages模块点击choose a theme选择一个页面主题访问https://username.github.io就可以访问博客网站了为github设置SSH Keys之所以配置SSH Keys,是因为你提交代码肯定要拥有你的github权限才可以,但是直接使用用户名和密码太不安全了,所以我们使用ssh key来解决本地和服务器的连接问题。 首先检查机器上是否已经存在id_rsa.pub文件 cd ~/. ssh #检查本机已存在的ssh密钥如果不存在那就通过命令生成秘钥 ssh-keygen -t rsa -C "邮箱地址"一路回车就好(记得应该是连续3次回车),最终会生成一个文件在用户目录下,打开用户目录,找到.ssh\id_rsa.pub文件,记事本打开并复制里面的内容。 打开你的github页面,点击setting进入---> SSH and GPG keys ---> New SSH key,然后把你复制的内容放到Key中,其中Title中的内容可以随便填一个就ok了,如下图: 添加成功保存就OK了。 测试SSH Key输入下面命令,测试SSH Key是否安装成功 ssh -T git@github.com # 不用改邮箱地址如果提示Are you sure you want to continue connecting (yes/no)?,输入yes,然后会类似于:`Hi mengnn! You've successfully authenticated, but GitHub does not provide shell access.`的字符,说明你安装成功了。 安装Hexo以上准备工作完成后,就要放大招了,对,接下来就是重头戏-本地部署Hexo。 ...

August 19, 2019 · 1 min · jiezi

前端面试每日-31-第125天

今天的知识点 (2019.08.19) —— 第125天[html] 举例说明table怎么合并行和列的?[css] 使用纯CSS代码实现动画的暂停与播放[js] 你有用过webRTC吗?它有什么运用场景?[软技能] 说说你对Web App 、Hybrid App和Native App这三者的理解?项目地址: 前端面试每日3+1 【推荐】欢迎跟 jsliang 一起折腾前端,系统整理前端知识,目前正在折腾 LeetCode,打算打通算法与数据结构的任督二脉。GitHub 地址 微信公众号欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎点个Star, 同时欢迎微信扫码关注 前端剑解 公众号,并加入 “前端学习每日3+1” 微信群相互交流(点击公众号的菜单:进群交流)。 《论语》,曾子曰:“吾日三省吾身”(我每天多次反省自己)。 前端面试每日3+1题,以面试题来驱动学习,每天进步一点! 让努力成为一种习惯,让奋斗成为一种享受!相信 坚持 的力量!!!学习不打烊,充电加油只为遇到更好的自己,365天无节假日,每天早上5点纯手工发布面试题(死磕自己,愉悦大家)。希望大家在这浮夸的前端圈里,保持冷静,坚持每天花20分钟来学习与思考。在这千变万化,类库层出不穷的前端,建议大家不要等到找工作时,才狂刷题,提倡每日学习!(不忘初心,html、css、javascript才是基石!)欢迎大家到Issues交流,鼓励PR,感谢Star,大家有啥好的建议可以加我微信一起交流讨论!希望大家每日去学习与思考,这才达到来这里的目的!!!(不要为了谁而来,要为自己而来!)交流讨论欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎分享! 项目地址: 前端面试每日3+1

August 19, 2019 · 1 min · jiezi

rem自适应原理

需要了解的知识html{font-size:16px}p{font-size:1rem}1rem = 16px;rem 和 em 类似,em相较于父元素的字体大小,而rem相较于html的字体大小; 实现原理有了这个以上的前提可以通过监测屏幕大小改变html的字体大小,从而实现自适应大小的效果; 获取设备宽度与设计稿宽度的比例 作为html font-size的大小;假如是750/750 那么font-size:1px;设计稿上200px,代码就要写200rem;这样写太大.通常750/750*100,多除100;100作为px转化为rem的换算比例,100px = 1rem;那么设计稿750px代码里就要写7.5rem;function getRem () { var html = document.getElementsByTagName("html")[0]; var deviceWidth = document.body.clientWidth || document.documentElement.clientWidth; var rem = deviceWidth / designWidth * 100; console.log(rem) html.style.fontSize = rem+ "px";}设计稿为750px时,html{font-size:50px;} 50px * 7.5 = 375px;正好是设备的宽度;当设计稿750px,设备320px时, 320/750100 = 42.6666667;42.66667 7.5 = 320px;所以当设备为375时 7.5rem是maxWidth,设备是320时,7.5rem也是maxWidth,这样就达到了自适应设备的目的;简陋版完整代码: (function (designWidth,n) { function getRem () { var html = document.getElementsByTagName("html")[0]; var deviceWidth = document.body.clientWidth || document.documentElement.clientWidth; var rem = deviceWidth / designWidth * n; console.log(rem) html.style.fontSize = rem+ "px"; } getRem () window.addEventListener('resize',function (){ getRem() })})(750,100)

August 18, 2019 · 1 min · jiezi

原生支持的懒加载已经到来

资料来源:https://medium.com/bbc-design...title: Native lazy loading has arrived! author: Andy Potts (BBC 软件工程师) date: 2019-08-12 对于从未看到过原生懒加载这个术语的人: 谷歌上周发布了 Google introduced native lazy loading to Chrome version 76现在你可能会想知道:“什么是原生懒加载,它是否值得添加到我的网站上?” 好的,这正是我希望为你解答的问题,因为我会谈谈我使用它的经验。 什么是懒加载?懒加载是指通过在用户需要时加载资源(例如图像资源)来提高性能。举个例子,当用户访问你的网站的时候,它会在进入视图的时候(就是在用户可以看见的时候)加载当前视图所需要的图像,而不是在页面最初加载所有图像。这是很有好处的,因为用户不需要总是看在页面底部的图像,所以为什么要让我们的用户加载所有不必要的图像呢? 以前,如果我们想要实现懒加载,我们必须导入一个库或编写一些 JavaScript 来检查元素相对于用户视图的位置,必要时(就是用户移动到对应位置的时候)再加载对应的资源。听起来实现起来有一点复杂,不是吗? 原生懒加载是 Google 浏览器新的内置解决方案,这意味着不需要编写额外的 JavaScript 来实现懒加载(并且极大地提高了网站的性能)。原生懒加载使用起来十分简单,只需要通过添加loading属性到 <image>或 iframe 标签上就可以实现。 听起来很不错,不是吗?但它实际上值得实施吗?我决定在BBC的一个内部产品上实现原生懒加载技术,这个网站每天有大约 3,000 名活跃用户。这个网站上涉及一个最常见的操作——查询,该查询将呈现一个最多100个图像的列表 -——我认为这似乎是尝试原生懒加载的理想场所。 所以,它值得添加到我们的网站上吗?是的!将loading属性添加到图像上会使图像在一个快速的网络连接环境上的加载时间减少约 50% —— 从约 1 秒到 <0.5 秒,以及最多可以向服务器保存 40 个请求????。所有的·这些性能增强只是将一个属性添加到一堆图像中! 实例所以,现在我们已经看到了它能够做什么, 让我们来看看它是如何工作的。我将介绍如何为图像实现原生的懒加载。 这真的非常容易 —— 把loading属性,值为lazy加在image标签上,这就能告诉浏览器去懒加载这张图片,并且指定图片的宽高能够避免页面的重排。 <img src="/images/example.png" loading="lazy" width="400" height="400" />(因为 SF 不能显示 iframe 所以这里放链接) https://codepen.io/andypotts/... 总而言之,使用原生懒加载是为您的用户提供真正的渐进式性能增强的最简单方法之一。这不是一个完美的解决方案,但如果你还没有使用延迟加载并拥有大量图像/ iframe,那么它绝对值得尝试 - 特别是因为它很容易实现! ...

August 18, 2019 · 1 min · jiezi

第十三集-从零开始实现一套pc端vue的ui组件库-评分组件-小星星

第十三集: 从零开始实现一套pc端vue的ui组件库( 评分组件 小星星 )1. 本集定位     说起评分的话, 最早看到这种形式是电影网站, 每部电影得到几颗星这种方式, 后来就出现了用户来手动选星星打分的玩法, 这些方式更直观, 更吸引用户参与进去, 这个组件其实还有很多玩法, 比加载动画, 我可以把星星不断的点亮作为一个加载进度的映射, 这个组件很多ui库都把他做的很固定, 比如说自能是5颗星星或者笑脸, 而本次编写这个组件我的原则就是, 星星的数量可以任意的多, 当然也可以任意的少, 最少1颗, 最多无限颗, 是不是很有趣????.     实现思路因为我这边icon组件用的是svg实现的, 最后选择了使用两排一样的icon组件, 重叠在一起, 然后把最上层的宽度变化一下, 就达到了选择区域有颜色的效果了. 2. 需求评审只读模式: 可只做展示.选择模式: 可通过点击设置新的评分.颜色与大小, 要可供用户自己设定.特色: 可设置'星星'的总数量.可设置满分为多少分可更换图形, 绝对不止是'星星'.要兼容多层父级组件的情况以及多层父级并且父级组件滚动偏移的情况可以每次以半颗星为单位进行选取.3. 基础的搭建先上一张正常状态下的效果图vue-cc-ui/src/components/Rate/index.js import Rate from './main/rate.vue'Rate.install = function(Vue) { Vue.component(Rate.name, Rate);};export default Ratevue-cc-ui/src/components/Rate/main/rate.vue <template> <div class='cc-rate' :style="{ cursor: disabled ? 'auto' : 'pointer', // 不让修改的状态也就没必要出现小手了 }"> <i class='cc-rate__box'> <span class='cc-rate__dark'> <cc-icon v-for='item in num' :key='item' :size="`${size}px`" :name='iconType.name' /> </span> <span class='cc-rate__bright' :style="{ width }"> <cc-icon v-for='item in num' :key='item' :size="`${size}px`" :name='iconType.name' /> </span> </i> </div></template>上述的num指的就是 用户定义的星星的数量total就是当星星满分的时候, 相当于多少分 ...

August 18, 2019 · 4 min · jiezi

前端面试每日31周汇总20190818

《论语》,曾子曰:“吾日三省吾身”(我每天多次反省自己)。 前端面试每日3+1题,以面试题来驱动学习,每天进步一点! 让努力成为一种习惯,让奋斗成为一种享受!相信 坚持 的力量!!!项目地址: https://github.com/haizlin/fe... 【推荐】欢迎跟 jsliang 一起折腾前端,系统整理前端知识,目前正在折腾 LeetCode,打算打通算法与数据结构的任督二脉。GitHub 地址 微信公众号欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎点个Star, 同时欢迎微信扫码关注 前端剑解 公众号,并加入 “前端学习每日3+1” 微信群相互交流(点击公众号的菜单:进群交流)。 学习不打烊,充电加油只为遇到更好的自己,365天无节假日,每天早上5点纯手工发布面试题(死磕自己,愉悦大家)。希望大家在这浮夸的前端圈里,保持冷静,坚持每天花20分钟来学习与思考。在这千变万化,类库层出不穷的前端,建议大家不要等到找工作时,才狂刷题,提倡每日学习!(不忘初心,html、css、javascript才是基石!)欢迎大家到Issues交流,鼓励PR,感谢Star,大家有啥好的建议可以加我微信一起交流讨论!希望大家每日去学习与思考,这才达到来这里的目的!!!(不要为了谁而来,要为自己而来!)htmlHTML5规范将元素分为哪几个大类?分别说说它们的特点使用canvas画出一个矩形说说form-data、x-www-form-urlencoded、raw、binary的区别是什么?请描述下application cache的更新过程?你知道富文本编辑器的实现原理吗?说说你对富文本的理解,你有用过哪些富文本编辑器呢?有使用过HTML5的跟踪元素吗?说说你对它的理解css举例说明伪类:nth-child、:first-child与:first-of-type这三者有什么不同?什么是zoom?它有什么作用?举例说明微信端兼容问题有哪些?请举例说明伪元素 (pseudo-elements) 有哪些用途?设置字体时为什么建议设置替换字体?你有没有自己写过一套UI库?说下遇到哪些难点?说说你对GPU的理解,举例说明哪些元素能触发GPU硬件加速?js如何实现文件拖动上传?分析('b' + 'a' + +'a' + 'a').toLowerCase()返回的结果能否正确获取本地上传的文件路径?如果可以怎么做?如果不可以解释下为什么?请说说escape、encodeURI、decodeURI、encodeURIComponent和decodeURIComponent的区别?如何终止WebWork?写一个方法把多维数组降维使用正则去掉html中标签与标签之间的空格软技能你有开发过弹幕吗?知道它的原理吗?说说看你了解雅虎前端优化的35条军规吗?你能说上几条?如果一个项目要你重构成前后端分离,你的方法论是什么?用哪种格式可以存储包含Alpha通道的图像?Alpha通道是指什么?你有签过保密协议吗?说说你对保密协议的理解你对jsfuck有了解吗?它的原理是什么?请举例说明你有做过骨架屏吗?它的原理是什么知道吗?全部所有 交流讨论项目地址: https://github.com/haizlin/fe...

August 18, 2019 · 1 min · jiezi

前端面试每日-31-第124天

今天的知识点 (2019.08.18) —— 第124天[html] HTML5规范将元素分为哪几个大类?分别说说它们的特点[css] 举例说明伪类:nth-child、:first-child与:first-of-type这三者有什么不同?[js] 如何实现文件拖动上传?[软技能] 你有开发过弹幕吗?知道它的原理吗?说说看项目地址: 前端面试每日3+1 【推荐】欢迎跟 jsliang 一起折腾前端,系统整理前端知识,目前正在折腾 LeetCode,打算打通算法与数据结构的任督二脉。GitHub 地址 微信公众号欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎点个Star, 同时欢迎微信扫码关注 前端剑解 公众号,并加入 “前端学习每日3+1” 微信群相互交流(点击公众号的菜单:进群交流)。 《论语》,曾子曰:“吾日三省吾身”(我每天多次反省自己)。 前端面试每日3+1题,以面试题来驱动学习,每天进步一点! 让努力成为一种习惯,让奋斗成为一种享受!相信 坚持 的力量!!!学习不打烊,充电加油只为遇到更好的自己,365天无节假日,每天早上5点纯手工发布面试题(死磕自己,愉悦大家)。希望大家在这浮夸的前端圈里,保持冷静,坚持每天花20分钟来学习与思考。在这千变万化,类库层出不穷的前端,建议大家不要等到找工作时,才狂刷题,提倡每日学习!(不忘初心,html、css、javascript才是基石!)欢迎大家到Issues交流,鼓励PR,感谢Star,大家有啥好的建议可以加我微信一起交流讨论!希望大家每日去学习与思考,这才达到来这里的目的!!!(不要为了谁而来,要为自己而来!)交流讨论欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎分享! 项目地址: 前端面试每日3+1

August 18, 2019 · 1 min · jiezi

2019年夏天我走上了前端之路

HTML5语义化标签文本相关标签表格相关标签表单相关标签多媒体API的丰富与增强CSS3属性选择器文本相关属性背景边框,边距属性大小、定位、轮廓属性盒模型与布局相关属性表格相关属性CSS动画效果scss、less预编译器JavaScriptJavaScript基础语法JavaScript DOM操作JavaScript事件类型、机制等本地存储与离线应用localStorage、sessionStorageindexedDB存储与调用Web Worker多线程APIworker线程数据交换嵌套workerSharedWorkerPromise的原理及使用客户端通信跨文档消息传递WebSocket通信心情初探前端开发,内容非常丰富,发展也是非常迅速,所以必定学无止境。面对如大海般的知识,我相信很多人跟我一样也会有些迷茫,不知所措。边学习边想了很久,技术是社会发展的推动力,可以说技术是永远学不完的,所以切不可贪多,求全。对于浩如烟海的知识与技术,我们该如何应对呢?想必有很多前辈都会有这样的经验,学技术需要一专多长,需要从一个切入口达到一定的深度,再去考虑扩展广度。那么像我这个夏天所学,远远不够,可以说才刚刚了解前端,要想达到去企业工作的水平还需要更多的实践和练习。那么怎么能做到不成为社会发展的淘汰者呢?这就需要掌握核心的本领,高屋建瓴,从平地而起,在计算机科学领域,算法,计算机网络,操作系统可以说是非常核心的内容了,所有的程序设计都因此而有意义。对于程序来说,代码的架构,复用度,可维护性,高性能则是成为专家的必经之路。前端开发,其核心在于用户交互,我们要关心,页面的交互性,布局,用户体验和网页性能优化。对于代码来说就是简洁、高效、可维护性高。对于前端开发来说,我机缘巧合走上这条路,我便始终如一,尽管可能与我专业不尽相同,这便是人生,所有事都是缘分。

August 17, 2019 · 1 min · jiezi

30分钟完成JavaScript中的记忆游戏

通过在30分钟内构建一个记忆游戏来学习JS,CSS和HTML! 本教程介绍了一些基本的关于HTML5,CSS3和JavaScript概念。 我们将讨论数据属性,定位,透视,转换,flexbox,事件处理,超时和三元表达式。 读懂此文章不需要大家有许多编程方面的知识。 如果您已经知道HTML,CSS和JS的用途,那就绰绰有余了! 项目结构让我们在终端中创建项目文件: ???? mkdir memory-game ???? cd memory-game ???? touch index.html styles.css scripts.js ???? mkdir imgHTML连接css和js文件的初始页面模板。 <!-- index.html --><!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Memory Game</title> <link rel="stylesheet" href="./styles.css"></head><body> <script src="./scripts.js"></script></body></html>这个游戏有12张卡片。每个卡片由一个名为.memory-card的容器div组成,其中包含两个img元素。第一个代表卡片的front-face(意为正面),第二个代表卡片的back-face(意为背面)。 <div class="memory-card"> <img class="front-face" src="img/react.svg" alt="React"> <img class="back-face" src="img/js-badge.svg" alt="Memory Card"></div>我们可以在Memory Game Repo下载该项目的资源文件。这组卡片将被包装在section容器元素中。最终代码结果是这样的: <!-- index.html --><section class="memory-game"> <div class="memory-card"> <img class="front-face" src="img/react.svg" alt="React"> <img class="back-face" src="img/js-badge.svg" alt="Memory Card"> </div> <div class="memory-card"> <img class="front-face" src="img/react.svg" alt="React"> <img class="back-face" src="img/js-badge.svg" alt="Memory Card"> </div> <div class="memory-card"> <img class="front-face" src="img/angular.svg" alt="Angular"> <img class="back-face" src="img/js-badge.svg" alt="Memory Card"> </div> <div class="memory-card"> <img class="front-face" src="img/angular.svg" alt="Angular"> <img class="back-face" src="img/js-badge.svg" alt="Memory Card"> </div> <div class="memory-card"> <img class="front-face" src="img/ember.svg" alt="Ember"> <img class="back-face" src="img/js-badge.svg" alt="Memory Card"> </div> <div class="memory-card"> <img class="front-face" src="img/ember.svg" alt="Ember"> <img class="back-face" src="img/js-badge.svg" alt="Memory Card"> </div> <div class="memory-card"> <img class="front-face" src="img/vue.svg" alt="Vue"> <img class="back-face" src="img/js-badge.svg" alt="Memory Card"> </div> <div class="memory-card"> <img class="front-face" src="img/vue.svg" alt="Vue"> <img class="back-face" src="img/js-badge.svg" alt="Memory Card"> </div> <div class="memory-card"> <img class="front-face" src="img/backbone.svg" alt="Backbone"> <img class="back-face" src="img/js-badge.svg" alt="Memory Card"> </div> <div class="memory-card"> <img class="front-face" src="img/backbone.svg" alt="Backbone"> <img class="back-face" src="img/js-badge.svg" alt="Memory Card"> </div> <div class="memory-card"> <img class="front-face" src="img/aurelia.svg" alt="Aurelia"> <img class="back-face" src="img/js-badge.svg" alt="Memory Card"> </div> <div class="memory-card"> <img class="front-face" src="img/aurelia.svg" alt="Aurelia"> <img class="back-face" src="img/js-badge.svg" alt="Memory Card"> </div></section>CSS我们将使用一个简单但非常有用的重置,适用于所有项目: ...

August 17, 2019 · 6 min · jiezi

网络直播平台与版权保护之间的较量

冯提莫,网友称之为“斗鱼一姐”,在现场互动中播放了一首歌《恋人心》。随后,中国音乐版权协会将斗鱼公司发布到武汉斗鱼互联网法院,以传播有关该歌曲享有的音乐信息,将斗鱼网络技术有限公司起诉到北京互联网法院。要求赔偿涉案歌曲版权使用费用共计4万多元。 北京互联网法院判决斗鱼公司赔偿中国音乐版权协会的经济损失为2000元,合理的诉讼费用成本为3200元。据了解,案件的一审判决最近有效。 客观地说,网络主播可以在直播期间播放背景音乐或者唱别人的歌曲,在直播行业中很常见,是许多网络主播的常用表现方法,网络主播直播中有很多观众我已经习惯了。 然而,从合法的角度来看,网络主播在直播期间播放广播或歌曲,由粉丝奖励并获得经济奖励。这是一场公开演出,基本上是一场商业演出。墨者安全表示网络主播在直播期间未经权利所有者的许可播放或唱出其他人的音乐歌曲,并将其录制在视频中供粉丝欣赏。这显然侵犯了他人的版权,应对这种侵权行为负责。 目前,冯提莫已被证实在直播期间任意播放其他人的歌曲,斗鱼平台已被判2000元,这些裁决无疑是给快速发展的直播行业和短视频行业一个大大的警钟,大多数关于实时和短视频平台版权保护的主持人,短视频制作人和法律教育课程。警示广播直播平台,短视频平台和主播,短视频创作者尊重和保护他人的版权。 实际上,为了实现直播行业和短视频行业的长期发展,有必要保护他人的版权作为前提,大多数主播和直播平台必须提高版权保护意识。另一方面,主持人未经许可不能播放和唱别人的歌曲,他们必须制作更多的原创内容,同时使用分享网络广播的好处的直播平台。该平台的主要职责是加强对主播直播内容的审查和监督,并及时发布涉嫌侵权的内容。同时,为了减少主持人侵犯他人版权的可能性,直播平台和短视频平台可以参考KTV和电视台的才艺表演,并以包装的方式购买音乐和电影作品的版权。

August 17, 2019 · 1 min · jiezi

前端包管理Bower入门教程

Bower了解bower是twitter的一个开源项目,使用nodejs开发,用于web包管理。如果越来越多得开源项目都托管在github上,bower只需要将github上项目加上一个配置文件既可以使用bower方式使用安装包。作为包管理,bower能提供添加新web包,更新web包,删除web包,发布web包功能,管理包依赖。web包通常认为由html+css+javascript构成。 环境依赖bower是依赖于 Node.js的,所以安装之前需要Node环境,Node.js官网 安装最新版本,然后命令行中严重是否安装成功 node -v //版本号查询 我的是v10.16.0安装Bowerbower官网 优点:项目依赖安装,可以固定资源文件,支持资源版本升级,可以支持缓存安装等全局安装bower npm install -g bower //如果你觉得npm安装较慢,可以用淘宝镜像cnpm安装安装完成后,查询版本号 bower -v //如果出现对应的版本号说明安装成功Bower 使用创建文件夹(以我的为例,创建了一个空文件夹bowerDemo),然后命令行到该空文件下 cd bowerDemo初始化bower bower init会提示你输入一些基本信息,根据提示按回车或者空格即可,然后会生成一个bower.json文件,用来保存该项目的配置 插件安装接下来你就可以安装插件了,比如安装下载jquery,在根目录先输入下面命令安装 bower install jquery --save安装成功后你就会在跟文件夹里看到一个bower_components文件夹,这也是插件默认的文件夹 你也可以输入命令查询包的信息,输入命令后会出现包的所以版本,然后你就可以更新安装不同的版本 bower info jquery //包的信息bower update //包的更新bower uninstall jquery //包的卸载这就是一个简单的bower的安装以及插件包的下载 当然,这些仅仅是不够的,作为一个前端开发,有时候会写很多html,css,js页面,甚至每次创建新的项目,都要用同样的模板,所以这个时候,就用到bower的注册功能,把自己的包或者插件发布到bower平台,并下载使用。 bower平台发布插件并下载首先打标签(假设你已经把项目模板发布到github上面),在你的本地仓库根目录下运行下面命令 // -a是添加 标签名,一般写版本号, -m为标签添加注释信息git tag -a 1.0.0 -m “version info″// –tags参数表示提交所有tag至服务器端,普通的git push origin master操作不会推送标签到服务器端git push origin --tags一切准备就绪后,开始注册插件 bower register projectName 项目的github地址 eg:bower register fontend https://github.com/mengnn/fontendGet.git这样,你的插件就注册成功了,你就可以在你的项目根目录下下载你的插件(模板),也就不用每次重复的copy bower install fontend --save-dev //fontend是我注册的插件名称运行成功,你就可以看到你的模板下载到你的项目文件夹下面,just so so! ...

August 17, 2019 · 1 min · jiezi

最近学到的前后端分离知识

前言只有光头才能变强。文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 前后端分离这个词相信大家都听过,不知道大家是怎么理解的呢。前阵子看项目的时候,有一段实现硬是没看懂,下面来给大家说一下一段愚蠢的经历哈。 (我没正正式式写过前端,所以如果文章有错的地方希望可以在评论区友善交流~) 一、交代背景我一直都知道我现在的这个系统是前后端分离的,我的接口只会返回JSON出去,但我不曾关心前端是怎么处理我的JSON数据的(以及他是怎么跑通和运行的) 在某一天,我在查接口的时候,习惯F12,想直接看一下这个请求返回的JSON数据是什么。但是一看,在network返回的是html格式: 于是,我就很好奇啊,就看一下这个接口是不是我想象中的那个。于是就去找我的接口,看一下是不是真的返回JSON(我还专门Debug了一下,看看是不是真请求到这个接口上了): 得出的结果是:我的接口的确是返回JSON数据,浏览器的reponse返回的的确是HTML格式。 于是,我就去找我前端的小伙伴,去问了一下这是怎么搞的。他回复我说:“在浏览器看到返回的是页面,那肯定是你们后端干的呀” 我说:“没有啊,我Java接口返回的是JSON数据啊,是不是中途你们用node做了些处理啊?”(我之前听过Node.js,但仅仅是听过) 他说:“Node.js也是你们后端的啊。” 我一听,啊?Node.js不是属于前端的吗? 二、初识Node.js在遇到这个事情之前,其实我在知乎已经看了一个帖子,话题名是这个《毕设答辩,老师说node不可能写后台怎么办?》 有兴趣的小伙伴可以去了解一下,大多数内容还是挺通俗易懂的: https://www.zhihu.com/question/327657434/answer/704249816我在下载Node.js的时候,发现其简介十分简洁: Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js® 是一个基于 Chrome V8 引擎 的 JavaScript 运行时。 然后点进去Chrome V8引擎,再看了一下介绍: V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++. It is used in Chrome and in Node.js, among others. V8是Google的开源高性能JavaScript和WebAssembly引擎,用C ++编写。它用于Chrome和Node.js等。 看了介绍,一脸懵逼,这是啥玩意啊。下面我来解释一下 2.1 V8引擎是什么?众所周知,JavaScript是解析型语言,我们写好的JavaScript代码会由JavaScript引擎去解析,而V8是JavaScript引擎的一种。 在传统意义上,我们会认为解析器是逐条解析(一边执行一边解析),但为了提高JavaScript的解析速度(相当于提高用户体验),在解析的时候做了点“手脚”。V8引擎:为了提高解析的性能,引入了一些“后端”的技术(不过他本来就由C++编写的)。它是先将JavaScript源代码转成抽象语法树,然后再将抽象语法树生成字节码。如果发现某个函数被多次调用或者是多次调用的循环体(热点代码),那就会将这部分的代码编译优化。说白了就是:对热点代码做编译,非热点代码直接解析。 ...

August 8, 2019 · 1 min · jiezi

医学思维导图讲解绘制软件那个好

要想成为一名合格的医生,背书还真是一道绕不开的坎,作为一名医学生,背书背到崩溃是生活的常态。面对那些种类繁多的药品名称,各种数据症状和临床表现,简直崩溃有木有。其他专业背书好歹能画个重点,但是医学你想找重点?不存在的,病人的病可不会挑重点给你治。什么?你问我怎么才可以提高背书的效率?思维导图记忆法一起来了解下! 什么是思维导图?思维导图又叫心智图,是一种用来提高大脑逻辑思维能力的工具 ,它简单而又及其有效。如今在很多地区和国家都掀起了一股思维导图的热潮,越来越多的人都在学习使用思维导图。他已经被应用于生活中的方方面面,包括学习笔记、做决策、计划、会议记录、演讲、写作等,都可以看到思维导图的影子。 如何借助思维导图把书读薄?大家都知道,学医的要背的书通常都是一本比一本厚,要是没点技巧光靠死记硬背是很难背下来的,所以我们需要借助思维导图拆书法来将这些书读“薄”。 我们可以通过建立联想记忆,之后只记忆标题,当提及标题的时候联想扩展到各个知识点。读到最后,呈现在你思维框架内的只有大块的模块与线索,类似一个索引目录一样。你的知识体系框架基本确立,不再拘泥于某一个点,而是通透,全面地审视一个学科,这个过程就是将书读薄。 当然了,理想的高效背书模式,还是建立在平时努力的基础上的,临时抱佛脚什么方法都很难帮你,如果你对这种背书方法已经跃跃欲试的话,可以点击此处来获取免费的思维导图软件。 软件推荐MindMaster 可谓是思维导图软件中的新秀。界面设计更加时尚大方,超大的操作按钮图标,即便是零基础用户都可以快速上手;功能颇具特色,让学生用户可以用上甘特图、幻灯片以及鱼骨图等功能。MindMaster提供免费基础版,自带海量的符号和精美的例子,无需联网,就能找到合适的图标和模板,高效完成导图的绘制工作。 更多特点 1、适用于Mac、Windows以及Linux三大操作平台; 3、功能和易用性堪比国外的MindManager软件; 4、模板、例子以及剪贴画素材比较丰富,特别是内置科学用的图形符号; 5、支持云协作和云分享; 6、可切换为黑色护眼的模式。 点击即可下载免费思维导图软件 温馨提示:>> 点击进入思维导图社区,搜索:医学,即可免费获取本文高清版思维导图。

August 8, 2019 · 1 min · jiezi

第十集-从零开始实现一套pc端vue的ui组件库-计数器组件

第十集: 从零开始实现( 计数器组件 ) 本集定位: 听到计数器这个名字很多人是不是一瞬间没有什么印象, 毕竟这个组件用的比较少,就是那种左边一个'-'右边一个'+', 控制某些数量的时候才会用到, 比如我之前做的商城小程序只有'下单'页面的规格弹出框里面才有他的身影, 如果是涉及到处理商品数量很频繁的业务场景应该会很常见吧, 但是不要看这个组件小, 编写它的时候坑还不少, 本次我们就来做一个计数器, 目标就是尽可能小, 尽可能的省性能. 1:需求分析每次+1 -1是常态, 但是如果搞活动, 每次最少为+-2个或三个, 就要兼容一下了,( 举一个实际遇到的坑, 我们之前把用户限制为每次活动, 每个用户只能买2个, 但是没有做好防备, 导致用户可能这次只买一个, 而下次他再次购买的时候会提示每次只能买两个, 但显示他只点击了买一个, 因为他已经买过一个, 为了兼容这个问题, 搞得还要加莫名其妙的补救代码 )中间的显示区应该可输入的, 用户想买1000个不可能让他+1+1+1..., 某些组件采用的是, 平时其为div, 点击之后变为input, 个人感觉完全没必要, 一个元素就够了, 何必搞两个元素, input状态下把他的默认样式去掉就好了.左右两边要有限制, 很多时候会有限购一说, 比如我做的商城, 库存只有10个 或者单个用户最多购买3个, 最少买两个等等限制.小数位数的显示一说... 这个其实我还真遇到过, 有一种需求叫做, 只要涉及数字就必须精确到后两位, 这种需求会导致后台同学对数据库做一定的限制, 从而我们传给后台的数据也就存在限制了.2: 基本结构:先展示一章普通状态的图, 让我们更直观的去完成它, 造型比较别致, 是本套组件的一个特点, 哈哈做的与别人一样会导致思想的禁锢, 自己写代码多尝试新的东西, 但是工作中一定要中规中矩, 以公司条款为准则. vue-cc-ui/src/components/InputNumber/index.js import inputNumber from './main/input-number.vue'inputNumber.install = function(Vue) { Vue.component(inputNumber.name, inputNumber);};export default inputNumbervue-cc-ui/src/components/InputNumber/main/input-number.vue ...

August 8, 2019 · 3 min · jiezi

可靠React组件设计的7个准则之SRP

翻译:刘小夕原文链接:https://dmitripavlutin.com/7-... 原文的篇幅非常长,不过内容太过于吸引我,还是忍不住要翻译出来。此篇文章对编写可重用和可维护的React组件非常有帮助。但因为篇幅实在太长,我不得不进行了分割,本篇文章重点阐述 SRP,即单一职责原则。 ————————————我是一条分割线———————————— 我喜欢React组件式开发方式。你可以将复杂的用户界面分割为一个个组件,利用组件的可重用性和抽象的DOM操作。 基于组件的开发是高效的:一个复杂的系统是由专门的、易于管理的组件构建的。然而,只有设计良好的组件才能确保组合和复用的好处。 尽管应用程序很复杂,但为了满足最后期限和意外变化的需求,你必须不断地走在架构正确性的细线上。你必须将组件分离为专注于单个任务,并经过良好测试。 不幸的是,遵循错误的路径总是更加容易:编写具有许多职责的大型组件、紧密耦合组件、忘记单元测试。这些增加了技术债务,使得修改现有功能或创建新功能变得越来越困难。 编写React应用程序时,我经常问自己:如何正确构造组件?在什么时候,一个大的组件应该拆分成更小的组件?如何设计防止紧密耦合的组件之间的通信?幸运的是,可靠的组件具有共同的特性。让我们来研究这7个有用的标准(本文只阐述 SRP,剩余准则正在途中),并将其详细到案例研究中。 单一职责当一个组件只有一个改变的原因时,它有一个单一的职责。编写React组件时要考虑的基本准则是单一职责原则。单一职责原则(缩写:SRP)要求组件有一个且只有一个变更的原因。 组件的职责可以是呈现列表,或者显示日期选择器,或者发出 HTTP 请求,或者绘制图表,或者延迟加载图像等。你的组件应该只选择一个职责并实现它。当你修改组件实现其职责的方式(例如,更改渲染的列表的数量限制),它有一个更改的原因。 为什么只有一个理由可以改变很重要?因为这样组件的修改隔离并且受控。单一职责原则制了组件的大小,使其集中在一件事情上。集中在一件事情上的组件便于编码、修改、重用和测试。 下面我们来举几个例子实例1:一个组件获取远程数据,相应地,当获取逻辑更改时,它有一个更改的原因。 发生变化的原因是: 修改服务器URL修改响应格式要使用其他HTTP请求库或仅与获取逻辑相关的任何修改。示例2:表组件将数据数组映射到行组件列表,因此在映射逻辑更改时有一个原因需要更改。 发生变化的原因是: 你需要限制渲染行组件的数量(例如,最多显示25行)当没有要显示的项目时,要求显示提示信息“列表为空”或仅与数组到行组件的映射相关的任何修改。你的组件有很多职责吗?如果答案是“是”,则按每个单独的职责将组件分成若干块。 如果您发现SRP有点模糊,请阅读本文。在项目早期阶段编写的单元将经常更改,直到达到发布阶段。这些更改通常要求组件在隔离状态下易于修改:这也是 SRP 的目标。 1.1 多重职责陷阱当一个组件有多个职责时,就会发生一个常见的问题。乍一看,这种做法似乎是无害的,并且工作量较少: 你立即开始编码:无需识别职责并相应地规划结构一个大的组件可以做到这一切:不需要为每个职责创建组成部分无拆分-无开销:无需为拆分组件之间的通信创建 props 和 callbacks这种幼稚的结构在开始时很容易编码。但是随着应用程序的增加和变得复杂,在以后的修改中会出现困难。同时实现多个职责的组件有许多更改的原因。现在出现的主要问题是:出于某种原因更改组件会无意中影响同一组件实现的其它职责。 不要关闭电灯开关,因为它同样作用于电梯。 这种设计很脆弱。意外的副作用是很难预测和控制的。 例如,<ChartAndForm> 同时有两个职责,绘制图表,并处理为该图表提供数据的表单。<ChartandForm> 就会有两个更改原因:绘制图表和处理表单。 当你更改表单字段(例如,将 <input> 修改为 <select> 时,你无意中中断图表的渲染。此外,图表实现是不可重用的,因为它与表单细节耦合在一起。 解决多重责任问题需要将 <ChartAndForm> 分割为两个组件:<Chart> 和<Form>。每个组件只有一个职责:绘制图表或处理表单。组件之间的通信是通过props 实现。 多重责任问题的最坏情况是所谓的上帝组件(上帝对象的类比)。上帝组件倾向于了解并做所有事情。你可能会看到它名为 <Application>、<Manager> 、<Bigcontainer> 或 <Page>,代码超过500行。 在组合的帮助下使其符合SRP,从而分解上帝组件。(组合(composition)是一种通过将各组件联合在一起以创建更大组件的方式。组合是 React 的核心。) 1.2 案例研究:使组件只有一个职责设想一个组件向一个专门的服务器发出 HTTP 请求,以获取当前天气。成功获取数据时,该组件使用响应来展示天气信息: import axios from 'axios';// 问题: 一个组件有多个职责class Weather extends Component { constructor(props) { super(props); this.state = { temperature: 'N/A', windSpeed: 'N/A' }; } render() { const { temperature, windSpeed } = this.state; return ( <div className="weather"> <div>Temperature: {temperature}°C</div> <div>Wind: {windSpeed}km/h</div> </div> ); } componentDidMount() { axios.get('http://weather.com/api').then(function (response) { const { current } = response.data; this.setState({ temperature: current.temperature, windSpeed: current.windSpeed }) }); }}在处理类似的情况时,问问自己:是否必须将组件拆分为更小的组件?通过确定组件可能会如何根据其职责进行更改,可以最好地回答这个问题。 ...

August 8, 2019 · 4 min · jiezi

前端面试每日31第114天

今天的知识点 (2019.08.08) —— 第114天[html] 举例说明HTML5的Canvas元素有什么用途?[css] 为什么要使用css sprites?[js] 写一个把数字转成中文的方法,例如:101转成一百零一[软技能] 你知道什么是B/S和C/S架构吗?说说它们的区别项目地址: 前端面试每日3+1 【推荐】欢迎跟 jsliang 一起折腾前端,系统整理前端知识,目前正在折腾 LeetCode,打算打通算法与数据结构的任督二脉。GitHub 地址 微信公众号欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎点个Star, 同时欢迎微信扫码关注 前端剑解 公众号,并加入 “前端学习每日3+1” 微信群相互交流(点击公众号的菜单:进群交流)。 《论语》,曾子曰:“吾日三省吾身”(我每天多次反省自己)。 前端面试每日3+1题,以面试题来驱动学习,每天进步一点! 让努力成为一种习惯,让奋斗成为一种享受!相信 坚持 的力量!!!学习不打烊,充电加油只为遇到更好的自己,365天无节假日,每天早上5点纯手工发布面试题(死磕自己,愉悦大家)。希望大家在这浮夸的前端圈里,保持冷静,坚持每天花20分钟来学习与思考。在这千变万化,类库层出不穷的前端,建议大家不要等到找工作时,才狂刷题,提倡每日学习!(不忘初心,html、css、javascript才是基石!)欢迎大家到Issues交流,鼓励PR,感谢Star,大家有啥好的建议可以加我微信一起交流讨论!希望大家每日去学习与思考,这才达到来这里的目的!!!(不要为了谁而来,要为自己而来!)交流讨论欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎分享! 项目地址: 前端面试每日3+1

August 8, 2019 · 1 min · jiezi

动态创建标签img-VS-script

对于统计页面数据这样的情景(俗称埋点),我们常用的方式就是动态创建<img>或<script>,至于原因,一般有以下几点:1.埋点一般不用关心请求的结果2.可以实现跨域请求 3.无需使用ajax就能达到发请求的目的 4.都是原生实现,兼容性好 现就两种方式做一下对比和总结: 一、用法1.动态创建<img>方式1:通过img标签 function sendByImg(src) { var img = document.createElement("img"); img.src = src;}方式2:通过Image对象 function sendByImage(src) { var img = new Image(); img.src = src;}2.动态创建<script>只有一种方式:通过<script>标签 function sendByScript(src){ var script = document.createElement("script"); script.src = src; (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(script);}二、区别区别1:如果要触发请求,动态创建的<script>必须要插入到DOM中,而动态创建的<img>则不需要演示代码: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Img VS Script</title></head><body><h3> 请观察浏览器中的Network和Elements!</h3><script> function sendByScript(src){ var script = document.createElement("script"); script.src = src; } function sendByScriptInsertDOM(src){ var script = document.createElement("script"); script.src = src; (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(script); } function sendByImage(src) { var img = new Image(); img.src = src; } function sendByImg(src) { var img = document.createElement("img"); img.src = src; } function sendRequest(src) { //一、通过script: //不插入DOM,不会触发请求 sendByScript(src + '/byScript'); //插到DOM中,会触发请求 sendByScriptInsertDOM(src + '/byScriptDOM'); //二、通过img: //不插入DOM,不会触发请求 sendByImage(src+ '/byImage'); //不插入DOM,不会触发请求 sendByImg(src+ '/byImg'); } sendRequest('https://wwww.baidu.com')</script></body></html>用chrome浏览器打开此HTML文件,查看network: ...

August 8, 2019 · 1 min · jiezi

复习CSS实现宽高等比自适应容器

在最近开发移动端页面,遇到这么一个情况:当页面宽度 100% 时,高度为宽度一半,并随手机宽度变化依然是一半。 于是我们就需要实现一个宽度自适应,高度为宽度一半的容器。 这里先以高度为宽度一半为例,也可以是其他任意比例。 一、思考如何实现这个问题类似于:我们在移动端页面,上面有一张宽度 100% 的图片,如果我们没设置高度,则图片会根据原有尺寸,等比缩放。 我们可以借助这个想法,根据元素高度,来为元素设置一个相应比例的高度即可。 二、实现方法1 - 通过 vw 视口单位实现所谓视口单位(viewport units)是相对于视口(viewport)的尺寸而言,100vw 等于视口宽度的 100%,即 1vw 等于视口宽度的 1%。 我们就可以利用这个特性,实现移动端的宽高等比自适应容器。 HTML代码: <div class="box"> <img src="http://images.pingan8787.com/2019_07_12guild_page.png" /></div>CSS代码: *{ margin:0; padding:0}.box{ width:100%; height:51.5vw}.box img{ width:100%; }为什么 .box 高度为 51.5vw 呢?原因是图片原来的尺寸是 884 * 455的宽高比例,即 455 / 884 = 51.5%。 这个方法相比原来图片的等比缩放,有个优点:无论图片是否加载成功,容器高度始终是计算完成,不会造成页面抖动,也不会造成页面重绘,从而提升性能。 下面看看这种情况下,图片加载成功和失败的对比: 三、实现方法2 - 通过子元素 padding 实现通过设置子元素的 padding 属性来实现,是比较常用,也是效果比较好的一种,这里需要理解的是:子元素的 padding 属性百分比的值是先对父容器的宽度而言。 这里看下面代码和效果图理解下: HTML代码: <div class="box"> <div class="text">我是王平安,pingan8787</div></div>CSS代码: .box{ width: 200px;}.text{ padding: 10%;} ...

August 8, 2019 · 1 min · jiezi

常用元素水平垂直居中方案

flex实现水平垂直居中适用场景:父子宽高都可未知(比较推荐这种方式,简单,而且目前兼容性也不错。) <html> <head> <style> .parent { width: 100%; height: 100px; background: cyan; display: flex; justify-content: center; align-items: center; } .son { width: 20%; height: 20%; background: pink; } </style> </head> <body> <div class='parent'> <div class='son'></div> </div> </body></html>绝对定位加上负margin适用场景:父元素宽高已知未知都行,但是首先得有宽高。其次子元素的宽高必须已知,因为需要设置子元素的负margin. (也可以将负margin设置成translate来做位移实现) <html> <head> <style> .parent { position: relative; width: 200px; height: 200px; background: pink; } .son { position: absolute; left: 50%; top: 50%; margin-left: -25px; margin-top: -25px; width: 50px; height: 50px; background: yellow; } </style> </head> <body> <div class='parent'> <div class='son'></div> </div> </body></html>绝对定位 + auto margin适用场景:父子元素宽高都未知的情况(该方式不需要明确知道子元素宽高,子元素宽高可用百分比,对于子元素宽高不确定需要居中的情况比较适合。) ...

August 7, 2019 · 2 min · jiezi

canvas与svg区别

一:定义什么是canvascanvas画布,使用js在网页上绘制图像 什么是svgsvg是可伸缩矢量图二:使用canvas使用 <script type="text/javascript"> var c=document.getElementById("myCanvas"); var cxt=c.getContext("2d"); cxt.moveTo(10,10); cxt.lineTo(150,50); cxt.lineTo(10,50); cxt.stroke(); c.addEventListener("mousedown", function(event){ alert("hh") });</script>浏览器DOM展示 <canvas id="myCanvas" width="200" height="100" style="border:1px solid #c3c3c3;"></canvas>注意: 1.canvas通过js在画布上画了连线,但是浏览器中没有展示连线DOM2.由于不是以DOM形式展示,canvas是一个整体,不能给画上图形添加事件,只能给canvas整体添加事件svg使用<!DOCTYPE html><html><body> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="190" @click="svgClick"> <polygon points="100,10 40,180 190,60 10,60 160,180" @click="domClick" style="fill:lime;stroke:purple;stroke-width:5;fill-rule:evenodd;" /> </svg></body></html>注意: 1.直接将svg元素嵌入html中,且在浏览器中展示的就是相对应的DOM节点2.能给整个svg添加事件也可以给画的图形添加单独事件三:区别

August 7, 2019 · 1 min · jiezi

单页面路由切换原理简单实现

前言最近学习react时,在使用react-router-dom的时候,对history原理与路由切换实现并不了解,经过学习后总结一下吧!如果你只是使用react 自带history 那下面这些原理,你可能并不会用到。但当需要使用自己的history 或 使用第三方history 的时候你就需要了解其原理在react 中,你要在非组件内可以灵活的切换路由,那么你就要使用自定义的history。 // app.jsximport React from 'react'import './App.scss'import { BrowserRouter } from 'react-router-dom'import history from './history'import XtContent from './layout/content'import Login from './components/loginModal'function App() { return ( <div className="App"> <BrowserRouter history={history} basename="/xiutui"> <Login /> <XtContent /> </BrowserRouter> </div> )}export default App // history.js // 这里使用第三方创建history import { createBrowserHistory } from 'history'export default createBrowserHistory()// 在封装的fetch中使用import axios from 'axios'import history from '@/history';// 设置axios 通用const service = axios.create({ timeout: 5000, headers: { 'Content-Type': 'application/json;charset=UTF-8' }, withCredentials: true})// 响应拦截service.interceptors.response.use( response => { //服务端定义的响应code码为0时请求成功 if (response.data.code === 200) { //使用Promise.resolve 正常响应 return Promise.resolve(response.data) } else if (response.data.code === 1002) { //服务端定义的响应code码为1401时为未登录 message.error('登陆失效,请从新登陆!') /////////// 登陆失败切换登陆页面 **history.push('/Login')** ////////// window.localStorage.removeItem('userInfo') return Promise.reject(response.data) //使用Promise.reject 抛出错误和异常 } else { message.error(response.data.message) return Promise.reject(response.data) } }, error => { if (error && error.response) { let res = {} res.code = error.response.status res.msg = throwErr(error.response.status, error.response) //throwErr 捕捉服务端的http状态码 定义在utils工具类的方法 message.error(res.msg) return Promise.reject(res) } return Promise.reject(error) })模式在React/Vue的路由时,会有两种模式 hash 和 history ,事实上他们是针对游览器的路由模式设置的。其基本原理实际就是通关游览器提供的监听这两种模式的变化,从而映射的对应路由的组件render. ...

August 7, 2019 · 3 min · jiezi

推荐一款P2P不限速的百度云下载工具吗

目前支持百度云的不限速下载工具中,pandownload呼声最高,用的人也最多,但是用多了就会被限速封号,速度直接变成几十KB,今天就给大家推荐一款不怕被限速的下载工具——enfi下载器。 主要特点: 1、免登陆下载 不用登录百度云账号就可以下载,避免了被封号或者限速的困扰。 2、高速下载 因为是不限速,所以速度自然是比超级会员的3-5MB/S要快很多的。 3、离线下载 迅雷走了以后,很少有软件支持离线下载了,还好,enfi下载器弥补了这个空缺,让广大宅男有了新的选择。 4、挂机免费下载 相比于其他付费软件,enfi下载器是可以免费下载的,只要你挂机就可以了,原理是利用你的上传带宽,来为其他用户下载提供加速,这也是点对点下载的精髓,并且挂机的积分还可以提现。 5、按需付费 相比于百度云一个月30元的一刀切,这里提倡按需付费,用多少买多少,适合下载量不多的用户。 产品官网:https://www.enfi.cloud/#/index

August 7, 2019 · 1 min · jiezi

神奇的标签块级元素行内元素空元素

最近有人问我,前端模块为什么是空着的。是呀,前端模块一直没有着手开始写,不是因为没有东西可写,是一直在想着以什么样的前端开篇,有太多东西要写,但如果没有规划的写,可能久而久之的就遗弃了。所以再三决定,从我第一次认识前端知识开始写起,当然对于那些前端大牛,也许这篇文章没有营养,但我相信也不乏一些刚起步进入前端行业的新人,所以大家选择性预览。 前端是一个很容易入门,但却很难走进去的一个行业。看似简单,但一旦深入,就“不可自拔”。说到,前端,肯定少不了要认识他的组成元素,那这就涉及到块级元素,行内元素以及一些空元素。 Html标签html标签定义:是由一对尖括号包裹的单词构成,例如: <html>.标签不区分大小写<html> 和 <HTML>, 推荐使用小写.标签分为两部分: 开始标签<html> 和 结束标签</html>, 两个标签之间的部分我们叫做标签体.有些标签功能比较简单,使用一个标签即可,这种标签叫做自闭和标签,例如: <br/><hr/><input/><img/>标签可以嵌套,例如:<a><b><b/><a/>;但是不能交叉嵌套,例如:<a><b><a/><b/>块级元素总是在新行上开始;高度,行高以及外边距和内边距都可控制;宽度缺省是它的容器的100%,除非设定一个宽度。它可以容纳内联元素和其他块元素 块级元素分类(双标签,eg:<div></div>):<h1>,<h2>,<h3>,<h4>,<h5>,<h6> 定义 HTML 标题。<div> 定义文档中的节。<p> 定义段落。<ul> 定义无序列表。<ol> 定义有序列表。<li> 定义列表的项目。<dl> 自定义定义列表。<dt> 自定义定义列表中的项目。<dd> 自定义定义列表中项目的描述。<table> 定义表格。<thead> 定义表格中的表头内容。<tbody> 定义表格中的主体内容。<tfoot> 定义表格中的表注内容(脚注)。<th> 定义表格中的表头单元格。<tr> 定义表格中的行。<td> 定义表格中的单元。<pre> 定义预格式文本。<address> 定义地址。<article> 定义文章。<aside> 定义页面内容之外的内容。<audio> 定义声音内容。<video> 定义视频。<blockquote> 定义长的引用。<canvas> 定义图形。<caption> 定义表格标题。<details> 定义元素的细节。<fieldset> 定义围绕表单中元素的边框。<figcaption> 定义 figure 元素的标题。<figure> 定义媒介内容的分组,以及它们的标题。<footer> 定义 section 或 page 的页脚。<form> 定义供用户输入的 HTML 表单。<header> 定义 section 或 page 的页眉。<nav> 定义导航链接。<noframes> 定义针对不支持框架的用户的替代内容。<noscript> 定义针对不支持客户端脚本的用户的替代内容。<legend> 定义 fieldset 元素的标题。<menu> 定义命令的列表或菜单。<meter> 定义预定义范围内的度量。<output> 定义输出的一些类型。<section> 定义 section。行内元素和其他元素都在一行上;高,行高及外边距和内边距不可改变;宽度就是它的文字或图片的宽度,不可改变;内联元素只能容纳文本或者其他内联元素; ...

August 7, 2019 · 1 min · jiezi

把富文本的-↵-转为br标签

例如:"我家孩子在SayABC小班课↵跟小伙伴们一起互帮互助,↵合作竞争,学习更加有动力!↵从简单的单词到句型和场景对话,↵孩子越来越敢于开口说英语啦![耶]↵扫码立即领取外教课[爱心]↵让孩子从小与世界接轨~" 需要转为才能被html识别,并且换行。可以这样做。 ‘↵’是回车符'/n',这段内容是通过textarea人为编辑,提交给后端保存的。编辑框中可以识别的字符,在普通的标签里面没办法识别到,所以要转换成可以识别的<br/> 方法1string.replace(/(rn|n|r)/gm, "")然后再用v-html=转换之后的string,就可以正常展示换行了 方法2第二种方法是用 <pre></pre>标签,<pre> 标签的一个常见应用就是用来表示计算机的源代码。可以识别字符串中的‘/n’,‘/r/n’, 制表符,空格... 方法3第三种方法是用<textarea></textarea>展示,这样那边编辑的什么,这边就会显示什么

August 7, 2019 · 1 min · jiezi

用键盘8个键演奏一首蒲公英的约定送给996的自己或者一首月亮代表我的心给七夕的她

体验地址: https://wscats.github.io/pian...项目地址: https://github.com/Wscats/piano 用键盘8个键演奏一首蒲公英的约定送给996的自己或月亮代表我的心给七夕的她,非常简单~ 这个项目仅仅用了几个简单的前端技术实现,献给每一位挚爱音乐的代码家???? 如果你喜欢或者对你有帮助,给我点个赞支持下吧???? 技术点和目录结构项目中没有使用市面主流的框架(React,Vue 和 Angular )和热门的技术,而用的是Omi框架(JSX+WebComponents),还有 Omil 的单文件组件 SFCs 加载器,组件通讯基于Proxy特性,并结合了 VScode 的插件 Eno-Snippets基于AST和正则实时编译.eno或.omi 后缀组件减轻部分的 Webpack 的局部编译压力,当然其他同学们熟知的技术这里就不提及了。 src assetselement app-piano songs 钢琴简谱目录app-piano.eno 单文件组件app-piano.js 组件编译后的JS文件notes.js 键盘按键和音符的映射index.js 组件根容器,配置Proxy的通信方法public samples/piano 钢琴单音符素材app-piano.eno开发中你需要编写的单文件组件app-piano.js经过Eno-Snippets修改或者保存文件Hello.eno后经过插件转化的js文件如下图,左边的代码是我们编写的 .eno 后缀的单文件组件,右边是经过 Eno Snippets 生成的 .js 后缀文件。 Develop & Installation<!-- <img src="./public/demo.png"> -->开发,构建和运行。 # 获取远程仓库代码git clone https://github.com/Wscats/piano# 进入目录cd piano# 安装依赖npm install# 启动项目npm start# 在浏览器访问 http://localhost:3000使用 npm 包管理器安装。 npm install omi-piano运行或者发布属于自己的演奏版本。 # 进入目录cd omi-piano# 安装依赖npm install# 启动项目npm start# 发布自已的演奏版本npm run build简单乐理知识首先我们先补习点音乐基础,提前收集好最基本的钢琴单音素材,每个音符对应一份.mp3文件,用一个对象记录起来,类似下面这样,举个例子这里的A指的是CDEFGAB音名中A也就是Sol,这是最基本的乐理,有没有让你想起小时候上音乐课,画板上的五线谱。 ...

August 7, 2019 · 7 min · jiezi

网站不能正常访问几种原因

再专业网站制作和建设公司,再好的技术和服务都会遇到网站无法正常访问的情况。以下是四川多享公司总结的几种常见的网站打不开无法正常访问的几种原因,要了解这个问题,首先要简单了解一下网站的构成,一个完整的网站主要由域名,空间,程序组成。 一、域名原因 1、 域名是否成功注册或续费。没在正常服务期,网站当然不能正常访问。 2、 是否解析正确,每个网站都有对应的服务器地址。应做好正确的解析,域名才能访问。 3、 域名是否备案,如果你选择的是国内空间,就需在工信部备案。如果没有备案通过,网站也是无法正常访问的。 二、空间问题 1、 虚拟主机是否到期,到期自然打不开。 2、 虚拟主机IP地址是否有变化,如果发生变化,需重新解析域名。 3、 空间是否用完,如果网站内容太多,占用完空间。网站也无法访问。 4、 虚拟主机故障,导致无法访问。 三、网站程序 1、 浏览器兼容问题,网站无法正常访问。 2、 程序有漏洞,被黑客攻击。 3、 网站流量过大,负荷太得。无法正常访问。 4、 程序其他问题。 以上是网站打不开,无法正常访问的几种常见情况。

July 26, 2019 · 1 min · jiezi

20190726前端笔记防抖和节流

防抖为了避免一些监听事件为在自己预料的情况,频繁触发。or 在某些监听命令会频繁触发事件比如resize、mousemove等等未防抖 示例 var count = 0, Elem = doc.getElementById('con') function appendCount(e) { console.log(e); Elem.innerHTML = count++ } // 正常,没有防抖的情况下,直接监听执行 Elem.addEventListener('mousemove', function() { appendCount() })这会导致,只要鼠标移动,会导致Eelm.innerHTML不断改变。现在看起来好像没什么问题,如果是很多数据渲染或者请求几千条列表数据呢? 会导致浏览器不断回流和重绘。 那如何防抖呢??触发mousemove时间后1s内,只有不在触发mousemove方法才会能执行appendCount()。 var count = 0, Elem = doc.getElementById('con'); function debounce(fn, waitTime){ // 定义定时器 var timeoutFn = null; return function (){ // 清空定时器 clearTimeout(timeoutFn); // 重置定时器 timeoutFn = (() => { fn.apply(this, arguments) },waitTime) }}function appendCount(){ ELem.innerHTML=count++;}Elem.addEventListener('mousemove', debounce(appendCount, 500))防抖流程mousemove触发,触发debounce()`定义一个定时器timeoutFn,返回执行内容为:清除当前timeoutFn定时器( timeoutFn = null;),定义执行内容。 ...

July 26, 2019 · 1 min · jiezi

如何结合npm做一个前端脚手架

背景需求:在日常开发中,随着项目越来越多,能重复利用的代码就越多,急需一套基本的模板来初始化项目,把代码放到自己的gitlab或github上,每次又得找到地址重新clone一下,很麻烦期望的结果:XXX init 。。。一行命令解决步骤:1、申请一个npm账号,https://www.npmjs.com/2、写一个npm项目package.json: { "name": "windssr", "version": "1.0.8", "description": "a tool service for react-ssr", "main": "index.js", "bin": { "windssr": "index.js" }, "author": "windseek", "license": "ISC", "dependencies": { "chalk": "^2.4.2", "co": "^4.6.0", "co-prompt": "^1.0.0", "commander": "^2.20.0" }, "scripts": { "test": "test" }, "repository": { "type": "git", "url": "git+https://github.com/Windseek/react-ssr-cli.git" }, "keywords": [ "react", "react-ssr", "wind-ssr", "react-ssr-cli" ], "bugs": { "url": "https://github.com/Windseek/react-ssr-cli/issues" }, "homepage": "https://github.com/Windseek/react-ssr-cli#readme"}init.js 'use strict'const exec = require('child_process').execconst co = require('co')const prompt = require('co-prompt')const config = require('./template.json')const chalk = require('chalk')module.exports = () => { co(function *() { // 处理用户输入 let tplName = yield prompt('Template name (you can input one like react, vue, angular): ') let projectName = yield prompt('Project name: ') let gitUrl,branch; console.log(config.tpl); if (!config.tpl[tplName]) { console.log(chalk.red('\n × Template does not support!')) process.exit() } gitUrl = config.tpl[tplName].url branch = config.tpl[tplName].branch // git命令,远程拉取项目并自定义项目名 let cmdStr = `git clone ${gitUrl} ${projectName} && cd ${projectName} && git checkout ${branch}` exec(cmdStr, (error, stdout, stderr) => { if (error) { console.log(error) process.exit() } console.log(chalk.green('\n √ Generation completed!')) console.log(`\n cd ${projectName} && npm install \n`) process.exit() }) })}index.js ...

July 26, 2019 · 1 min · jiezi

RN中webview的一些思考

遇到的坑:webview和h5通信时,会有一些延迟导致不能立即生效具体描述:在使用react-native时,需要加载外部网页,加载后,RN提供一个按钮可以关闭网页,但如果打开的是内部网页就需要隐藏这个按钮,h5代码使用react写的,在componentDidMount时,发送postmessage给客户端(RN),此时发现收不到,查阅react-native官方文档后得已解决。解决过程:https://github.com/facebook/r...,解释了为什么要延迟https://github.com/react-nati... 解释了,升级后的webview为什么postmessage不能直接用 import React from 'react';import { WebView } from 'react-native';export default class myComponent extends React.Component<any, any> { public hide(){ // 隐藏按钮的逻辑 // 建立一个白名单,在白名单里的域名隐藏按钮,之外的不做处理 } public render(): React.ReactNode { const { navigation } = this.props; const { state } = navigation; const { params } = state; return <WebView ref={'webview'} source={{ uri: params.url }} onLoadEnd={this.hide} />; }}感觉对你有帮助的话,支持一下哈:

July 26, 2019 · 1 min · jiezi

深入前端JavaScript异步编程

JavaScript的执行机制在上篇文章中进行了深入的探讨,那么既然是一门单线程语言,如何进行良好体验的异步编程呢回调函数Callbacks当程序跑起来时,一般情况下,应用程序(application program)会时常通过API调用库里所预先备好的函数。但是有些库函数(library function)却要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。这个被传入的、后又被调用的函数就称为回调函数(callback function)。 什么是异步"调用"在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在"调用"发出后,"被调用者"通过状态、通知来通知调用者,或通过回调函数处理这个调用。异步调用发出后,不影响后面代码的执行。简单说就是一个任务分成两段,先执行第一段,然后转而执行其他任务,等做好了准备,再回过头执行第二段。在异步执行的模式下,每一个异步的任务都有其自己一个或着多个回调函数,这样当前在执行的异步任务执行完之后,不会马上执行事件队列中的下一项任务,而是执行它的回调函数,而下一项任务也不会等当前这个回调函数执行完,因为它也不能确定当前的回调合适执行完毕,只要引它被触发就会执行, 地狱回调阶段异步最早的解决方案是回调函数,如事件的回调,setInterval/setTimeout中的回调。但是回调函数有一个很常见的问题,就是回调地狱的问题下面这几种都属于回调 事件回调Node APIsetTimeout/setInterval中的回调函数ajax 请求异步回调嵌套会导致代码难以维护,并且不方便统一处理错误,不能 try catch会陷入回调地狱 fs.readFile(A, 'utf-8', function(err, data) { fs.readFile(B, 'utf-8', function(err, data) { fs.readFile(C, 'utf-8', function(err, data) { fs.readFile(D, 'utf-8', function(err, data) { //.... }); }); });});ajax(url, () => { // 处理逻辑 ajax(url1, () => { // 处理逻辑 ajax(url2, () => { // 处理逻辑 }) })})Promise解决地狱回调阶段Promise 一定程度上解决了回调地狱的问题,Promise 最早由社区提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。 Promise存在三个状态(state)pending、fulfilled、rejectedpending(等待态)为初始态,并可以转化为fulfilled(成功态)和rejected(失败态)成功时,不可转为其他状态,且必须有一个不可改变的值(value)失败时,不可转为其他状态,且必须有一个不可改变的原因(reason)new Promise((resolve, reject)=>{resolve(value)}) resolve为成功,接收参数value,状态改变为fulfilled,不可再次改变。new Promise((resolve, reject)=>{reject(reason)}) reject为失败,接收参数reason,状态改变为rejected,不可再次改变。若是executor函数报错 直接执行reject();Promise 是一个构造函数,new Promise 返回一个 promise对象const promise = new Promise((resolve, reject) => { // 异步处理 // 处理结束后、调用resolve 或 reject});then方法注册 当resolve(成功)/reject(失败)的回调函数// onFulfilled 参数是用来接收promise成功的值,// onRejected 参数是用来接收promise失败的原因//两个回调返回的都是promise,这样就可以链式调用promise.then(onFulfilled, onRejected); const promise = new Promise((resolve, reject) => { resolve('fulfilled'); // 状态由 pending => fulfilled});promise.then(result => { // onFulfilled console.log(result); // 'fulfilled' }, reason => { // onRejected 不会被调用 })then方法的链式调用Promise对象的then方法返回一个新的Promise对象,因此可以通过链式调用then方法。then方法接收两个函数作为参数,第一个参数是Promise执行成功时的回调,第二个参数是Promise执行失败时的回调。两个函数只会有一个被调用,函数的返回值将被用作创建then返回的Promise对象。这两个参数的返回值可以是以下三种情况中的一种: ...

July 26, 2019 · 3 min · jiezi

一键markdown转html

使用marked 这个插件npm install marked --save然后再需要的页面引入, import marked from 'marked' 然后直接使用maeked()方法即可转换为html。 sendNews() { alert(marked(this.content)); },转换前 转换后

July 16, 2019 · 1 min · jiezi

代码质量把控和项目进度之间的平衡

作为前端负责人,很多时候发愁的不是写好代码,而是怎么让身边水平较差的小伙伴能写出好的代码另外,你还要保证项目的进度,所以代码质量和项目进度之间有着天然的矛盾,怎么去平衡值得我们去思考,以下是我的一点经验代码质量由以下几个方面来保证代码风格问题,由工具和强制规范去解决,eslint + prettier + 代码规范(ts部分需要完善)code review,现在主要是由我来看, 后面开放给每个人,我会整理checklist,来协助大家reviewCI (结合gitlab,但是还没有做起来)在项目进行中不断重构(现在我就是这么干的),特别是在原有功能上新增功能,势必会对老代码进行修改,这是重构的大好机会。封装公共的组件库,这样让别人可以很方便的用你写的库,减少了让别人写烂代码的机会在框架架构层面把代码写好,让大家在框架内写代码的时候减少写烂代码的机会具体来谈谈code review现在每个人的代码我都会review,但是我不可能把很多时间放在上面,所以有时候不满意的地方,我会降低要求,直接放过了。所以这中间需要一个取舍,哪些是要严格要求的,哪些是可以不管的。 对变量命名上绝对要严格,而且这是非常容易修改的地方,大家也都愿意改对于代码行数,如果超出行数导致代码过于复杂,难以维护,一定要提出拆分对同一个需求在实现上不同,只要对方的实现没有特别大的漏洞,都可以接受在代码实现度上有更好的方案,可以采取建议的方式,而不是直接否决也要看人,有的人能接受别人的建议,有的人听不得半点否定的东西,要区别对待好代码不一定是写出来的不一定。假如你是做业务逻辑的。首先,好代码可能是聊出来的。比如需求确认这一块,多问多画流程图少动手。就可以减少后期很多麻烦事情。如果在没有理解透需求的情况下动了手,就会做得越多,错的越多。我相信很多工程师都有这种感觉。其次,好代码可能是边读边写出来的。回顾一下一天的工作,你会发现,不管是,你写文章,或者是做一些其他的东西。读代码,大部分都是跳转代码,文件内跳转,文件外跳转,分屏浏览。在这个过程中不断整理和梳理原有的概念。最后落实到代码上。代码的直接修改。占到你很少的时间。最后,好代码是改出来的。

July 16, 2019 · 1 min · jiezi

又是一波前端知识点总结

总结的点都杂七杂八,但愿能找到对你有所帮助的,没有的也没关系嘛!????1. vue强制渲染某个组件$forceupdate 使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。由于某些场景 $forceupdate 不起作用,所以用下面的hack方法。一般来说,这种强制渲染某个组件的情况不多,在组件内部应该处理好内部的渲染。 这个例子还是因为使用某个库后发现了一个bug,后面才想到以下hack方法的。 <my-comp v-if="show"></my-comp><script>data() { return { show: true }},methods: { reRender() { this.show = false this.$nextTick(() => { this.show = true }) }}</script>必须用v-if,v-show不行在$nextTick回调中重新赋值,否则vue会忽略show的第一次赋值2. vue里的ref和v-for一起使用时,得到的引用将会是一个包含了对应数据源的这些子组件的数组当 ref 和 v-for 一起使用的时候,你得到的引用将会是一个包含了对应数据源的这些子组件的数组。<div v-for="item in list" :ref="item.code" @click="handleClick(item.code)">{{item.title}}</div>handleClick(code) { ~~let dom = this.$refs[code]~~ // 错误的写法 let dom = this.$refs[code][0]} vue的一些api在特殊情况下会出现不一致的情况,这点比较蛋疼,需要对文档比较熟悉。 3. Gitlab不仅仅可以作为代码仓库,还可以作为项目管理工具,通过标签,里程碑,提交历史,代码审核流程等。以后在公司里,如果做项目管理或者code review都可以用gitlab来做。 4. css 背景图片background-size的几种适用范围css 背景图片background-size的几种适用范围 5. 作为TL,安排工作计划,协调各种资源也是需要花费时间的,这些时间需要考虑在内,必然会减少编写代码的时间。这一点要清楚。6. 怎么评估工期需求非常明确而且经常这样做:自己评估时间 * 1.5需求不够清晰,有可能变,但是代码和技术方案熟悉:自己评估的时间 * 2需求不够清晰,代码和技术方案也是新的,需要探索:自己评估的时间 * 2.5 or 3自己评估的时间一般会留点 buffer,自我感觉应该没问题,实际上开发过程可能会有各种会议、需求和技术方案变更或者突发事件。所以多留一点 buffer 会更好,因为这个时间点可能是下游运营活动上线时间点,评估后业务方觉得太长可以砍需求拆成两期或者调整上线预期,但一旦设置了时间点,不应该跳票。如果你比预期早完成上线,皆大欢喜,如果你一次次的告知业务方还需要延期一两天,效果正好相反。7. 无缝滚动组件无缝滚动组件 ...

July 16, 2019 · 2 min · jiezi

基于小米即时消息云服务MIMC的Web-IM

michat一个基于小米即时消息云服务(MIMC)的Web IM。 源码地址github和gitee同步。 截图展示 如何使用请先双击目录“需要安装的jars”的install.bat,安装自定义的jars。直接运行类MichatApplication,启动项目。访问http://localhost:8081/login,登录账号。默认配置了以下账号做测试:用户名 密码user 123456admin 123456jack 123456rose 123456simon 123456ddd 123456如何配置自己的MIMC登录https://dev.mi.com/console/appservice/mimc.html,注册并创建应用,修改chatIndex.js的mimc_appId,mimc_appSecret,mimc_appKey为你自己的值。

July 16, 2019 · 1 min · jiezi

你必须要知道的前端那些事儿入门级必读

“ 作为一个入门级的前端小白,前端的发展历史,是你必须要了解的。因为这可以让你更好的理解前端、理解整个前端的行业状态。” 原始社会 早期的前端可以说是原始社会。 long time ago~~ 1990 年,Tim Berners-Lee 以超文本语言 HTML 为基础在 NeXT 电脑上发明了最原始的 Web 浏览器。 1994 年 11 月,Mosaic 浏览器的开发人员创建了网景公司(Netscape Communications Corp.),并发布了 Mosaic Netscape 1.0 beta 浏览器,后改名为 Navigator。但是它只有少数的幸运儿才能使用,因为它此时,只是为了方便科学家们查看文档,传阅论文用的。 所以你可以把1994年看做是前端的起点。 NCSAMosaic浏览器1-1 NCSAMosaic浏览器1-2 此时的网页还是很笨拙的! 你的页面如果有新的内容要刷新展示,那它会重新加载一个新的网页。而这个过程是漫长的。 你如果提交了一个数据请求,那你可能要白屏等待很久,最后返回给你个数据请求错误。。。 如果此时,你想做一个电商网站,那体验的酸爽,可想而知~ 此时的互联网,它的开发者统称为程序猿。 因为前后端开发是一体的,前端代码是后台代码的一部分:后台收到浏览器的请求 ===> 发送静态页面 ===> 发送到浏览器。(这跟我们现在的前后端分离开发方式,完全不一样) 此时的网页以 HTML 为主,是纯静态的网页,网页是“只读”的,信息流只能通过服务器到客户端单向流通,由此世界进入了 Web 1.0 时代。 石器时期 1995 年,网景工程师 Brendan Eich 花了10几天时间设计了 JavaScript 语言。起初这种脚本语言叫做 LiveScript,后来为了借助 Java 语言创造良好的营销效果最终改名为 JavaScript。网景公司把这种脚本语言嵌入到了 Navigator 2.0 之中,使其能在浏览器中运行。 1996 年,微软发布了 VBScript 和 JScript。JScript 是对 JavaScript 进行逆向工程的实现,并内置于 Internet Explorer 3 中。但是 JavaScript 与 JScript 两种语言的实现存在差别,这导致了程序员开发的网页不能同时兼容 Navigator 和 Internet Explorer 浏览器。Internet Explorer 开始抢夺 Netscape 的市场份额,这导致了第一次浏览器战争(有兴趣的同学可以找度娘哦~)。 ...

July 16, 2019 · 2 min · jiezi

浅谈http协议二cookie的历史由来与实际应用

HTTP协议当初为了让协议尽量简洁,制定为无状态协议,即指每次request请求之前是相互独立的,当前请求并不会记录它的上一次请求信息。那么问题来了,开发中经常需要用到状态记录,比如日常的登录网站,不可能每次登录都要客户重新输入密码,这样用户体验肯定会很差,那如何让无状态的http协议将状态记录下来呢?于是浏览器厂商发明了cookie来解决这个难题。 Cookie总是保存在客户端中,按在客户端中的存储位置,可分为内存Cookie和硬盘Cookie,设置了过期时间Expires(Cookie的几个属性之一)的Cookie会存储在硬盘里面,不同操作系统cookie的储存路径会有所不同,而没有设置该属性的Cookie会存储在内存里面,此时浏览器的选项卡可以共享同一个cookie信息,关闭浏览器就会清除该Cookie!首先看一下cookie在前后端交互中的应用: 第一次验证成功后,服务端会在响应头信息中带上“set-cookie”字段,浏览器监测到该字段之后,会把其中的值对号入座写入浏览器的cookie的属性中 存储在cookie中的数据,在它过期之前,每次都会被浏览器自动放在http请求中,如果这些数据并不是每个请求都需要发给服务端的数据,浏览器这设置自动处理无疑增加了网络开销;但如果这些数据是每个请求都需要发给服务端的数据(比如身份认证信息),浏览器这设置自动处理就大大免去了重复添加操作。所以对于那设置“每次请求都要携带的信息(最典型的就是身份认证信息token)”就特别适合放在cookie中。而服务器端通过验证cookie中的信息,实现了验证,也让浏览器端省去了每次都需要输入登录信息的麻烦。 为了实现cookie的作用,除了name和value之外,设计者还给它增加了七个属性,分别是expires/max-age、domain、path、secure、HttpOnly、samesite,这些属性是通过cookie选项来设置的,在设置任一个cookie时都可以设置相关的这些属性,当然也可以不设置,这时会使用这些属性的默认值。 Expires和Max-Ageexpires选项用来设置“cookie 什么时间内有效”。expires其实是cookie失效日期,expires必须是 GMT 格式的时间(可以通过new Date().toGMTString()或者 new Date().toUTCString() 来获得)。如expires=Thu, 25 Feb 2016 04:18:00 GMT表示cookie讲在2016年2月25日4:18分之后失效,对于失效的cookie浏览器会清空。如果没有设置该选项,则默认有效期为session,即会话cookie。这种cookie在浏览器关闭后就没有了,属于内存cookie。而max-age就是cookie写入之后的有效时长,比如max-age=600就是600秒后,cookie则会失效。max-age的优先级高于expires domain 和 pathdomain是域名,path是路径,两者加起来就构成了 URL,domain和path一起来限制 cookie 能被哪些 URL 访问,domain属性的默认值是创建cookie的网页所在服务器的主机名。不能将一个cookie的域设置成服务器所在的域之外的域,要想cookie在多个二级域名中共享,需要设置domain为顶级域名。 HttpOnly告知浏览器不允许通过脚本document.cookie去更改这个值,同样这个值在document.cookie中也不可见。但在http请求张仍然会携带这个cookie。注意这个值虽然在脚本中不可获取,但仍然在浏览器安装目录中以文件形式存在。 secure安全标志,指定后,只有在使用SSL链接(https)时候才能发送到服务器,如果是http链接则不会传递该信息。就算设置了secure 属性也并不代表他人不能看到你机器本地保存的 cookie 信息,所以不要把重要信息放在cookie中。 除了服务器端返回的set-cookie字段,浏览器端也可以对cookie进行操作,有npm为我们封装好的插件js-cookie: https://www.npmjs.com/package...,不过我们还是用原生方法手动实现一遍 获取cookie:在控制台输入document.cookie,或者js代码中console.log(document.cookie)可以得到下图:可以看到,cookie是一个个键值对(“键=值”的形式)加上分号空格隔开组合而成, 形如: "name1=value1; name2=value2; name3=value3",可以用正则表达式来提取等号后面的值 function getCookie(name) { var value = '; '+ document.cookie; var parts = value.split('; ' + name + '='); if(parts.length === 2) { return parts.pop().split(';').shift(); }}写入cookie function setCookie (name, value, day) { if(day !== 0){ //当设置的时间等于0时,不设置expires属性,cookie在浏览器关闭后删除 var expires = day * 24 * 60 * 60 * 1000 var date = new Date(+new Date()+expires); document.cookie = name + "=" + escape(value) + ";expires=" + date.toUTCString() }else{ document.cookie = name + "=" + escape(value) }}注意:expires使用GMT或UTC格式的时间, 我这里没有指定路径(path)和域(domain), 当没有指定路径时默认为当前路径下,如对 于“https://home.cnblogs.com/u/ma...”下设置的cookie,其path为"/u/maderlzp", 其domain为当前域名“home.cnblogs.com” ...

July 16, 2019 · 1 min · jiezi

讲清楚基础系列css布局

两列或三列布局使用flexfloat左右position:absolute,中间margin-left,margin-right圣杯和双飞翼布局,都是为了实现一个两侧宽度固定,中间宽度自适应的三栏布局。<!-- 圣杯布局:column左浮动center宽度100%,否则会导致高度坍塌left使用负外边距margin-left:-100%,然后使用相对定位定位到最左边right直接使用负边距居右--><header id="header">header</header><main id="container"> <div id="center" class="column">center</div> <div id="left" class="column">left</div> <div id="right" class="column">right</div></main><footer id="footer">footer</footer><!-- 双飞翼--><header id="header">header</header><main id="container" class="column"> <div id="center">center</div></main><aside id="left" class="column">left</aside><aside id="right" class="column">right</aside><footer id="footer"></footer>垂直水平居中水平居中text-align:center和块级元素的margin:0 auto;table方案,(IE8+)<style>.table{ display:table;}.cell{ display:table-cell; text-align:center; vertical-align:middle;}</style><div class="table"> <div class="cell"> <img src="http://p0.qhimg.com/t01c430356016e16a2c.png" alt="" /> </div></div>absolute+margin:auto方案,兼容主流的浏览器;但是需要定义父容器的高度,否则子元素绝对定位会导致父元素的坍塌。.absolute-aligned { position: relative; min-height: 500px; background: hsl(200, 100%, 97%);}.absolute-aligned img { margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0;}absolute+translate,(IE9+),同样需要设置父元素的高度.center { background: hsl(180, 100%, 97%); position: relative; min-height: 500px;}.center img { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 30%; }Flexbox方案.center { background: hsl(240, 100%, 97%); display: flex; justify-content: center; align-items: center;}calc方案,IE9+,更适合子元素宽高固定的情况// 50%是父元素的中心点,减去图片宽度和高度的一半从而达到定位效果.calc { background-color: hsl(300, 100%, 90%); min-height: 350px; position: relative;}.calc img { width: 100px; height: 100px; position: absolute; left: calc(50% - 50px); top: calc(50% - 50px);}

July 16, 2019 · 1 min · jiezi

vue-hls-循环-实时监控视频m3u8格式列表

默认vue已经安装好了,UI组件这里以vux为例,用什么UI库问题不大注:循环这种实时视频的做法其实不推荐,但是你保不准,真的有这样的需要 1. 安装依赖 hls.jsnpm i hls.js -S 2. 使用2.1 html 循环渲染video节点<div v-for="video in videos" :key="video.ref" class="videoList"> <p> <span>XX监控</span> <span>通道{{video.which}}</span> <span><x-button @click.native="playVideo(video.which)" mini>播放</x-button><span> </p> <div class="videoContainer"> <video :ref='video.ref'></video> </div></div>2.2 【js】hls挂载节点,解析// 结构略import Hls from 'hls.js';data() { return { videos: [] }},methods: { // 节点挂载---$refs attach() { for (let index = 0; index < this.videos.length; index++) { if (Hls.isSupported()) { this.videos[index].hls = new Hls(); this.videos[index].hls.attachMedia(this.$refs[this.videos[index].ref][0]); } } }, // 播放实时监控 playVideo(channel) { let _this = this; let videoRef = this.videos[channel-2].ref; this.$refs[videoRef][0].controls = 'controls'; // 请求和心跳等涉及业务的略 _this.videos[channel-2].hls.loadSource(res.data.url); // 正常解析 _this.videos[channel-2].hls.on(Hls.Events.MANIFEST_PARSED, function () { _this.$refs[videoRef][0].play() }); // 失败 _this.videos[channel-2].hls.on(Hls.Events.ERROR, function () { 根据业务对失败情况进行分别处理 } }}// 选择生命周期(需要$el已经存在,mounted()或者keep-alive的activated())// 我这里使用的是activated()activated(){ // axios 请求略(这里演示用固定数量,通道从2开始) this.videos = []; for (let i = 0; i < 5; i++) { let item = { hls: null, ref: `video${i+2}`, which: i+2, } this.videos.push(item) this.$nextTick(() => { this.attach() }) }}// 销毁deactivated() { for (let i = 0; i < this.videos.length; i++) { this.videos[i].hls.destroy(); }}

July 16, 2019 · 1 min · jiezi

highcharts大数据显示

今日分享基于highcharts的地图,柱状图及饼图设计界面中的图表均是模拟ajax请求json格式完成图形渲染。界面设计为响应式设计,可适配不同尺寸大小的屏幕。效果图展示: 饼图位于second.html 代码下载地址:https://github.com/zhangshuan...(图表若无法显示,可放于服务器测试。)

July 16, 2019 · 1 min · jiezi

svg-线条动画

<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg&quot;> <line x1="10" y1="10" x2="10" y2="90" /><polyline points="30,0 30,90 80,90" fill="none" stroke="black" stroke-width="4"/></svg> <style>svg { background: #ccc;}svg line { /* stroke: #999; */ stroke-width: 4; fill: none;}@keyframes depict { from { stroke: red; stroke-dashoffset: 200; } to { stroke: red; stroke-dashoffset: 0; }}svg polyline{ stroke-dasharray: 200; animation: depict 2s linear 0s 1 normal forwards;} </style>

July 16, 2019 · 1 min · jiezi

初识React-Native的环境搭建问题Android

最近公司技术栈调整,移动端框架要转成react native,所以抽时间先搭建了个Android的开发环境,准备先来个Hello World看看,然后...就被虐了,所以记录下被虐的过程中遇到的问题。 1.首先就是按照react native中文网的顺序,该安装的安装,到react-native run-android的时候,出现第一个问题:Exception in thread “main”java.util.zip.ZipException,后面还有说gradle文件的一堆问题。。。解决方案:然后我就去gradle官网下了一个同样版本的(我的版本是gradle-5.4.1-all.zip),把我的C:\Users\win 10\.gradle\wrapper\dists\gradle-5.4.1-all\3221gyojl5jsh0helicew7rwx\gradle-5.4.1-all.zip替换成下载下来的同样版本的文件 2.然后第二个问题也是到react-native run-android的时候,报了一堆错,瞬间有点凌乱了,就是下面的这堆: 据说就是这个安卓的sdk如果要install,需要你同意它的license解决方案:进入到你安装Android SDK的目录,也就是这个路径里:C:\Users\everrise\AppData\Local\Android\Sdk(自己环境的sdk安装路径)然后进入到tools:cd tools接着进入bin:cd bin然后执行这个命令:sdkmanager.bat --licenses 回车之后会出现提示,需要你允许认证,so我就一路y下来了。 最后把Android Studio 中的模拟器打开(打开的时候需要将BIOS设置里面的vt虚拟化打开,步骤Advanced->Virtualization Technology设置为Enabled),然后运行react-native run-android,成功的将第一个hello world 跑起来了. ps:如有错误,还请路过的大佬,不吝赐教

July 16, 2019 · 1 min · jiezi

html通过canvas转成base64

作者:@wucj shouzijiang 在H5的营销活动中,经常生成一张图片让用户分享或者保存,这时候处理方案有两种。一种是让后端生成图片,返回一个图片地址给前端展示一种是前端自主合并生成图片展示,文中主要说明这个方案 demo <!--生成后存放的IMG--><img src="" id="saveImages" alt=""><a href="javascript:;" class="create">生成海报</a><!--用来生成的HTML--><div id="saveContent" class="saveContent"> <img src=""> <div class="name pa"></div> <div class="msg pa"></div></div><style>#saveContent{width: 7.5rem; height: 12.27rem; position: relative;}#saveContent img{ width: 100%;}#saveContent .name{color: #7c5234;font-size: .3rem;top: 6.55rem;line-height: .6rem;text-align: center;left: 0;right: 0;}#saveContent .msg{color: #7c5234;font-size: .24rem;top: 7.35rem;text-align: center;left: 0;right: 0;}#saveContent .msg span{ color: #cf5350; font-size: .36rem;}</style><!--使用最新版本的html2canvas--><!--官网https://html2canvas.hertzen.com/--><script src="//html2canvas.hertzen.com/dist/html2canvas.min.js"></script><script src="//static.leiting.com/lib/jquery-1.9.0.min.js"></script><script>//生成$(function(){ var isCreate=false; $('a.create').on('click',function(){ isCreate=true; $('#saveContent img').attr('src','//activity.leiting.com/wd/201904/data/images/pop/1.jpg'); $('#saveContent .name').html('aaaaaa'); $('#saveContent .msg').html('bbbbbbbbbb'); html2canvas(document.getElementById('saveContent'), { onrendered: function(ca) { $('#saveImages').attr('src',ca.toDataURL('image/jpeg')); } }); })})</script>

July 16, 2019 · 1 min · jiezi

前端知识总结

前端知识总结vuejsvue实现双向绑定原理1、Object.defineProperty()中的set/get设置属性值/获取属性值2、过程 Observer劫持并监听所有属性 发生变化,通知Dep观察者(update函数)Watcher负责向观察者列表添加对应更新函数Compile编译解析初始化/更新vue生命周期beforeCreate data和methods中的数据和方法还没初始化created data和methods初始化完成beforeMount 模板已经在内存编译好了,尚未挂载到页面mounted 页面挂载完成,可以操作DOMbeforeUpdate 页面数据是旧的,data数据是新的,页面和最新数据还没同步updated 页面和data已经保持最新beforeDestory 进入销毁阶段,data、methodes...还可用destroyed 组件已经完全销毁,data、methods以及过滤器,指令不可用vue组件通信父子通信 父组件绑定属性“:data-attr”数据子组件在props接收驼峰式dataAttr数据子与父通信 子组件$emit('to-parent',newMsg)绑定属性传输数据父组件绑定@to-parent="getChildren(e)"属性接收数据兄弟通信 在main.js建立一个Vue.prototype.bus事件总线(中间层)在borther1,this.bus.$emit('属性toborther2',值)在borther2接收,this.bus.$on('toborther2',function(val){ that.msg = val })vue的虚拟DOM虚拟DOM出现是为了减少频繁大面积的重绘引发的性能问题虚拟dom和真实dom的区别 1、虚拟dom不会排版与重绘 2、真实dom频繁排版与重绘效率相当低 3、虚拟dom进行频繁修改,然后一次性比较并修改真实dom中需要改的部分,最后并在真实dom中进行排版与重绘,减少过多dom节点排版与重绘损耗 4、虚拟dom有效降低大面积的重绘与排版,因为最终与真实dom比较差异,可以只渲染局部DOM Diff 指的是通过Diff算法去比较虚拟DOM的变化vue怎么更新节点 1、先根据真实DOM生成virtual DOM 2、当virtual DOM某个节点的数据改变后会生成一个新的Vnode 3、Vnode和oldVnode作对比,发现有不一样的就直接修改在真实的DOM,然后使oldVnode的值为Vnode路由全局路由拦截(路由守卫) router.beforeEach(( to, from, next )=>{}) //跳转前 to: 即将进入的目标(路由对象)from:当前导航正要离开的路由next()进行下一个钩子,next(false)中断当前导航,如果此时URL改变,则会重置为from后的路由地址, next('/') next(path: '/')终止当前导航,跳转到一个不同的地址,next(error)如果参数为一个error实例,则会终止导航beforeResolve(( to, from, next )=>{}) //跳转成功afterEach(( to, from, next )=>{}) //跳转后局部路由拦截 路由内部钩子: beforeEnter(( to, from, next )=>{})组件内部钩子 beforeRouteEnter(( to, from, next )=>{}) //从另外的组件进入该组件前触发该钩子beforeRouteUpdate(( to, from, next )=>{}) //同一个组件,参数不一样,不一样数据beforeRouteLeave(( to, from, next )=>{}) //该组件离开跳转到另外的组件时触发该钩子路由传参 ...

July 16, 2019 · 2 min · jiezi

JavaScript基础篇

把知识串一串,连成线,形成体系,从此走上大神之路啦,道路可能会曲折一点,但是咸鱼也要翻一翻身撒~ 一、变量提升何为变量提升? 在JavaScript中,函数及变量的声明都将被提升到函数的最顶部 (函数声明的优先级高于变量声明的优先级)这样就造成了一种不同于其他语言的现象,初看甚至觉得有些诡异:变量可以先使用再声明。举个栗子: x = 1;console.log(x); // 1var x;var name = 'World!';(function () { if (typeof name === 'undefined') { var name = 'Jack'; console.log('Goodbye ' + name); } else { console.log('Hello ' + name); }})();// 输出为 Goodbye Jack为什么会出现这样情况呢? 在JavaScript中,变量声明与赋值的分离,如 var a = 2 这个代码是分两步进行的,编译阶段之行变量声明 var a,在执行阶段进行赋值 a = 2,于是便造成了了变量声明提前情况的发生。解析:对于第二个例子,由于存在变量提升,所以变量声明先于if判断,所以此时 name = undefined,于是便输出了 Goodbye Jack 二、隐式转换前段时间,前端各大博客被一道题刷屏了 ++[[]][+[]]+[+[]]==10?这道题怎么去解决呢,这就涉及到了JS的隐式转换相关的知识了。 简述隐式转换规则对于原始类型:Undefined、Null、Boolean、Number、String 1,加号运算符(+):若后面的是数字,会直接相加得出结果,如 1 + 1 = 2;若后面的是字符类型,则会进行字符拼接,如 1 + '1' = '11'。2,减号运算符(-):若后面的是数字,会直接相减得出结果;若后面的字符,则会将其转为数字类型,然后相减得出结果。3,==运算负责: ...

July 16, 2019 · 4 min · jiezi

Hexo第二弹

目录 1. Hexo支持流程图、时序图2. Hexo多行代码提供复制3. Hexo复制时追加版权Hexo支持流程图、时序图画流程图还需要用别的编辑器画了用图片导入?Hexo实现手写流程图也很简单哦,但是有个小坑,小编被坑了好久,接下来手把手????带你们过坑。 markdown语法实现流程图的方式可以通过mermaid或flowchart,时序图则可以mermaid或sequence,但是默认是不会识别语法的,只是当做普通的多行代码,需要安装插件。 <!-- more--> 方式一:mermaid支持流程图(graph)、时序图(sequenceDiagram)、甘特图(gantt),可以说支持很多了。配置教方式二麻烦一点。 <p id="div-border-left-yellow">在线编辑器地址:https://mermaidjs.github.io/m... ,可以利用在线编辑器编辑完流程图之后,下载SVG或者直接link。</p> 安装官方说的是通过yarn安装(如果没有安装yarn,使用npm install -g yarn安装) $ yarn add hexo-filter-mermaid-diagrams也可以使用npm: $ npm i hexo-filter-mermaid-diagrams插件的官方网址 配置(1)修改<span id="inline-green">站点配置文件_config.yml</span>在最后加入 # mermaid chart mermaid: ## mermaid url https://github.com/knsv/mermaid enable: true # default true version: "7.1.2" # default v7.1.2 options: # find more api options from https://github.com/knsv/mermaid/blob/master/src/mermaidAPI.js #startOnload: true // default true (2)Next主题更改:在themes/next/_partials/footer.swig 最后加入 {% if theme.mermaid.enable %} <script src='https://unpkg.com/mermaid@{{ theme.mermaid.version }}/dist/mermaid.min.js'></script> <script> if (window.mermaid) { mermaid.initialize({theme: 'default'}); } </script>{% endif %}主题可更改,包含 default | forest ...

July 15, 2019 · 3 min · jiezi

解决H5的a标签的download属性下载service上的文件出现跨域问题

1.通过点击下载多媒体文件(图片/视频/文件等)最简单的方式: <a href='url' download="filename.ext">下载文件</a>如果url指向同源资源,是正常的。如果url指向第三方资源,download会失效,表现和不使用download时一致——浏览器能打开的文件,浏览器会直接打开,不能打开的文件,会直接下载。浏览器打开的文件,可以手动下载。 解决方案一:将文件打包为.zip/.rar等浏览器不能打开的文件下载。解决方案二:通过后端转发,后端请求第三方资源,返回给前端,前端使用file-saver等工具保存文件。  如果url指向的第三方资源配置了CORS,download属性无效,但可以获取文件下载到本地,无法修改修改文件名。2.解决方法1. 借助HTML5 Blob实现文本信息文件下载const downloadRes = async (url, name) => { let response = await fetch(url) // 内容转变成blob地址 let blob = await response.blob() // 创建隐藏的可下载链接 let objectUrl = window.URL.createObjectURL(blob) let a = document.createElement('a') //地址 a.href = objectUrl //修改文件名 a.download = name // 触发点击 document.body.appendChild(a) a.click() //移除 setTimeout(() => document.body.removeChild(a), 1000)}2.图片格式如果我们想下载一张图片,可以把这张图片转换成base64格式,然后下载。```export const downloadImg = async (url, name) => { var canvas = document.createElement('canvas'), ctx = canvas.getContext('2d'), img = new Image(); img.crossOrigin = 'Anonymous'; img.onload = function() { canvas.height = img.height; canvas.width = img.width; ctx.drawImage(img, 0, 0); var dataURL = canvas.toDataURL('image/png'); let a = document.createElement('a'); a.href = dataURL; a.download = name; document.body.appendChild(a); a.click(); setTimeout(() => { document.body.removeChild(a); canvas = null; }, 1000); }; img.src = url;};```

July 15, 2019 · 1 min · jiezi

dataimage-data-url-文件转为Blob上传后端

一些场景,比如canvas获取的图片,或者微信开发sdk返回的图片格式是data:img格式的,我们需要上传到服务器上,那就需要进行转化。将dataURL转成Blob// base64 转 blobdataURItoBlob(dataURI) { // convert base64/URLEncoded data component to raw binary data held in a string let byteString; if (dataURI.split(',')[0].indexOf('base64') >= 0) { byteString = atob(dataURI.split(',')[1]); } else byteString = unescape(dataURI.split(',')[1]); // separate out the mime component const mimeString = dataURI .split(',')[0] .split(':')[1] .split(';')[0]; // write the bytes of the string to a typed array const ia = new Uint8Array(byteString.length); for (let i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } return new Blob([ia], { type: mimeString });},构建Form上传表单const blob = dataURItoBlob(imgDataUrl);const formData = new FormData();// formData.append('auth', state.token.auth); 可以选择性的加入一些鉴权formData.append('file', blob);进行数据上传,我这里使用的是axiosconst params = { url: '/store/file', payload: formData }; const data = await this.upload(params);我已经对axios进行了封装export const upload = (params) => { const { url, payload } = params return axios.post(url, payload, { headers: { 'Content-Type': 'multipart/form-data' } }).then(x => x.data)}

July 15, 2019 · 1 min · jiezi

移动端键盘和光标的兼容那点事

作者:@micky思 @wupq @yewq 在H5的开发中,个人的制作页面布局习性不同,多多少少会产生在真机上input的光标和键盘的弹出会出现的各种BUG,文中整理了部分遇到的问题,欢迎新增 ios移动端输入框上浮导致输入位置偏移问题原因:遮罩层定位为fixed,当键盘弹起时,ios11以及以下视口计算有问题,页面的fixed会失效,变成absolute,结果就是当屏幕数据超过一屏时,滑动页面,input框也会跟着一起滚动导致光标不跟随密码弹出框移动。解决方法:如果使用页面数据不超过一屏(禁止滚动),那么即使变成了absolute页面也不会有什么变化。//在弹窗出现的事件里加入$('.wrap').css('height','100%');//wrap为包含除弹窗外的所有页面元素的父div//关闭弹窗时div恢复原来高度$('body').on('click','.pop_close',function(){ $('.wrap').css('height','24.69rem');});//ps:如果整体背景图是在父元素wrap里,background-size:cover微信输入法键盘弹起H5页面无法还原//判断ios系统var u=navigator.userAgent;if(u.indexOf('iPhone')>-1){ var flag; $('body').on('focus','input',function(){ flag=false; }); $('body').on('blur','input',function(){ flag=true; setTimeout(function(){ if(flag==false){ return false; }else{ document.body.scrollTop=document.body.scrollTop; } //防止在多个input间切换时做过多操作 },0); //解决select导致的键盘弹起 $('.select').on('click',function(){ document.body.scrollTop = document.body.scrollTop; }); });}readonly时,IOS会出现光标和输入提示<input type="text" class="" value="" readonly unselectable="on" onfocus="this.blur()">

July 15, 2019 · 1 min · jiezi

常见的面试问题CSS已知高度写出三栏布局

问题:已知高度,写出三栏布局,其中左右两栏宽度各位200px,中间自适应 回答:效果示例解决方案(1)浮动;(2)绝对定位;(3)弹性布局;(4)表格布局;(5)网格布局。 拓展问题:(1)每个解决方案的优缺点(2)他们之间的比较,假设高度去掉,那种方法还能适用或者不适用(3)解决方案的兼容性,哪个更适用在实际项目中 拓展回答:(1)A:缺点:浮动脱离文档流,所以使用的时候要清除浮动;优点:兼容性比较好B:缺点:绝对定位布局脱离文档,它的子元素也会脱离文档流;优点:使用快捷,不容易出现问题,兼容性也比较好C:弹性布局是为了解决上述问题出现的,比较完美的一个D:表格布局比较繁琐,不利于SEO优化;表格布局兼容性比较好,IE8不支持flex,但支持表格。当其中的一个单元格超出的,两侧单元格也会同时增高,根据场景决定。E:网格布局作为一个新技术,可以实现很多复杂的布局,代码量简化很多。(2)flex布局和表格布局。浮动布局因为左侧有遮挡,所以没有超出的文本会在中间出现,超出部分没有遮挡会再左侧出现。 变通:三栏布局两栏布局左右宽度固定,中间自适应左宽度固定,右自适应上下高度固定,中间自适应右宽度固定,左自适应/上高度固定,下自适应/下高度固定,上自适应公共样式:设置大小盒子的高度为 100px,左右(left 和 right)的 div 宽度固定为 200px, 并分别给三个盒子设置不同颜色用来区分。 * { padding: 0; margin: 0;}.layout { height: 100px; margin-top: 20px; margin-bottom: 20px; overflow: hidden;}.layout div { height: 100px;}.layout .left { width: 200px; background-color: blue;}.layout .center { background-color: yellow;}.layout .right { width: 200px; background-color: red;}(1)方案一:浮动center 的 div 需要放到后面(其余方案都不需要更改 Html 顺序),对左右 div 使用 float:left 和 float:right,float 使左右两个元素脱离文档流,中间的正常文档流中。 .float .left { float: left;} .float .right { float: right;} <section class="layout"> <article class="float"> <div class="left"></div> <div class="right"></div> <div class="center"></div> </article></section>(2)方案二:绝对定位将 left、right 和 center 的 div 都设置 absolute 脱离文档流,给 center 的 div 设置左右两边距离 200px (即左右两边盒子的实际宽度)。 ...

July 15, 2019 · 1 min · jiezi

踩坑完全指南长期更新

有很多坑踩过的,记录下来。尤其是css,相信前端er们最讨厌写的就是css样式篇如何设置表格的单元格内容高度回答链接???? 必须要给单元格加一个高度,当然这个高度的值本身并不会生效 <td style="height: 1px"/>

July 15, 2019 · 1 min · jiezi

前端面试重点之多列布局

在页面开发中,当我们拿到设计师给出的UI图后,首先考虑的就是布局问题,而多列布局会是我们碰到最多的布局问题,个人就汇总了开发中常见多列布局问题的解决方法。按列数可以分为两列布局,三列布局,多列布局,其中布局方法中的原理都有类似之处。 目录 一、定宽+自适应两列布局二、两列定宽,一列自适应布局 三、左边不定宽,右边自适应布局 四、多列不定宽,一列自适应 五、等宽布局解决方案 六、等高布局解决方案 (文中Css代码中颜色需自行添加) 一、定宽+自适应两列布局<div class="parent"> <div class="left"><p>left</p></div> <div class="right"><p>right</p></div></div>需求:实现左侧100px,右侧自适应,且间距20px 方法一:左侧浮动,右侧宽度通过margin调整.left { float: left; width: 100px;}.right { margin-left: 120px; //相差的20px是左右之间的间距}方法二:左侧浮动,右侧BFC.left { float: left; width: 100px; margin-right: 20px;}.right { overflow: hidden;}方法三:table单元格默认会等宽,但是table-layout: fixed能够让table元素布局优先,。 .parent { display: table; width: 100%; table-layout: fixed;}.left, .right { display: table-cell;}.left { width: 100px; padding-right: 20px;}方法四:flex.parent { display: flex;}.left { width: 100px; margin-right: 20px;}.right { flex: 1}方法五:css3 calc()计算属性.left { display: inline-block; width: 100px; margin-right: 20px;}.right { display: inline-block; width: calc(100% - 120px);}二、两列定宽,一列自适应布局多列布局用到的属性原理基本都一样,上面的方法也同样适用于此。 ...

July 15, 2019 · 2 min · jiezi

vuecli-项目打包完成后运行-文件路径报错问题

刚新建的vue-cli项目,同事说要打包一版进行测试,打包完成后放在tomcat上发现路径报错问题。百度了一下,怀疑是build里面没有定义路径问题,度友提供了解决方案: 找到config文件夹下的index.js文件,修改路径代码找到build对象,修改属性assetsPublicPath为 ‘./’ 但是由于vue-cli项目中已经没有config文件夹,需要在根目录下创建vue.config.js具体配置网上查了一下,用了一个推荐的配置: module.exports = { baseUrl: '/', outputDir: 'dist', lintOnSave: true, runtimeCompiler: true, //关键点在这 // 调整内部的 webpack 配置。 // 查阅 https://github.com/vuejs/vue-doc-zh-cn/vue-cli/webpack.md chainWebpack: () => {}, configureWebpack: () => {}, // 配置 webpack-dev-server 行为。 devServer: { open: process.platform === 'darwin', host: '0.0.0.0', port: 8080, https: false, hotOnly: false, // 查阅 https://github.com/vuejs/vue-doc-zh-cn/vue-cli/cli-service.md#配置代理 proxy: null, // string | Object before: app => {} }}但是这个配置打包完之后依旧报错,看了原因,是baseUrl: '/'的路径还是有问题,把路径改为baseUrl: './'就能找到对应的路径了,以下为修改后代码: ...

July 15, 2019 · 1 min · jiezi

一个前端界面vue-ssr-后端界面-react-spa-服务node的项目

Kite This is a vue + react project kite前台演示网站地址: 小随笔https://www.xiaosuibi.com/ 后台演示网站地址: 小随笔https://www.xiaosuibi.com/_admin 后台演示网站账户:kitetest 密码:q123456 (资源有点大,可能要加载一段时间) 兼容方面目前还是主推荐用google浏览器吧 备注:因为项目是一直在写的,周期比较长,改了又改,代码可能比较乱,大家能看则看,有意见的,直接提意见,发出来的目的,就是希望大家多提建议,或者意见然后我再来改,代码方面我会一直优化的!!!!!!关于项目的维护,会一直维护下去的 再次备注:代码方面美观,或者有问题的代码,各位大佬直接指出即可,都是自己一个人在学,所以代码方面质量方面肯定没那么好 后续是先做小程序版本+app版本 然后边维护和改bug 目前还需要对编辑器进行优化 Build# npm install || cnpm install 安装所有的包,可能有些多,前台和后台是在一起的打包后台界面 npm run admin-build打包前台界面 npm run client-buildStart# 目前用的数据库只有mysql 本地开发的话,下一个phpstudy即可初始化:npm run init 然后打开浏览器收入 localhost:8086 按照步骤操作即可然后可以选择pro or dev 开始pro 生产环境pro1.1 在cmd 中输入 npm run server 即可进入程序pro1.2 (url或者ip)+ :8086端口即可看到客户端主页pro1.3 (url或者ip)+ :8086/admin端口即可看到客户端后台页面dev 本地开发环境dev1.1 在cmd 中输入 npm run server-start 即可进开启接口服务dev1.2 在cmd 中输入 npm run admin-start 即可进入后台开发预览(地址为:localhost:8083)dev1.3 在cmd 中输入 npm run client-start 即可进入前台开发预览(地址为:localhost:8081)dev1.4 开发环境下 一定要先运行dev1.1的情况下再运行 dev1.2 或者 dev1.3目前cli部分代码写的比较乱,等后期有时间再继续优化,哈哈项目断断续续的写着,主体基本写完,目前就是优化和改bug,代码的逻辑啥的,能看则看,不能看就略过吧,也是自己学习的一个过程,放心这个代码会一直优化的,已经坚持了很久了,可以看提交,哈哈目录结构kite/ | ├──admin/ * 后台页面目录react | ├──client/ * 前台ssr文件目录 │ ├──build * vur ssr build 配置文件 │ ├──config * 部分配置文件 │ ├──public * index模版文件 │ ├──request * 请求配置文件 │ ├──server * dev 模式下的开始文件 │ ├──src * src ssr 主文件目录 │ └──static * 静态资源目录 │ │──config/ * 部分可配置文件 │ │──db/ * mysql and lowdb | ├──server/ * 服务层,所有前台后台接口 │ ├──static/ * 静态资源目录 | ├──views/ * cli 模版目录 │ │──plugins/ * 第三方组件 + 自有js库 + 其他插件性质的脚本 │ │──static/ * 不经编译器处理的静态资源 │ │──store/ * 全局数据状态管理 │ │──package.json * 包信息 │ │──.eslintrc * Eslint配置 │ │──_nodemon.json * _nodemon配置 │ │──.gitignore * Git忽略文件配置 │ └──pm2.json * pm2配置初始化 ...

July 15, 2019 · 2 min · jiezi

常见核心前端面试问题与详细解答

本文总结了前端老司机经常问题的一些问题并结合个人总结给出了比较详尽的答案。关于知识点原理和详细,参考讲堂的视频教程:前端增长-重新定义大前端课程知识在不断更新,本片内容也逐步更新官方博客:FED123前端学堂 1.关于性能优化说说js文件摆放顺序、减少请求、雪碧图等等原理, 说下window.performance.timing api是干什么的?浏览器是按照文档流解析html,为了更快构建DOM树和渲染树将页面呈现到屏幕上,建议是降js放在文档dom树结尾,body标签闭合前。浏览器并发HTTP请求有限制(6个左右),加载页面html后开始解析,解析到外链资源比如js css和图片,就会发http请求获取对应资源。减少请求就是减少这些资源请求, 可以 css资源合并,js资源合并,图片资源合并同时做lazyload,区分首屏非首屏接口,按需请求数据。雪碧图是一种图片资源的合并方法,将一些小图片合成一张图,通过background-position来定位到对应部分。window.performance.timing 参考下前端页面性能指标数据计算方法, performance接口属于w3c标准hight resolution time中的一部分,通过navigation timeline api 、 performance timeline api,user timing api,resource timeline api 这四个接口做了增强实现。其中navigation timeline api中PerformanceTiming 接口数据放在 performance.timing这个对象上。主要记录了浏览器从跳转开始的各个时间点的时间,比如navigationStart是页面开始跳转时间,fetchStart是页面开始时间,domainLookupStart是DNS开始时间,domainLookupEnd是DNS结束时间, 查找到DNS后建立http链接,connectStart和connectEnd分别是链接开始和结束时间,然后是requestStart开始发起请求时间,responseStart开始响应时间,responseEnd响应结束时间。然后是苟安DOM树时间,分别是domLoading, domInteractive, domContentLoad和domComplete时间,分别对应document.readyState状态loading、interactive和complete。最后是页面onload,分别是loadEventStart和loadEventEnd时间节点。可以通过这个接口统计前端的页面性能数据。 domainLookupStart - fetchStart = appCache时间,这段时间浏览器首先检查缓存domainLookupEnd -domainLookupStart = DNS时间connectEnd - connectStart = TCP时间responseStart - requestStart = FTTB首字节时间,或者说是服务器响应等待时间domContentLoad - navigationStart = 页面pageLoad时间 loadEventEnd - navigationStart = 页面onLoad时间 关于知识点原理和详细,参考讲堂的视频教程:前端增长-重新定义大前端 2.请你描述下一个网页是如何渲染出来的,dom树和css树是如何合并的,浏览器的运行机制是什么,什么是否会造成渲染阻塞?参考下:浏览器工作原理   浏览器渲染与阻塞原理 第一部分通过performance.time这个api我们可以了解浏览器加载网页的流程,浏览器边加载html边构建DOM树,当然会有容错和修正机制。浏览器解析到行内css和内联css会立马加入到构建渲染树,解析到外链css就开始加载,加载完之后也会合并到渲染树的构建中,最后将渲染树和DOM做节点链路匹配,也叫layout阶段,计算每个DOM元素最终在屏幕上显示的大小和位置。 遍历顺序为从左至右,从上到下,绘制在屏幕上,layout过程中可能会触发页面回流和重绘,比如某个外链css加载完解析之后合并构建到渲染树中,其中某个css改变了DOM树种某个元素的定位(改成绝对定位)或者改变了长宽边距等位置信息,会触发重新layout,所以会回流reflow。重绘是比如css改变了之前的背景图片颜色,浏览器会重新绘制。 会有渲染阻塞,浏览器刷新的频率大概是60次/秒, 也就是说刷新一次大概时间为16ms,如果浏览器对每一帧的渲染工作超过了这个时间, 页面的渲染就会出现卡顿的现象。浏览器内核中有3个最主要的线程:JS线程,UI渲染线程,事件处理线程。此外还有http网络线程,定时器任务线程,文件系统处理线程等等。 JS线程负责JS代码解析编译执行,称为主线程。常说‘浏览器是单线程’指的是JS主线程只能有一个,主线程执行同步任务,会阻塞UI渲染线程。JS线程核心是js引擎 (IE9+: Chakra firefox:monkey chrome:v8)。webworker可以创建多个js线程,但是受主线程控制,主要用于cpu密集型计算。UI渲染线程当然是负责构建渲染树,执行页面元素渲染。核心是渲染引擎(firefox:gecko、chrome/safari:webkit),由于JS可以操作DOM元素处理样式等,JS主线程是执行同步任务的,所以设计上JS引擎线程和GUI渲染线程是互斥的。 也就是说JS引擎处于运行状态时,GUI渲染线程将处于冻结状态。事件处理线程,由于浏览器是事件驱动的,事件处理线程用来控制事件回调处理,浏览器触发某个事件后会把事件回调函数放到任务队列中,可以看下下面会提到。其他线程统称工作线程,如处理 ajax 的线程,dom事件线程、定时器线程、读写文件的线程等,工作线程的任务完成之后, 会推入到一个任务队列(task queue) ...

July 14, 2019 · 5 min · jiezi

Centos7环境下源码部署ThingsBoard

本文为有thingsboard二次开发需求的同学准备,可以修改源码后编译运行。 准备工作一台4Gb内存以上的服务器(官方推荐8Gb以上,但实测以下配置即可正常运行) Centos7系统 打开8080端口 安装wgetsudo yum install -y wget 更新 EPEL releasesudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm 开始安装安装Java JDK-1.8sudo yum install java-1.8.0-openjdk sudo update-alternatives --config java 查看Java是否安装成功java -version 期望输出为openjdk version "1.8.0_xxx"OpenJDK Runtime Environment (...)OpenJDK 64-Bit Server VM (build ...)如果输出不正常则需要配置环境变量vim /etc/profileexport JAVA_HOME = ${你的安装路径不带bin} 在PATH后边加入$JAVA_HOME/bin 安装最新版Maven(直接用yum安装可能会导致版本过低无法编译)下载wget https://www-eu.apache.org/dist/maven/maven-3/3.6.0/binaries/apache-maven-3.6.0-bin.tar.gz 解压缩tar xvf apache-maven-3.6.0-bin.tar.gz -C /usr/lib/ 配置环境变量vi /etc/profile 添加以下代码M2_HOME="/usr/lib/apache-maven-3.6.0"export M2_HOMEM2="$M2_HOME/bin"MAVEN_OPTS="-Xms256m -Xmx512m"export M2 MAVEN_OPTSPATH=$M2:$PATHexport PATH加载更新后的profile. /etc/profile 或source /etc/profile 查看Maven是否配置成功mvn -version 有如下返回则表示成功Apache Maven 3.6.0 (97c98ec64a1fdfee7767ce5ffb20918da4f719f3; 2018-10-24T23:41:47+05:00)Maven home: /usr/lib/apache-maven-3.6.0Java version: 1.8.0_191, vendor: Oracle Corporation, runtime: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.x86_64/jreDefault locale: en_US, platform encoding: UTF-8OS name: "linux", version: "3.10.0-957.el7.x86_64", arch: "amd64", family: "unix"安装PostgreSQL更新yumsudo yum update ...

July 14, 2019 · 2 min · jiezi

JavaScript技巧分享纯数字带小数点过滤

应用场景在编写输入金额的输入组件input时,虽然能够设置type为number,但却不能够自动检验用户输入的值是否符合金额的格式。比如,用户能够同时输入两个小数点。本文章以此为大前提展开略浅的技巧。 过程解析原始状态说到校验,第一个想到的就是用正则表达式。以微信小程序为例。 DOM结构...<input type='digit' value='{{value}}' bindinput='numChange' />...JavaScript逻辑...numChange(e) { // 修改单次金额 const NEXT = e.detail.value; let currentValue = this.data.value; const NEW_VALUE = this.numCheck(currentValue, NEXT); this.setData({ value: NEW_VALUE || currentValue; })},numCheck(prev, next) { // 数据过滤 // 只保留两位小数 if (next && !/^(([1-9]\d*)|0)(\.\d{0,2}?)?$/.test(next)) { if (next === '.') return '0.'; return prev; } return next;}...获取非空数据并且转换数据类型因为经过过滤后,返回的数据类型是字符串,在使用时,需要再转换一下数据类型。 ...getPureMoney() { // 获取干净的数据(非空) const { value } = this.data; const PARSE_VALUE = parseFloat(value); return !isNaN(PARSE_VALUE) ? PARSE_VALUE : '';},...用过都说好!最后,嘻嘻! ...

July 14, 2019 · 1 min · jiezi

前端增长重新定义大前端

前端增长-重新定义大前端 精心打造全新课程,欢迎吐槽!反馈宝贵意见! 在线课程:思否课堂限时免费哦! 课程介绍前端知识点很多,很细碎。一般同学都是死记硬背一些知识点。机灵的同学会背一些案例,更聪明的同学会背一下原理,理解下大概。奈何时光催人老,再好的记忆也会有忘记的时候,况且人生的不同阶段所侧重的点也不一样。所以本课程从面试考察的知识点入手,梳理前端知识点脉络,精讲各个点的长问问题和设计原理,让你从死记硬背转化为理解,实现前端能力增长。再也不需要死记硬背,该忘记就忘记吧,有事没事想一想,捋一捋就行。 课程大纲本课程参考总结的脑图逐个展开讲解原理。(目前课件还在更新中) 第一章 HTML-相识1.1 前端增长,业界发展,盘他?1.2 学习目标,人生就是起起落落落?1.3 HTML咋解析的呢?DOM构建1.4 CSSOM如何构建?会阻塞吗1.5 RenderTree上来秀一波1.6 Layout布局引擎,新交规解析1.7 牛逼的render进程合成层,拯救世界1.8 HTML加载阻塞?咋不上天呢1.9 页面渲染会堵车吗?FM93交通之声 第二章 CSS-相知2.1 啥是Containing Block?有鸟用2.2 要BFC?要啥自行车2.3 到底是怎么定位?挖坑吗2.4 咋布局?设套吗?flex兄弟上车2.5 CSS优先级,优生优育2.6 CSS预处理原理2.7 合成器和非合成器动画,爆GPU菊花2.8 大哥,你的动画卡顿了,快逃2.9 基线和行高的坑 第三章 JavaScript-相爱 课时19 浏览器引擎与webkit课时20 JavaScript虚拟机运行原理流程剖析课时21 JavaScript类型推断课时22 JavaScript虚拟机对象访问优化课时23 秒懂事件循环原理课时24 事件循环之宏任务与微任务课时25 JavaScript虚拟机垃圾回收课时26 JavaScript数据类型与内存模型课时27 数据类型检测与深浅克隆课时28 数据监听方法有哪些?课时29 模块数据通信的方法 第四章 浏览器-相生 【待更新】 第五章 框架-相克 【8月10更新】 第六章 编码能力-相辅 【8月10更新】 第7章 NodeJs-相成 【8月20更新】 第8章 打包-相情 【8月20更新】 第9章 小程序-相怨【8月20更新】 第10章 前端架构-相恨 【8月20更新】 课件思维导图:

July 14, 2019 · 1 min · jiezi

JS红皮书解读之防篡改对象

前言:去年7月份在简书写的,发现后端、React中也有体现,觉得有必要在微信上分享下。 注意:一旦把对象定义为防篡改,就无法撤销了。 1.不可扩展对象扩展指可以给对象添加属性和方法。 使用Object.preventExtensions(object)阻止对象扩展 let a={name:'chen'} Object.preventExtensions(a) a.age=18 console.log(a.age) //undefined delete a.name console.log(a) //{}注意:(1)严格模式下,不是undefined而是报错。(2)可以删除或修改已有对象属性,但不可添加新属性 使用Object.isExtensible(object) 判断对象是否可扩展 console.log(Object.isExtensible(a)) //false2.密封的对象(sealed object)注意:(1)被密封的对象不可扩展,因此可用Object.isExtensible(object)来判断(2)可以修改,不可删除已有属性,不可添加新属性 Object.seal(a) a.age=20 delete a.name console.log(a.name) //chen a.name='ch' console.log(a.name) //ch使用Object.isSealed(object)判断是否密封 3.冻结的对象(frozen object)冻结的对象是最严格的防篡改级别,既不可扩展,也是密封的,不可修改属性。 使用Object.freeze(object)冻结对象 对于JS库作者而言,冻结对象可防止有人修改库的核心对象。 (完)

July 13, 2019 · 1 min · jiezi

为什么要用语义化标签

一、什么是语义化的HTML? 语义化的HTML就是正确的标签做正确的事情,能够便于开发者阅读和写出更优雅的代码的同时让网络爬虫很好地解析。 二、为什么要做到语义化? 1、有利于SEO,有利于搜索引擎爬虫更好的理解我们的网页,从而获取更多的有效信息,提升网页的权重。 3、便于团队开发和维护,语义化的HTML可以让开发者更容易的看明白,从而提高团队的效率和协调能力。 标签语义化有助于构架良好的HTML结构,有利于搜索引擎的建立索引、抓取。简单来说,试想在H1标签中匹配到的关键词和在div中匹配到的关键词搜索引擎会吧那个结果放在前面。有利于不同设备的解析(屏幕阅读器,盲人阅读器等)满是div的页面这些设备如何区分那些是主要内容优先阅读?有利于构建清晰的机构,有利于团队的开发、维护

July 13, 2019 · 1 min · jiezi

EnTanMoETM项目周报75711

亲爱的ETM小伙伴: 随着高考、中考、期末考陆续结束 学生们似乎迎来了一年中最轻松的时刻 而对于区块链圈的人来说 却到了最难熬的时期 丰水期来临本是好事 奈何币价起起伏伏 算力再次大幅提升 伊朗加入挖矿大战与国人竞争 矿圈不太平 比特币破万本是喜事 奈何并未迎来加密货币牛市 比特币成一枝独秀 其他币种上涨乏力 币圈不给力 Libra诞生本是美事 奈何美国会议员联名反对 各国监管态度不一 新生事物前途未卜 链圈不顺意 好了,尽管黑夜很漫长,但不妨碍我们向往阳光,来看看ETM在过去一周又有哪些新变化吧。 以下是ETM周报具体内容 项目进展 ETM-Core ETM-Core 资产发行功能,已完成 75%核心代码阶段性梳理,已完成 70%数据库结构优化,已完成 65%ETM-Module 矿机 GUI 客户端,测试中矿机 GUI 客户端跨平台研发,已完成 65%侧链数据库结构优化,已完成 55%ETM-Pay、ETM-ID 已完成 15%ETM-Mobile ETM 钱包移动端研发,已完成 35%ETM-DApp DApp 发布流程优化,已完成 20%ETM-Web WebSite 新增资讯版块日常更新,已上线Wallet v1.6 资产发行界面设计,已完成 60%社区论坛建设,上线前内测中运营进展 社群数据 官方微信社群数量:210+,活跃率 68%官方微信社群人数:57700+官方微信客服好友:14000+官方电报群人数:52000+官方微博关注人数:11100+官方微信公众号关注人数:1900+运营数据 官方微信公众号发布 5 篇图文官方微博发布 15 条微博,阅读量 17000+在金色财经、币世界、陀螺财经、币乎、CSDN、简书、大鱼号、百家号、头条号、知乎号、企鹅号等各内容平台发布文章社群活动 “日拱一卒”:本周知识点为数字证书、数字签名、多重签名、环签名、分布式存储等7个名词,后台回复“日拱一卒”查看本周合辑“圆桌派”话题讨论:# Libra因挑战美元被叫停,加密货币会取代法币吗?#“争分夺秒”:每周二 16:00 社群抢答活动,本期 5 题,每题奖励 5 ETM“Momo答题”:微博每日抢答送出 1 ETM币一周动态 ...

July 12, 2019 · 1 min · jiezi

干货亮相-Staking-生态大会的ETM都透露了啥进展

7月10日,由星球日报主办的大型线下活动Staking 生态大会在北京隆重举行。作为公链3.0项目的代表之一,En-Tan-Mo首席科学家、创始人Aaron Yuan受邀参加此次活动,并在以《Staking的突破——现状、瓶颈与未来》为主题的圆桌分享上发表观点。 Aaron Yuan不仅阐明了En-Tan-Mo应对PoS一系列问题的解决方案,还介绍了En-Tan-Mo在百花齐放的公链项目中的核心竞争力,并透露了En-Tan-Mo主网会在9月份正式发布的利好消息,可谓干货满满。 以下是Aaron Yuan在圆桌分享中的文字实录。 • 请各位嘉宾用一分钟的时间简短的介绍一下自己的业务,以及跟Staking相关的业务进展。Aaron Yuan: 大家好,我是En-Tan-Mo的首席科学家Aaron Yuan。我们项目在发展过程中,很荣幸有诺贝尔奖得主以及我的博导参与到团队中,和我们一起工作。我们在2018年3月份发布了白皮书,上个月的今天,我们有幸作为OKEx Jumpstart的第三个项目跟大家见面。 • 想问一下各位怎么看PoS发展到现在整个的发展趋势,以及大家自己的项目或者说是公链在百花齐放的状态里面有什么核心的竞争力?Aaron Yuan: 首先,我很认同前面几位嘉宾的观点。PoW发展到今天,的确出现了很多的问题,特别是它的算力集中化的问题是很难解决和克服的。因此,引入PoS机制是大势所趋。 当然PoS也有PoS的问题,PoW整个的机制,我们说比较简单粗暴一点,但是PoS需要非常精细的设计,否则权益将会更快速地向超级节点去集中。 我们En-Tan-Mo项目在设计的时候,是反对超级节点的,我们所有的机制——权益因子、优选机制,所有的机制是让更多的人、更多的节点能够参与进来,而不是只是由21个,甚至300个超级节点去完成。 当然,这是在链的设计初期就需要去做数据建模和仿真论证的工作。我们在今年3月份的时候完成了主网的第三次公测,有3000多个节点加入,平均出块速度是3.2秒。3000多个节点其中95%的节点都有参与的机会,这就打破了垄断,能够让更多的节点参与挖矿。 大家知道,去中心化才是区块链的灵魂,算力和权益的累积并不保证安全性,算力和权益的概率分布才保证它的安全性,当所有人的权益接近的时候,这样的一条区块链是非常安全的。 效率是我们要解决的核心问题,但是我们不能把其它的问题丢弃。En-Tan-Mo启动的其实很早,走得不算快,但是走得很扎实,每一步都经过层层论证仿真实验。我们的主网会在9月份正式发布,到时候希望能带给大家一个比较不一样的PoS,我们把我们的机制叫做UPoS。 • 在你们看来,或者说实际业务开展的过程中所面临的在这个生态里面(PoS存在的种种问题)最大的一个挑战是什么,以及你们将或者已经做了一些什么去解决它?Aaron Yuan: 我们现在所谓PoS机制,也主要有两大阵营,一个是超级节点的阵营,一个是反超级节点的阵营,今天很高兴能收获盟友。 区块链项目和以前传统的互联网项目从开发上来说,是有一点的区别的,区块链项目当你发布了之后其实是不应该去做大的调整和修改的,由社群决定比较好。当你发现原始设计存在一定问题的时候,比如说漏洞,或者说大的冲击,如果你想调整,最大的可能是分叉,这对链本身影响是非常大的。 因此,在设计初期就要思考这样的问题,正如王梦蝶刚才提出来的几个问题,第一个是投票率不高,第二个是Staking会比较集中,第三个安全性的问题。 在去年三月(En-Tan-Mo发布的)白皮书里面,(En-Tan-Mo团队)提出了这个问题,并且给出了解决的路线。在上个月,我们在星球日报发布了我们的黄皮书,具体解释了我们怎么解决每一个问题的,也非常欢迎大家有兴趣的去看一下文章,欢迎跟我们做讨论。我大概讲一下我们的想法和解决思路。 第一个是投票率不高,核心的原因是因为投票者是在等待超级节点、在等待收益利润,这个链除了发布挖矿收益以外,这两部分是割裂的。(En-Tan-Mo)投票收益由两部分组成,只要你参与投票,你投的节点入选就有收益;还有一部分非固定性收益,这个是不固定性的,每次都有大奖产生。 第二点讲到Staking过于集中化的问题,我们看到很多PoS的公链投票之后有前100名或者前21名入选。我们是根据概率来的,如果我手上只有千分之一的票,我们设想我们只有100个席位,那么,前面的票在大户手里,后面的票在参与者手里。我们还设立了权益因子,也通过这样的因子去调整,最后根据实际的情况去做调整。 这种充分的去中心化带来的问题就是效率的问题,因为当超级节点效率更好一些,所有的节点(参与)效率会更差。我们用优选机制,这个节点每一次被入选挖矿和实际出块会有一个比例,这个比例会参与到你下一次竞选当中去,我们用优选机制来处理,是链上自动去远程而不是人工做调整。 DPoS的超级节点,始终集中在少数节点是容易被攻击的。我们引入了混沌排序的概念,提前预告一点,基于En-Tan-Mo本身的特点,我们会在8月份发布一个时间塔,它是一个区块链上的真随机数发生器,这大概就是我们之前预计的情况和我们实际实现的路径。 我们把去年3月份白皮书里面所公布的所有技术要点全部实现了,我们会在9月份正式把主网发布出来。这是我的观点,谢谢大家。 • 我们每人一句话展望一个市场或者给自己做一个广告。Aaron Yuan: 很高兴能来参加Staking大会,感谢王梦蝶的邀请,感谢在这里认识很多新的朋友,谢谢大家。

July 12, 2019 · 1 min · jiezi

Staking-生态大会后大佬们都去哪儿了

7月10日刚刚结束的Staking Con生态大会好不热闹,区块链行业头部媒体Odaily星球日报与区块律动做东,邀约矿池、钱包、投资机构的大佬们齐聚一堂。主题演讲一场接一场,圆桌分享上更是观点如珠,击中亟需更新的脑细胞。 为什么今年PoS/DPoS会火? 公链百花齐放,项目方核心竞争力是什么? PoS探索阶段,区块链项目面临的挑战是什么? 会上大佬们滔滔不绝,台下观众也紧追大佬发言听得餮足,一整天的Staking直播已经让人食髓知味,那么大家又问了,链圈大佬们下一站,去哪儿? • 19:00,人群再次聚集。 这是En-Tan-Mo共识之夜, 人头攒动,言语如织。 En-Tan-Mo共识之夜由公链项目En-Tan-Mo、Odaily星球日报以及区块律动联合主办,作为登陆OKEx交易所以来的第一场线下交流活动,En-Tan-Mo希望通过本次活动与区块链生态各节点进行深入沟通,因此特地邀约Algorand 、Cardano以及Cosmos、火币钱包等众多Staking周边生态大咖来到现场。 En-Tan-Mo的故事:公链初心不变作为活动主办方之一,En-Tan-Mo创始人Aaron Yuan上台发表讲话。 “En-Tan-Mo,灵感来源于Entente (联盟)、Transaction (交易)和 Mobius (莫比乌斯),是首个提出并实现SHD完备性的3.0底层公链项目。基于纳什均衡和价值均衡传递理论,ETM的科学家将PoW与DPoS改进并结合,创造性地提出了UPoS共识机制,实现了中心化、安全性以及高性能三者的兼容,解决了‘不可能三角’问题,即SHD完备性。” 随着区块链进入3.0时代,百花争鸣局面大开,Aaron表示,“我与我的团队赶上了这样一个好的时代,他们在自己的专业上都颇有建树,我们的价值观和理念非常契合,并且有着共同的理想——那就是实现中本聪最初所构想的去中心化世界。” 与诺奖结缘是En-Tan-Mo此前所有努力的回报,Aaron对此满怀感激。他在现场表示了对萨金特、格拉肖两位教授的诚挚感激。 “有了两位诺奖得主的加入,未来的路,我们走得更有信心。” 诺奖得主的加入,并不意味着前行的障碍就此消除,En-Tan-Mo选择全力以赴应对所有坎坷。从2017年7月项目正式启动,走过全球产品发布、全球巡演,再走过三轮全球测试。如今的En-Tan-Mo登陆国内三大主流交易所之一OKEx,往“去中心化世界”这个目标不断前进。 就在白天的Staking生态大会上,Aaron正式公布项目接下来两大重要节点。 第一件大事是,“我们会在8月份发布时间塔。”据了解,时间塔基于混沌算法的随机源,依赖ETM的纳什均衡体系,通过一系列设计单个输入参数的改变,无法保证最终输出结果向其期望的方向倾斜,从而得到一个去中心化的、可靠的随机源。 第二件大事也一直为用户所关注,“我们把去年3月份白皮书里面所公布的所有技术要点全部实现了,我们会在9月份正式把主网发布出来。” 一直以来,En-Tan-Mo以中本聪精神作为顶层建筑指引前行,在技术的创新与打磨中低调前行。以如此区块链的热忱以及精于打磨技术的工匠气质,才获得了两位诺奖得主的青睐,也才能在登陆交易所之后获得市场的认可、社群用户的认同。 当下公链生态中百花齐放,En-Tan-Mo选择苍劲有力地继续写自己的故事。 共话区块链:凝聚声音与共识Aaron发表讲话之后,现场进入自由交流环节。 白天连篇的观点输出与输入之后,参会嘉宾依然精力充沛,热情地与业内伙伴就区块链的发展与应用等话题侃侃而谈,现场逐渐进入热烈的交流之中。 区块链技术进入加速快车道,大众对于区块链的认识也在不断地迭代和升级,Staking经济、IEO、去中心化组织,诸如此类的话题在人头攒动中发酵。 在这里,感受交流的力量,听见共识接榫的声音。 难忘今宵:共识之夜宣告结束作为本次活动的主办方之一,En-Tan-Mo在活动过程中安排了多轮惊喜抽奖。连续几轮激动人心的抽奖环节,现场的气氛逐渐染上几分紧张与期待。 最终,活动现场五位嘉宾分别获得En-Tan-Mo送出的一二三等奖。其中,一位幸运女生获得终极奖励——5000枚ETM币,心满意足抱得大奖归。 随着大合照影像留存,En-Tan-Mo共识之夜正式宣告结束。 守望区块链:前路坦荡本次活动重磅邀请众多链圈知名人士,实现了区块链底层技术的交流与探讨,也传递了数字货币的信仰与初衷 走过风雨十年的区块链行业,即将迎来崭新的十字路口,它将何去何从? 我们无法给出准确的答案,短短几个小时共识之夜的交流也无法给出明确的发展路径。但推动业内交流,En-Tan-Mo共识之夜对于区块链行业来说意义尤为重大。 区块链前路开阔坦荡 风物长宜放眼量 我们不妨在不断凝聚的共识中眺望

July 12, 2019 · 1 min · jiezi

网站维护费用的那些事你知道多少

很多企业做网站找供应商的时候都会牵扯到一个网站续费问题,当问到网站为什么还需要续费的时候,各个网络公司告诉客户是网站维护费用,细心点的网站销售都会告诉客户网站维护费用由哪些组成,但是依然有很多客户处于朦胧状态,这里十二君再给大家普及下一般网站维护费用由哪些组成。 ①域名注册费用 只要做网站都会牵扯到域名续费,一般域名价格首年价格为16-65之间,具体多少因注册商与域名后缀不同而价格不同,各个网络公司一般收费为100-200元/年,为什么比域名注册平台高,因为域名注册平台仅包含注册,不含域名解析等服务,需要自助解析,网建公司有服务在内所以价格略微高于域名注册平台。 ②网站空间费用/服务器费用 网站上的图片文字需要有个储存的地方,与电脑硬盘存储一个道理,比如你的电脑里可能会存储很多小电影,美女图片一样。网站空间/服务器是需要租赁的,一般来说网站空间费用/服务器费用为几百元到几千元不等,也是因空间商不同、空间/服务器配置不同导致的价格不同。网建公司卖的价格略高于空间商,理由与域名费用一样。 ③网站内容更新的人力费用 网站产品更新、新闻发布、图片处理都是需要人力服务的,所以会产生费用,值得一提的是有些客户一年到头没有什么更新,那么网建公司轻松,小赚一笔。而有些客户频繁更新,那么对于网建公司而言,其实是亏本的。 ④网站bug修复/程序修改费用 网站上线之后,可能会遇见之前做网站的时候没注意导致的bug,那么这个修改也会产生人力成本,程序小调整也是一样,甚至网站空间问题导致的网站打不开依然是需要人力处理的,所以就产生了费用。 ⑤技术咨询费用 很多时候成本是浪费在沟通技术咨询上,经常遇见客户改一个内容只需要几分钟,但是跟客户沟通可能就需要几倍的时间,这个成本是较高的。为什么会这样,还是因为大多数客户互联网意识还不强,很多不了解。因为不懂,所以并不能直接高效的向你表达需求,那么你需要耐心地询问清楚,才能做出修改,所以工时会拉长。这里温馨提示广大客户:不要那么催网建公司,每天网建公司都有新订单,需要做新单,已经上线网站的客户,一般都会进行排单,比如每天下班前会修改掉,否则来一个客户立马修改只会影响效率。比如十二君公司对于网站修改的问题,一般都是当天所有提出网站修改的客户意见汇总,整理成一个个word文档,两个工作日内会改掉完成,然后再给客户回一个文档。 最后:当然关于网站维护费用组成还可能会因各个网建公司情况不同,会有些微调,具体就需要看企业主在哪家做网站了。---PS:本文出自成都多享科技有限公司

July 12, 2019 · 1 min · jiezi

小程序给餐饮行业带来第二春

餐饮行业小程序无非有一下几个优点:一、自助点餐完美的浏览体验用户可以随时查看商家信息,随时查看排队,预约信息。随时查看优惠,随时点餐,点外卖,排队。使用最前沿的小程序技术,近乎完美的用户体验让餐厅和客户互动更便捷友好。 二、节省人力,物力服务员掌上工作台、让服务员爱上工作。服务员使用手机即可实现上菜-划菜-开台-点餐-订单审核-收桌叫号。随时查看餐厅的公告,最新菜品,销售提成等操作简单,快速上手。 三、自己的平台拥有自己的外卖平台深度解决外卖问题。通过小程序即可进入点餐页面,随时点餐对接第三方配送,自动接单打印,自动配送杜绝平台抽成,从现在开始。 四、随时掌控实时的数据分析,随时随地掌握餐厅运营情况。移动端数据分析,随时查看餐厅实时数据、经营情况、提高管理效率智能分析餐厅营收,综合数据报表,第一时间发现运营异常信息。 五、会员营销会员直销多种营销功能,为您提供最简单的营销体验在餐前、餐后都可以对客户进行优惠促进用户到店消费,提升餐厅营业额。 除了已经推行成功的出行领域,餐饮点餐有可能是小程序最佳的线下使用场景之一。微信正在重新调整部分入口,一波新的流量机会可能来了。继「看一看」新增「好看」栏目,近期,有用户发现,微信正在成都地区内测新的功能插件「附近的餐厅」。使用小程序点餐也极大地提高了商家的接待效率,不仅省去了前台人工,而且线上提前预约下单,可以有效拉低后厨的订单处理峰值。无论是到店扫码点餐,还是线上点餐,商家都可在支付后发送优惠券,吸引用户二次到店。 如今,微信以社交关系为基础的附近的餐厅又卷土重来。对于用户而言,点评餐厅等信息好友可见尚无不可,但如果涉及到酒店住宿、景点、出行等领域,肯定会引发巨大恐慌与争议。微信的新功能,也将触及到一大批用小程序做本地化美食推荐的小程序。一旦微信下场来做,这类小程序开发者的机会就没了。         看过上面的介绍后相信大多数小伙伴们对于餐饮微信小程序怎么做都会有一定的认识了。现而今我们大家都清楚餐饮业在当前最为火爆,然而面对电商的冲击,使得线下的服务有些明显大不如前。但小程序的发展,吸引更多线上客户到线下消费,这无疑是实体店的春天。尤其是餐饮业更是可以借此得到更多的利处。   ---本文出自成都多享科技有限公司

July 12, 2019 · 1 min · jiezi

EnTanMo隆重亮相Staking-生态大会

7月10日,由星球日报、区块律动联合主办的Staking 生态大会在北京召开。En-Tan-Mo创始人Aaron Yuan作为受邀嘉宾,与 Algorand、Cardano、Tezos、Dash、NEM等知名PoS 项目的创始人、负责人一道亮相此次活动。 会上,Aaron Yuan参加了以《Staking的突破——现状、瓶颈与未来》为主题的圆桌分享。 提及自己项目在百花齐放的Staking机制中的竞争优势,Aaron Yuan表示,En-Tan-Mo项目在设计的时候,就是反对超级节点的,En-Tan-Mo所有的机制都是让更多的人、更多的节点能够参与进来,回归区块链去中心化的本质。 对于PoS机制生态面临的挑战,Aaron Yuan认为,目前投票率不高、Staking比较集中、安全性都是PoS存在的问题。 Aaron Yuan介绍,通过投票收益的固定与非固定的设置、概率和权益因子、优选机制、混沌排序等设计调节投票收益、节点入选概率以及安全保障等。 同时,Aaron Yuan还在圆桌分享中透露,En-Tan-Mo主网会在9月份正式发布;8月份则会发布一个时间塔,它是一个区块链上的真随机数发生器。 据悉,此次活动是数字加密世界第一场以 Staking 生态为主题的大型线下活动。 活动中,En-Tan-Mo作为区块链3.0的代表之一首次在国内公开活动现身,并通过圆桌分享发出自己的声音,体现了En-Tan-Mo在行业内的影响力与实力,也进一步让公众对En-Tan-Mo有了更深刻的认识。 以此为契机,En-Tan-Mo将砥砺前行,力争通过技术和商业价值成为行业标杆。

July 11, 2019 · 1 min · jiezi

EnTanMo重大节点公布今年8月发布时间塔9月正式上线主网

7月10日,Odaily星球日报和区块律动联合主办的Staking生态大会上,En-Tan-Mo首席科学家Aaron Yuan公布了今年下半年En-Tan-Mo的两个重要发展节点。 第一,En-Tan-Mo将于今年8月发布时间塔。据悉,时间塔基于混沌算法的随机源,依赖ETM的纳什均衡体系,通过一系列设计单个输入参数的改变,无法保证最终输出结果向其期望的方向倾斜,从而得到一个去中心化的、可靠的随机源。 此外,Aaron表示“我们把白皮书里面所公布的所有技术要点全部实现了”,今年9月份En-Tan-Mo主网正式上线。

July 11, 2019 · 1 min · jiezi

HTML语义化

html语义化的好处 有利于SEO,搜索引擎根据标签来确认上下文和各个关键字的权重。有利于阅读,在样式丢失的情况下也能呈现清晰的结构。有利于机器解析,盲人阅读器等根据语义解析有利于开发和维护,语义化使html代码结构更清晰,更具可读性常见的语义化标签: em:斜体,强调语气aside:侧边栏,具有导航性质的模块内容nav:一般为给当前页面内容提供导航链接、目录、索引等article:表示独立的结构,或者可复用的内容abbr:表示缩写,title属性为完整内容header:通常表示网页的头部内容,包括搜索框、logo、标题组等hgroup:对网页或者区段(section)的标题组合hr:表示故事走向的转换或者话题的转换时的水平分割线,如果是普通的水平线页面效果,用css呈现blockquote:段落级的引述,内部包含左右缩进和内边距q:表示行内应用,对内容自动加引号cite:表示作品名的引述main:表示页面的主要内容,一个页面只能出现一次footer:表示页面或文档的页脚,一般包含作者、版权、联系地址等figure:表示与主文章相关的图像、插图、图表、代码片段等figcaption:表示figure的说明strong:表示强调,和em的差别有:em表现为斜体,strong为加粗,em为强调内容,strong为语气更强的强调内容pre:表示内容我们已经经过特殊排版了,不希望浏览器帮我们自动排版samp:表示实例输出code:表示内容为代码time:表示日期或时间,有datetime属性表示内容的日期或者时间,如果没写datetime,在内容中一定要有日期时间dfn:表示对特殊术语的定义

July 11, 2019 · 1 min · jiezi

JS复习JS中事件的捕获与冒泡

https://juejin.im/post/5aab87...

July 11, 2019 · 1 min · jiezi

CSS水平或垂直居中技巧

前言css水平和垂直居中是一个更古不变的话题,它常常出现在优美的网页上以及各大前端面试当中。说来惭愧,在两年前面试的时候,我完全不知道如何做到水平和垂直均居中的方法,那场面别提有多尴尬了(ps:特想找个地洞钻进去)。。。时隔两年,对于这个问题算是有一些了解了,现做个小小的整理,也算是对自己学习的总结。 注:文中例子没写明html代码时,使用的是下面结构: <div class="example example14"> <div class="con"> 超级好用超级放心 <a href="https://tinypng.com/" target="_blank">在线压缩图片</a> <span>压缩完可以 </span> </div></div>只是类名会有所不同。 1、Line-height适用情景:单行文字(垂直居中)原理:将单行文字的行高设定后,文字会位于行高的垂直中间位置。html: <div class="example">Lorem ipsam.</div>css: .example{ width: 400px; background: #afddf3; line-height: 50px;}效果: 2、Line-height + inline-block原理:将多个元素或多行元素当成一个行元素来看待,所以我们必须要将这些数据多包一层,并将其设定为inline-block。由于inline-block在不同浏览器会有空隙产生,因此设定父元素font-size:0来消除,从而达到完美的垂直居中。css: .example2{ width: 400px; border: 1px solid #dcdcdc; line-height: 100px; font-size: 0;}.example2 .con { display: inline-block; line-height: 2; vertical-align: middle; width: 300px; font-size: 15px; background: #afddf3;} 3、:before + inline-block原理::before 伪类元素搭配 inline-block 属性的写法应该是很传统的垂直居中的技巧了,此方式的好处在于子元素居中可以不需要特别设定高度,我们将利用:before伪类元素设定为100%高的inline-block,再搭配上将需要居中的子元素同样设置成inline-block性质后,就能使用vertical-align: middle来达到垂直居中的目的了,此方式在以往其实是个非常棒的垂直居中解决方案,唯独需要特别处理掉inline-block元素之间的4-5px空间这个小缺陷,不用怕,设置父元素font-size: 0,子元素font-size: 15px即可。css: .example3 { margin-top: 10px; width: 400px; height: 150px; font-size: 0; border: 1px solid #dcdcdc;}.example3::before { content: ''; display: inline-block; height: 100%; width: 0; vertical-align: middle;}.example .con { width: 300px; font-size: 15px; background: #afddf3; display: inline-block; vertical-align: middle;} ...

July 11, 2019 · 3 min · jiezi

模块中间的拖拽定位不能做bug无法和自定义顺序选项相结合

1.参考网上已经有的库--------------------网址:http://www.wheelsfactory.cn/#...2.另一个拖拽库--------------------------------.https://www.npmjs.com/package... <transition-group> <div :key="1"> one </div> <div :key="2"> two </div> <div :key="3"> three </div></transition-group>

July 11, 2019 · 1 min · jiezi

效果实现在照片上面显示一段文字最多两行多余部分用省略号表示

思路:照片上面显示文字,怎么实现呢?将照片作为div的背景呀! 效果图: html: <div class="outer"> <!-- 多行文本溢出显示 --> <p class="text">我是一段很长的文字我是一段很长的文字我是一段很长的文字我是一段很长的文字我是一段很长的文字我是一段很长的文字我是一段很长的文字我是一段很长的文字</p> </div> <!-- 单行文本溢出显示 --> <p class="oneline">我是一段很长的文字我是一段很长的文字我是一段很长的文字我是一段很长的文字我是一段很长的文字我是一段很长的文字</p> <!-- input溢出显示 --> <input type="text">css <style> .outer { /*将图片作为背景*/ background-image: url(./imgs/img.jpg); /*必须设置div的高度,图片才能显示*/ height: 600px; width: 600px; background-repeat: no-repeat; /*图片填满div*/ background-size: 100%; position: relative; }/* 多行文本溢出隐藏 */ .text { position: absolute; top: 200px; left: 50%; margin-left: -100px; width: 200px; color: hotpink; font-size: 1.2em; /* 将元素作为box伸缩盒子 */ display: -webkit-box; /* 设置文本排列方式 */ -webkit-box-orient: vertical; /* 设置文本行数限制 */ -webkit-line-clamp: 2; /* 溢出部分隐藏 */ overflow: hidden; /* 文本溢出的部分显示省略号 */ text-overflow: ellipsis; }/* 单行文本溢出隐藏 */ .oneline { width: 400px; /* 不换行 */ white-space: nowrap; /* 溢出隐藏 */ overflow: hidden; /* 溢出的文本用省略号显示 */ text-overflow: ellipsis; }/* input的溢出显示省略号 */ input { /* 对于input只需要这一行 */ text-overflow: ellipsis; } </style>单行文本溢出显示省略号/* 单行文本溢出隐藏 */ .oneline { width: 400px; /* 不换行 */ white-space: nowrap; /* 溢出隐藏 */ overflow: hidden; /* 溢出的文本用省略号显示 */ text-overflow: ellipsis; }多行文本溢出显示省略号/* 多行文本溢出隐藏 */ .text { width: 200px; /* 将元素作为box伸缩盒子 */ display: -webkit-box; /* 设置文本排列方式 */ -webkit-box-orient: vertical; /* 设置文本行数限制 */ -webkit-line-clamp: 2; /* 溢出部分隐藏 */ overflow: hidden; /* 文本溢出的部分显示省略号 */ text-overflow: ellipsis; }input 溢出显示省略号/* input的溢出显示省略号 */ input { /* 对于input只需要这一行,因为input本身就不会换行,本身就会溢出隐藏 */ text-overflow: ellipsis; }

July 10, 2019 · 1 min · jiezi

JS事件冒泡与捕获

事件冒泡与事件捕获事件冒泡和事件捕获分别由微软和网景公司提出,这两个概念都是为了解决页面中事件流(事件发生顺序)的问题。 如下:假设三层div都有事件监听,这时我们点击的小的蓝方框,事件执行的顺序是怎么样的呢 <div id="s1" style="height: 400px;width: 400px;border: 1px solid red">红 <div id="s2" style="height: 200px;width: 200px;border: 1px solid yellow"> 黄 <div id="s3" style="height: 100px;width: 100px;border: 1px solid blue">蓝</div> </div></div> 事件冒泡微软提出了名为事件冒泡(event bubbling)的事件流。事件冒泡可以形象地比喻为把一颗石头投入水中,泡泡会一直从水底冒出水面。也就是说,事件会从最内层的元素开始发生,一直向上传播,直到document对象。因此在事件冒泡的概念下在div元素上发生click事件的顺序应该是div -> body -> html -> document 事件捕获网景提出另一种事件流名为事件捕获(event capturing)。与事件冒泡相反,事件会从最外层开始发生,直到最具体的元素。因此在事件捕获的概念下在div元素上发生click事件的顺序应该是document -> html -> body -> div -> div w3c 采用折中的方式,制定了统一的标准——先捕获再冒泡。addEventListener第三个参数默认值是false,表示在事件冒泡阶段调用事件处理函数;如果参数为true,则表示在事件捕获阶段调用处理函数。 测试事件冒泡-点击蓝色 s1 = document.getElementById('s1') s2 = document.getElementById('s2') s3 = document.getElementById('s3') s1.addEventListener("click",function(e){ console.log("红 冒泡事件");//从底层往上 },false);//第三个参数默认值是false,表示在事件冒泡阶段调用事件处理函数;如果参数为true,则表示在事件捕获阶段调用处理函数。 s2.addEventListener("click",function(e){ console.log("黄 冒泡事件"); },false); s3.addEventListener("click",function(e){ console.log("蓝 冒泡事件"); },false); 测试事件捕获-点击蓝色s1.addEventListener("click",function(e){ console.log("红 捕获事件"); },true); s2.addEventListener("click",function(e){ console.log("黄 捕获事件"); },true); s3.addEventListener("click",function(e){ console.log("蓝 捕获事件"); },true); ...

July 10, 2019 · 1 min · jiezi

最近项目中使用到的一些技术

项目需求vue项目,后端获取的n条数据中的名称,前台展示,并要求点击后可直接修改这个效果 1.使用input标签,但是:value和:model使用有问题 2.给按钮绑定enter事件,修改成功后光标依旧在闪,用户体验不好,需解决一<div class="lf"> <input type="text" class="noname" :title="item.show_name" :value="item.show_name?item.show_name:'未命名视频'" @keyup.enter="search($event,item)" @blur="search($event,item)" /></div>search: function (event, item) {//保存视频名称 let that = this let obj = { task_id: item.id, show_name: event.currentTarget.value } that.$ajax.post("/test", obj).then(res => { if (res.data.rtn == 0) { Message({ type: 'success', showClose: true, message: '命名成功!', duration: 3500 }) event.srcElement.blur() //主动使按钮失去焦点 } })},结论1.使用search($event)方法贼强大,比那些$refs等获取的跟强大(个人使用感觉),获取输入的字符很方便2.主动使按钮失去焦点如代码片段中注释所写 项目小需求 1.vue路由跳转后新打开页面 这个百度都能搜到 let { href } = this.$router.resolve({ //打开新窗口 path: "/new/admaking/production", query: { } }) window.open(href, '_blank')

July 10, 2019 · 1 min · jiezi

火币-websocket-获取-k-线数据和其它数据-API

火币 websocket 获取 k 线数据,和其它数据 API火币官方文档地址: https://huobiapi.github.io/do...pako(解压gzip): https://github.com/nodeca/pako坑死,接火币 websocket 地址 wss://api.huobi.pro/ws 的时候接到怀疑人生,怎么都无法建立连接,一度以为自己没有像其它 get/post 接口那样传入该传的参数,又以为是 wss 走的是 SSL 通道,所以才没能建立连接,还以为是需要服务端转接一下。 但,最后的最后,竟然发现是因为地址的问题,这个地址根本接入不了,至少我这边是接入不进去。 后来换这个地址: wss://api.hadax.com/ws就顺利的接入了 火币 websocket 规则先建立连接发送订阅请求,这个官方文档有说明火币服务器返回订阅成功与否的回馈信息如果成功就定时发送 gzip 压缩后的数据,解压 gzip 你需要 pako https://github.com/nodeca/pako我们自己客户端这边接收数据,并解压数据,才能获取到真正的 json 数据自己做前端该做的相应操作,压入数据,展示数据什么的。但,在这个期间,还有一个动作需要执行,火币服务器会每隔 5 秒,向客户端发送一条 ping 数据,客户端接收到这种信息的时候,需要 send 一条对应的 pong 数据,内容是 ping 的数据体(相应的数据格式如下),如果服务器在发送两条 ping 数据后没有收到 客户端返回的 pong 数据,火币服务器就会关闭连接。 关于其它信息的获取,查看官方文档关于 websocket 的说明就可以了。 // 服务器发送的 ping 数据{ ping: 1562741680416 }// 客户端返回服务器的 pong 数据{ pong: 1562741680416 }执行代码// K 线相关let hburl = 'wss://api.huobipro.com/ws'; // 实时币种价格let haurl = 'wss://api.hadax.com/ws';let requestK = { // 请求对应信息的数据 req: "market.bchusdt.kline.1min", id: "bchusdt", from: Math.round(new Date().getTime()/1000) - 60, to: Math.round(new Date().getTime()/1000)};let subK = { // 订阅数据 sub: "market.bchusdt.kline.1min", id: "bchusdt"};let socketK = new WebSocket(haurl);socketK.onopen = function () { console.log("connection establish"); socketK.send(JSON.stringify(subK)); socketK.send(JSON.stringify(requestK));};socketK.onmessage = function (event) { let blob = event.data; let reader = new FileReader(); reader.onload = function (e) { let ploydata = new Uint8Array(e.target.result); let msg = pako.inflate(ploydata, {to: 'string'}); handleData(msg); }; reader.readAsArrayBuffer(blob, "utf-8");};socketK.onclose = function () { console.log('connection closed');};// 处理接收到的信息function handleData(msg) { let data = JSON.parse(msg); if (data.ping) { // 如果是 ping 消息 sendHeartMessage(data.ping); } else if (data.status === 'ok') { // 响应数据 handleReponseData(data); } else { // 数据体 console.log(data) }}// 发送响应信息function sendHeartMessage(ping) { socketK.send(JSON.stringify({"pong": ping}));}function handleReponseData(data) {}

July 10, 2019 · 1 min · jiezi