当前位置:首页 » 编程软件 » 脚本ua

脚本ua

发布时间: 2022-08-19 11:14:20

1. jQuery $(window).scroll事件出现问题

web前端开发 20 年变迁史,让我们来看看这20年里,web前端究竟经历了哪些变革,web前端在这20年里又有哪些突破和成就,怎么样看待这20年的web前端开发!

1990年,第一个Web浏览器诞生,而WWW的诞生直接拉开前端史的序幕。

从静态页面到Java,从依赖后端到自主开发,前端开发者从不被重视的“页面仔”逆袭为如今很多前端工程师的薪资比后端还高,从前端技术由国外开发者主导到如今国内自主产生的小程序技术,我们走了20年。

了解web前端:http://www.cnite.cn/qianan/

作者 | 司徒正美

责编 | 伍杏玲

1990 年,第一个Web浏览器的诞生;1991 年,WWW诞生,这标志着前端技术的开始。

在这将近20年的前端发展史中,我们经历了从最早的纯静态页面,到Java跨时代的诞生;从PC端到移动端;从依赖后端到前端可自由打包开发;从早期的网景Navigator浏览器到现在各家浏览器百花齐放……

我们经历了前端的洪荒时代、Prototype时代、jQuery时代 、后jQuery时期、三大框架割据时代,这其中均是由国外开发者主导,直到如今的小程序时代,才是中国开发者独创的。

这是漫长的技术储备下的成果,最终促成了良好的技术成长收获。期间的前端发展之路,崎岖艰难:

洪荒时代(1990~1994年)

在1990~1994年期间,前端界发生的大事有:WWW(World Wide Web)的诞生、浏览器的诞生、Java的诞生,没有专业的前端,页面全是由后端开发的。

1990年,万维网之父蒂姆·伯纳斯-李(Tim Berners-Lee)在NeXT电脑上发明了第一个Web浏览器。

1991年8月6日,Tim在alt.hypertext新闻组贴出了一份关于World Wide Web的简单摘要,这标志了Web页面在Internet上的首次登场。

最早的Web主要被一帮科学家们用来共享和传递信息,全世界的Web服务器也就几十台。由于仅是用来传递信息,从可视化方式或从传递数量上看,仅比电报强一点点。

当时还没有Java,用的是纯静态的页面。

1993年,CGI(Common Gateway Interface)出现了,人们可以在后端动态生成页面。

Perl由于跨操作系统和易于修改的特性成为CGI的主要编写语言。当然,CGI也支持其他支持标准输入输出和环境变量的语言编写,比如Shell脚本、C/C++语言,只要符合接口标准即可。

但显然,页面的内容更新完全由后端生成,这带来一个明显的缺憾:每次更新都要整页刷新,加上早期的网速情况,这个操作是非常慢的。因此针对这情况,人们从多方面着手改进:编写语言的升级、浏览器的升级、HTML的升级。

1994年,网景公司成立,发布了第一款商业浏览器Navigator。自从这款浏览器面世后,微软推出IE浏览器。虽说有竞争才有发展,但这也埋下了Java分裂的种子。

(1994 年,网景浏览器的截图)

同年,PHP诞生。PHP能将动态的内容嵌入到HTML中,提升了编写页面的效率与可读性,其性能也比一般的CGI高。PHP的界定符、循环语句等的发明,深刻影响了后来的ASP、JSP,乃致后来的Java前端模板引擎。

1994年10月,W3C小组也成立了,他们负责HTML的发展路径,其宗旨是通过促进通用协议的发展。

待这一切就绪后, Java于1995年诞生了。

传闻,网景工程师布兰登·艾克(Brendan Eich)只花了10天时间设计出 Java 语言,近乎上帝七日创造世界那么高效。但也因为工期太短的缘故,导致许多瑕疵,因此一直被正统传序员所嫌弃,直到Ajax的出世,才让人们找到理由忍受它的畸形。早期的浏览器都配有一个选项,用来禁止Java语言运行。

Java主要语言特征[1]:

借鉴C语言的基本语法;

借鉴Java语言的数据类型和内存管理;

借鉴Scheme语言,将函数提升到"第一等公民"(first-class citizen)的地位;

借鉴Self语言,使用基于原型(Prototype)的继承机制。

时下,静态语言大行其道,类与接口被证明是构建大工程的最佳实践,人们想不出没有类的语言如何编写业务。因此当时的微软也打造了另一门运行于浏览器的语言——VB。

如果继续细探Java的能力,你会发现它早期真的非常空洞,一门没有灵魂的语言,没有包管理机制,也没有像Java与C++那样的打辅助用的SDK,内置的方法也屈指可数。比如说数组方法,早期只有push、pop、shift、unshift、splice、slice、sort、reverse、concat、join等操作。动态调用方面,Function的apply、call操作还没有出现!

早年的偷懒,导致后来不得不补课:到了2019年,数组上的原型方法,是原来3倍。

除了方法缺乏,还有性能问题,大家讨论用eval还是Function,用哪种循环方式,用parseInit还是~~,就是为了那一点点的性能提升。例如jsperf.com,就是一个专门研究Java性能的网站。

因此Java诞生后,其两大任务就是完善语言特性与提高性能。这两座大山分别由着名的prototype.js与jQuery来搬掉。

在搬掉之前,前端界还有一个曲折实践——第一次浏览器战争,并由其发展而来UA嗅深技术。

浏览器战争(1994~2005年)

浏览器战争一共打了三场,IE浏览器vs网景浏览器、IE浏览vs火狐浏览器、IE浏览器vs谷歌浏览器。

第一场浏览器之战打得尤其激烈。

微软的IE浏览器发布于1994年,但此时的网景已经占领绝对优势。微软在落后的情况,反编译Netscape的源码,推出IE与J。但是由于Bug非常多,大家不愿意为IE开发网站,因此发掘出UA,专门过滤掉IE浏览器。

UA即Navigator.userAgent ,是用一个字符串来记录用户当前运行在什么操作系统与浏览器中。当前IE3的UA是这样的:

Mozilla/2.0 (compatible; MSIE 3.02; Windows 95)

程序判断UA信息,假如发现当前运行的环境是IE浏览器的话,就提示用户用网景浏览器打开。因此微软不得不让自己的UA尽量伪装成网景的UA,欺骗用于检测UA的脚本,达到IE浏览器可以跑这些网站的目的。

最终,第一次浏览器之战以微软胜利,Netscape被美国在线收购,而落下帷幕。

第一次浏览器战争年代非常久远了,但其结局告诉我们,其实技术强弱并不重要。那时技术保护并没有这么重视,否则微软的行为可能会被告(谷歌的openSDK仅抄袭几十行代码,被Oracle公司诉讼赔88亿)。

第一次浏览器战争带来了一个问题:尽管当时有ECMA-262(Java规范文档)与W3C(HTML与CSS的规范文档),微软却没有照规范来实现Java、HTML与CSS,导致前端兼容问题的诞生。所以CSS Hack、浏览器判定、特性侦测,这些技术就应运而生。

这个时代最着名的人物是Dean Edwrad,他是最早的近乎完美解决事件绑定的兼容性大神,其addEvent()内置于jQuery最早的版本中。jQuery的作者John Resig看到其超强的技艺,最后放弃推出大而全的框架,专攻选择器引擎。

Dean Edwrad的IE7.js、IE8.js是早期处理浏览器兼容的良药,可以说是一切Polyfill[2]的起源。他写了大量的Hack, 比如在IE如何测量元素的宽高,许多操作DOM的兼容。

这时期太早,中国基本没有参与这次浏览器战争。

Prototype时期(2005~2009年)

Prototype是Sam Stephenson写的一个非常优雅的Java基础类库。他是Ruby的大牛,因此Prototype的许多方法名都是来自Ruby界。

Sam Stephenson最大的贡献是发掘了Prototype与创造了Function.prototype.bind,在数组上也写了一大堆方法,其中许多被标准化了。

同期的MooTools也是Prototype的方法,当时,大家还在前端论坛为这个争吵。还有前端工程师喜欢在当时很出名的前端聚集地——蓝色理想(现沦为设计师网站)上,讨论如何扒脚本、分享弹层、日历等小组件的技术,这在当时已经是非常了不起的事。

Prototype当时还解决两大问题:动画特效与Ajax请求。动画特效是由aculous提供,我们现在所熟知的各种缓动函数,各种特效的命名与大致的运行形态,都是由aculous确定下来的。

在早期,谷歌就开始使用iframe实现页面刷新。

2005 年2月,杰西·詹姆士·贾瑞特(JesseJamesGarrett)发表了一篇名为《Ajax:一种Web应用程序开发的新方法》的文章后,Ajax被挖掘出,大家才开始重视起这技术的应用。

例如IE下的ActiveXObject("Microsoft.XMLHTTP"),这是IE创建Ajax引擎的。假如当时有工程师开发出一个核心库,如果不包含Ajax的封装,便不好意思发布出来。

一些Ajax书藉

当时前端开发模式是选择一个核心库,找一些组件,或者扒别人的脚本进行开发

Prototype的源码挺好理解的,代码量也少,只有5000多行,里面的每个方法也很易扒出来,因此一些大公司总有高手能创造自己的Prototype。

但前端开发还是离不开后端,因为前端没有模块机制,当时我们需要用PHP进行打包。打包是雅虎34条军规之一,可以减少请求数。打包的同时也可以进行混淆,防止代码小偷来窥探。

N年前,前端面试必问的题目:

模块化的雏型, 在注释中标注它的依赖

这个时期,还没有前后端分离,可国内一些带着深厚后端背景的高手已经入场。

jQuery 时期(2009~2012年)

2006年,jQuery发布,它当时的竞争对手很多:Dojo、Prototype、ExtJS、MooTools。

所以那时jQuery的宣传口号仅能说是它的性能上升了100%、200%、300%。直到2009年,Sizzle选择器引擎研发成功,jQuery才取得压倒性的优势。

当时前端界首要面对的是浏览器兼容性问题,jQuery在处理DOM兼容上真是知微见着, 发掘出大量的DOM/BOM兼容方案(例如Dean Edwrad的addEvent(), IE的px转换方案,domReady的doScroll方案,globalEval的兼容方案等)

jQuery也打破了前端开发者的编程思维,之前是按照后端的开发思路来的:做一个业务就先封装一个类,有了这个类后,再想办法传入一个DOM,然后再通过类方法操作DOM。而jQuery是DOM为中心,开发者可以选一个或多个DOM,变成jQuery对象,然后进行链式操作。当时为了改变用户的思维,国内的高手写了不少文章来引导大家。

其次,开发者们已开始注重前后端分离,并要求不能污染Object原型对象,不能污染window全局变量。这样,jQuery只占用两个全局变量。

再次,jQuery非常轻量级,采用Dean Edwards编写的Packer压缩后, 大小不到30KB。并且里面实现得非常精妙,以令人瞠目的手段解决各种兼容痼疾。

为了学习这些技巧,高手们翻了一遍遍jQuery的源码,所以网上有大量关于其源码详解的书藉。甚至前端工程师在面试时也会被考到jQuery的源码实现,这样,jQuery在国内更加流行。

jQuery的流行间接带来以下的发展:

促使人们对CSS1~CSS3选择器的学习

促进了浏览器原生选择器引擎document.querySelectorAll、Element.matches的诞生

提高人们对domReady(DOMContentLoaded事件)的认识

促进了Promise与requestAnimateFrame 的诞生

最重要的是降低前端门槛,让更多人进入这行业,前端工程师的队伍越来越壮大。

这样的话,不断涌现出优秀的工程师,他们创造了大量jQuery插件与UI库。为后jQuery时代,人们研发前端模块加载、统一异步机制、 打造大型MVC框架, 甚至伸向后端,接管打包脚本而发明Node.js,来腾出大量时间。

这个时期涌现了大量jQuery-like的库,其中最着名的是Zepto.js。Zepto的出现也标志着我们进入移动互联网时代。那时配套出的着名库还有iScroll、fastclick、Lazy Load、Modernizr、fullPage。

jQuery的链式操作风麾一时,也带来许多问题,当Ajax出现依赖时,就不可避免就出现回调地狱。因此针对这方面的讨论,诞生Deffered与Promise。有关回调地狱的讨论,在后来讲Node.js异步处理时,将会再一次热烈地讨论。因此太阳下没有新事,我们总是遇到相似的问题。

jQuery如此多的选择器也法维护,随着越来越多人涌现这行业,页面的交互也越来越复杂,从Web Page向Web App进化,新的趋势带来新的开发方式。

后jQuery时期(2012~2016年)

这时期以RequireJS的诞生为起点,以RN的出现结束。同时解决了前端的模块定义问题,模块打包问题(通过Node.js),Java不依靠其他语言创造了一套自己的工具链。

jQuery的出现让前端工程师开发更加轻松,假如工程师想实现一个功能,现搜索出一个jQuery插件来实现。那时候大家在前端网站就整天介绍jQuery插件,很少讨论一些底层的实现。

前端工程师通常编写一个页面,会引入十多个乃至几十个jQuery插件,页面上塞满了标签。众所周知,浏览器是单线程,的加载,会影响到页面的解析与呈现,导致着名的白屏问题(当时前端用力过勐,body中的所有东西都是动态生成的)。

jQuery另一个问题是全局污染,由于插件的质量问题,或者开发的素质问题,这已经是IIEF模块或命名空间等传统手段无法解决了。

于是一些优秀的前端工程师们决定从取经后端,引入模块机制。早期,这种模块机制在Dojo、EXT这些框架中都是内置的,但是显然说服不了另一个框架的用户用对方的模块机制,于是有人立志要统一这种模块定义方式,成立了CommonJS。

但不料,CommonJS内部也有派系,谁也说不服对方。终于有一个人忍不住自己独立开发出RequireJS,其模块规范即为AMD。 AMD最大的优势是它支持各种插件,且简单明了,并且提供shim机制加载以非AMD规范编写的Java代码。

但在CommonJS诞生很久一段时间后,在后端的Node.js出现时才有用武之地。而国内,则流行另一种规范风格,背靠阿里的大旗,有人推出了SeaJS,号称其规范为CMD。其实无论国内还是国外,都产生许多模块加载器,但最后还是被淘汰了,规范一个就够了,不宜过多。

但是前端工程师的创造力就是这么惊人,从无到有,再到泛滥成灾,一年足矣。这可能与前端代码是开源的原因。最后有人统一了前两种规范(AMD、Node.js模块),同时还支持老式的“全局”变量规范。

自此,Java开发模式焕然一身了,大家只要在代码外面包一层就可以全世界通用,不用提心全局污染的问题。

其次,jQuery开发者需要解决大段HTML的生成问题,之前jQuery有$.html, $.append, $before等方法,可以将一大段符合HTML结构的字符串转换成DOM再插入到页面上。

但现在我们想分离出来,让HTML独立到不同的文件中,然后插数据,这就是前端模板。前端模板的情况与模板规范一样,从没有到多如芝麻的境地。这时筛选一个好用且性能高的模板是一件让前端工程师头疼的问题,那时网上有许多评测文章来介绍它们。

前端模板技术可以用一个公式来描述:

HTML = template(vars)

有了前端模板后,又诞生了前端路由,基于它们,人们发明一个新词汇SPA。作为这个时代的尾声,来自Ruby界的高手Ryan Dahl发明了Node.js。 前端工程师们欢唿:可以不用传统的后端就能自己写一个网站了!

Node.js的发展就不详述上,很快它就冒出海量模块、路由、状态管理、数据库、MVC框架都有了。这时,前端就缺自己的MVC框架了。Node.js转眼就十岁生日了。

着名的MEAN架构,是Java全栈开发的先锋。当时涌现了大量的MVC与MVVM框架。最先火起来的是Backbone.js,使用纯正的MVC模型, Backbone.js是jQuery最后的支持者,它强依赖于jQuery。

Backbone.js的作者还搞了另一套编译语言Coffee, 里面的箭头函数、类机制、 解构赋值等语法糖都深深影响了后来的ES6。

接着下来是谷歌的Angular,微软的Knockout.js,苹果的Ember.js这三个MVVM框架,MVVM就是比MVC多一个数据绑定功能,但这数据绑定功能是非常难实现。Knockout是使用函数代替属性的技巧实现,它的设计影响到后来的Mobx;Ember.js是基于Object.defineProperty;Angular是将函数体转译成setter()、getter()函数。

大公司的介入,对个人开发者影响是很大,毕竟大家都爱迷信大公司,因此局面一下子就稳定下来。大公司还带来了全新的开发模式,早期都是找一个核心库,再搜刮一大堆插件,然后自己写业务代码,最后后端打包。

大公司将后端开发经验挪用过来,用Node.js开发了一套CLI,里面包含了脚手架生成, 打包脚本、语法风格检测、环境变量插入,代码复杂度检测,代码提交时自动跑单元测试, 图片与JS压缩等功能。ESLint、JSLint、JSHint、CSS Lint、 htmllint等就是那时期出现的。

但CLI的出现导致了前端的分裂,以前大家都使用jQuery,但自CLI帮你建好项目的那一刻起,就将你划归某一子阵营,你是Angular?Ember.js?还是jQuery?对了,jQuery没有大公司支撑的阵营被快速边缘化。

对于个人开发者,他们是没有能力开发这么功能完备的CLI,于是出现了Code Climate、Travis CI、CircleCI这样的平台。它们的出现标志着jQuery小作坊时代的终结了。

CircleCI官网

前端开发者也出现分化:有些人转向后端,出现了CNode的门户网站。另外一些人开始搞工程化。一时间出现上百种构建工具,出名的有Grunt、Gulp、FIS3、webpack、 Rollup、npm-。

你方唱罢我登场,这些构建工具均会经历时代的考验,如大浪淘沙般,最后存活得仅为寥寥。

因此在这场工程化得盛宴中,注定把许多低层次的jQueryer淘汰掉。jQueryer在空闲之余培育出的前端模板、前端路由、MVC框架、模块加载器、Node.js构建工具,却不料最终成为它自己的挖墓人。

jQuery的时代一去不返了,再没有人关心拖堂拖了N年的Bootstrap 4终于发布了,没有人知道jQuery3.5的瘦身计划,也没有人问jQuery的源码,渐渐地,大家不关注jQuery的工具链了。

三大框架割据时代(2016~至今)

React是突然爆发的,虽然它是与Angular是同时期发布,但因为JSX怪异的语法让人们远离它。此时已经进入移动互联网的中期,大公司都有自己的App,或者基于原生,或者基于Hybird。

Hybird是用WebView加载一个网站或一个SPA。

由于原生成本太贵,需要招两套班子,一套安卓的,一套iOS的;而Hybird则一直存在性能问题。于是在2017年,Facebook推出了React Native(RN)。

RN的性能不比原生差多少,比Hybird能好些, 其次使用JSX开发界面比原生的快; RN 只需要低成本的前端开发人员就能上手了。中国国内经过瀑布流(图片导购)、团购、P2P、区块链等全新商业模式的开发浪潮后,前端人员数量大增。现在,他们只要稍微培训就可以转型为App开发。

在开发RN的过程中,人们开始了解React一系列的优胜之处。比如JSX背后的虚拟DOM技术,虽然事实证明虚拟DOM不会带来性能的巨大优势,但保证了你怎么写其性能不会太差。

React为了引入JSX,必须需要引入编译,这又间接促成Babel与webpack的壮大。尤其是Babel, 让我们在很旧的浏览器中使用非常新的语法,甚至一些还没有定案的语法。React从14升级到React 15,强制使用class语法,让这个推了好久的语法糖终于大规模落地。

之前如果Java想使用类,只能自己模拟类,由于没有官方的实现,只能任由各优秀工程师发挥。而普通人想用好类,需要了解很复杂的Prototype机制。

现在只用几个新关键字就可以得到这一切。

如果对比Python 2与Python 3间的升级,Java实在太辛运了!针对CSS逻辑功能过弱的问题,我们也有了新的解决方案:Less、Sass、PostCSS与CSS Moles!

谷歌在发布Angular的同时,也发布了一个叫Polymer的框架,那时它想推广一种叫Web Components的浏览器自定义组件技术。这其实是微软在IE5就玩剩的HTC技术的升级版。虽然它没有火起来,但它将、Style、Template三种内容混在一个文件的设计,启发一个留美华人,再结合当时的Backbone.js、Angular等设计,Vue.js横空出世。目前,这是国人最成功的前端框架了。

除此之外,国人也弄了好几套迷你React框架与迷你Vue框架。这有点像jQuery时代,大家疯狂做迷你jQuery框架一样。

总的来说,最有创造力的是React团队,做出状态管理器、CSS-in-JS、Flow静态类型检查、devTool、Fetch、前后端同构、Fiber、suspend、并发渲染等名词层出不穷。其中,状态管理器拥有上百套, CSS-in-JS也拥有上百套,Flow则让前端尝鲜到接口编程的好处,间接推动发Type发展。这三大框架无法比拼个一二出来:Vue.js有国人的拥趸,React与Angular有大公司光环。

三大框架的缠斗从PC领域扩展到移动端:React有RN, Vue.js有Weex,Angular有ionic。想当年我们为了兼容浏览器,攒了一大堆浏览器侦探的Hack,全部贬值为垃圾了。

在这时期,一种全新的后端渲染崛起,称之为前后同构,既拥有早期SEO的功效,又能复用大量的业务逻辑。随着国内移动互联网的发展,获客成本提高,各种有效的商业模式都进入红海,但只有头部用户能赚到钱,马太效应越来越严重,纯粹的技术解决方案已经无法满足商业诉求了。

小程序时代(2017~至今)

小程序时代与三大框架的时代几乎重合,但是出自不同一批人,决战的平台也不一样。

一直以来前端技术都是由国外开发者主导的,即便是Vue.js也是由美国的华人创造的。但是国内外的技术更新是存在代差,国内通常延期两三年,这个时间差可以让一些模仿者得以生存(如SeaJS、FIS、avalon)。但随着封闭的时间越来越长,国内肯会也会诞生自己的转有物种。小程序就是其中之一。

小程序的出现有着明显的商业诉求,因为马太效应,一些超大流量的App诞生了。这些大流量App集成了许多功能,但显然公司再多员工,也无法所有功能全是自己弄,于是产生小程序这种“外包”的手段。

小程序是国内前端技术的一次厚积薄发:底层运行的迷你React的虚拟DOM, 内置组件是使用Web Component,API来源于Hybird的桥方法,打包使用webpack,调试台是Chrome console的简化版, WXML、WXSS的语法高亮也应该是webpack或VS Code的插件, 模块机制是Node.js的CommonJS……其中最值得一提的是微信开发者工具,以后开发者工具成了各种小程序/快应用的标配。

但微信小程序一开始的复用能力非常弱,没有类继承,不能使用npm, 不支持Less、Sass, 因此基于它的转译框架就应运而生。第一代译转框架是wept、WePY、mpvue,它们无一例外是Vue风格的。因为WXML的模板指令与Vue非常相似,只是改一下就能兼容。当时也出现了一个MINA的框架,听说是微信团队开发的,可以单独架起Node.js后端,让小程序运于浏览器中,方便做单元测试。

第一代转译框架主要是基于Template标签实现组件机制,自定义组件机制是很后的事了。这就造成了利用第一代转译框架编写的小程序项目很难升级。那时候是个人开发者的天堂,这些框架都是某一大牛独力开发的。

第二代转译框架是大公司主导的,因为需要兼容的小程序越来越多,网络、支付宝、字节跳动、小米、华为等公司都推出自己的小程序和快应用。个人开发者很难凭个人力量去开发转译框架,这时候各大团队纷纷推出自己的轮子:如京东的Taro、滴滴的Chameleon网易的Megalo、去哪儿网的nanachi、网络的Okam等。

在这个时期,Angular显然落伍了,一是Angular升级太快,国内的高手还没有消化好,新一版的Angular又发布了。二是国内缺乏迷你Angular的轮子,导致庞大的Angular无法塞进小程序中。

国外谷歌发布了Flutter跨平台转译框架,但是它的编写语言是Dart,它也无法跨界到小程序中。

未来不仅国内一线巨头争夺小程序,二三线的巨头也可能会加入小程序的混战中,例如有人称360也在打造自己的小程序平台。小程序这种新的流量变现模式深刻地影响了国内的互联网布局。

结语

当初Java被误解为最糟糕的语言,时至今日它是最流行的语言:GitHub 60%的开源项目都是与Java有关。

以前,从事这行业的人被称为页面仔,现在他们的起薪有的比PHP、JAVA、C++等后端还高。甚至有人说,“任何可以使用Java来编写的应用,最终会由Java编写。”

我们前端开发者触及的领域不仅仅是浏览器,还可以做后端,做桌面端,做手机端,做小程序端,前端开发者的性价比越来越高,越来越重要。可谓是时代造英雄。

笔者有幸成为前端开发者大队伍中的一员,也坚信我们前端开发者以后的路会越来越宽,越来越好走。

资料:

[1]:计算机和编程语言的发展历史

[2]:Polyfill是一块代码(通常是 Web 上的 Java),用来为旧浏览器提供它没有原生支持的较新的功能。

作者简介:司徒正美,拥有十年纯前端经验,着有《Java框架设计》一书,去哪儿网公共技术部前端架构师。爱好开源,拥有mass、Avalon、nanachi等前端框架。目前在主导公司的小程序、快应用的研发项目。


  • 本文链接:http://www.cnite.cn/qianan/share/20198308.html

2. lua脚本怎么取出自己想要的的部分字符

你好,以前没接触过lua,刚自己试了一下,就按照你问题中的"23^Hello^你好^2000^world.txt"这个字符串为例,以^为分隔符来说吧:
---------------start---------------
str = "23^Hello^你好^2000^world.txt"
list = table.pack()
for w in string.gmatch(str, "[^^]+") do
print(w)
table.insert(list, w)
end
---------------start---------------
解释:代码共6行,
第1行:定义一个变量str,内容为"23^Hello^你好^2000^world.txt",这也是我们要处理的字符串.
第二行: 定义一个空列表,它是用在下面的for循环中,存放以"^"作为分隔符的每一部分
第三行:简单来看是个for循环,深入一点来看,也就是string.gmatch(str,"[^^]+")这部分需要解释一下,它表示调用的是string库的gmatch()函数,这个函数有两个参数,第1个参数为要处理的字符串,咱们这里就是上面定义的str,第二个参数就是我们要在这个字符串中匹配什么样的内容,这里的匹配内容写的是"[^^]+",学过正则的很好理解,单纯的[abc]表示匹配任意单个字符a或b或c,有一点特殊的是一旦[]中的字符是以^打头的,则表示匹配任意非[]中列出的字符,如[^abc]表示匹配任意除abc外的其它任一字符,所以[^^]解释为匹配除^外的任一字符,举例来说,如果我们有字符串"23^Hello",如果用[^^]匹配的话,最终得到的是7个单个字符,即"2","3","H","e","l","l","o",显示这不符合我们的题意,所以在这基础上改进了一下,即在其后又加了个+号,[^^]+,这里的+号表示尽可能多地匹配它前面内容,这里也就是尽可能多地匹配[^^],所以[^^]+在处理"23^Hello"的时候,结果得到的就是"23","Hello".这里关于用到的这个正则说的不是太清楚,多练练就明白了。最后,第3行把函数部分给替换掉后,可以理解为:for w in [23,Hello,你好,2000,world.txt],每次从[]中取一个值赋给w,然后执行for下面的语句,接着往下看
第4行,接第3行尾,就是把每次赋给w的值都打印出来
第5行,将每次赋给w的值都追加到列表list中
第6行,for循环语法上的闭合关键字,这个没啥说的
到此,我们得到了一个列表值为[23,Hello,你好,2000,world.txt]的list,此时我们就可以使用list[n]来取我们想要的值了 。
*.如果你要问上面最3条最后不都有[23,Hello,你好,2000,world.txt]了嘛,为啥还要那么麻烦,直接使用string.gmatch()函数不就行了嘛,其实第3条结尾我那么写只是为了让你好理解,实际上gmatch()函数的返回值并不是列表,而是一个可迭代的函数,而for循环的作用就是把gmatch()函数返回的这个可迭代的函数中的每个元素都取出来并赋给列表list
*.说的有点啰嗦了,希望对你有帮助吧,另外,我从没用过lua,也是刚查了查,自己实践了一下,希望不会形成误导

3. 智慧树油猴脚本不起作用

出现这种情况有两种可能,一是脚本没开启。 二是脚本已经失效。
碰到这种情况,一般有两种解决办法:
1、等待脚本作者更新脚本,或者更换其他脚本 用户主要是靠脚本获取网络云文件的下载直链,如果脚本被官方限制使用,脚本就会失效,idm自然也下载不了网络云文件。
这时可以等待脚本作者更新,如果不想等,可以登录“greasyfork”网站,搜索“网络网盘/网络云/网络下载直链/网络”等,找到相关脚本并安装即可。 通常脚本与脚本不会冲突,所以不用担心安装多个脚本导致idm下载失败的情况发生。 另外在安装其他脚本时,要注意脚本的使用的说明,不同脚本对idm的设置要求不同,比如有些脚本会更改idm的UA设置,而有的脚本需要将idm更改为单线程下载。
2、开通网络网盘会员 如果多个脚本同时失效,并且其他人都能正常使用脚本下载文件,那很有可能是自己的账号被网络官方拉黑了,也就是限速。
这种情况可以考虑充值一个月的网盘会员,会自动解封。

4. 怎样编写shell脚本实现统计一个小组的成绩情况,统计信息包括:总分,平均分,最高分

#!/bin/bash

# 2013/07/01 sun

#功能说明:实现统计录入学生成绩的总人数,得出最高分,最低分,平均分,方差,标准方差,还有各个分数段的所占百分比

echo "请输入所有学生的成绩,以空格隔开:"

read -a score_arr

#定义一个数组来存放用户输入的成绩

sorted_arr=($(printf '%s\n' "${score_arr[@]}"|sort -n -r))

#录入学生成绩,并且是成绩之间使用空格隔开

declare -i i b=0 c=0 d=0 e=0 f=0

#定义变量i来循环数组,依次读出数组里面的数据,定义五个初值为0的变量来存放每个分数段的人数

for (( i=0; $i<${#sorted_arr[@]}; i=$i+1 ))

#进行for循环,依次取出数组里面的数据

do

#对每个取出来的数据进行判断

case ${sorted_arr[i]} in

?|?\.*|[1-5]?|[1-5]?\.*)

#如果取出数组里面的数据在60分以下

b=$(($b+1));;

#变量b自加1,进行统计数据

6?|6?\.*)

#如果取出数组里面的数据在60分--69分之间

c=$(($c+1));;

#变量c自加1,进行统计数据

7?|7?\.*)

#如果取出数组里面的数据在70分--79分之间

d=$(($d+1));;

#变量d自加1,进行统计数据

8?|8?\.*)

#如果取出数组里面的数据在80分--89分之间

e=$(($e+1));;

#变量e自加1,进行统计数据

100|100\.0|9?|9?\.*)

#如果取出数组里面的数据在90分--100分之间

f=$(($f+1));;

#变量f自加1,进行统计数据

*)

score_rank[i]="Not a Score";;

esac

done

#判断结束

count=$(($b+$c+$d+$e+$f))

#算出总人数

declare -i j max min ave countall=0 u ua=0 ual=0 uall=0 fang

#定义变量j,最大值max,最小值min,平均数ave,所有人的分数之和countall

max=${sorted_arr[0]}

#获取排序后的数组的第一个数,也就是最大数

j=$((${#sorted_arr[@]}-1))

#得到排序后的数组的最后的一个分数的下标

min=${sorted_arr[j]}

#获取排序后的数组的最后一个数,也就是最小数

for (( j=0; $j<${#sorted_arr[@]}; j=$j+1 ))

#进行for循环,让学生成绩相加,算出学生成绩的总分

do

countall=$countall+${sorted_arr[j]}

done

ave=$countall/$count

#算出平均成绩

for (( j=0; $j<${#sorted_arr[@]}; j=$j+1 ))

#进行for循环,让学生成绩相加,算出学生成绩的总分

do

ua=$(awk -v va=${sorted_arr[j]} -v vb=$ave 'BEGIN{printf "%2d" ,va-vb}')

#让每一个数都减去平均数然后赋值于ua

ual=$(awk -v va=$ua -v vb=$ua 'BEGIN{printf "%2d" ,va*vb}')

#算得ua的平方

uall=$(awk -v va=$uall -v vb=$ual 'BEGIN{printf "%2d" ,va+vb}')

#算出它们的总合,也就是方差

done

u=$(awk -v va=$uall -v vb=$count 'BEGIN{printf "%2d" ,va/vb}')

#算出学生成绩的平均分,并赋值于ave

#下面是计算每个分数段的百分数

countb=$(awk -v va=$b -v vb=$count 'BEGIN{printf "%2.2f%%" ,va*100/vb}')

#echo $countb

countc=$(awk -v va=$c -v vb=$count 'BEGIN{printf "%2.2f%%" ,va*100/vb}')

#echo $countc

countd=$(awk -v va=$d -v vb=$count 'BEGIN{printf "%2.2f%%" ,va*100/vb}')

#echo $countd

counte=$(awk -v va=$e -v vb=$count 'BEGIN{printf "%2.2f%%" ,va*100/vb}')

#echo $counte

countf=$(awk -v va=$f -v vb=$count 'BEGIN{printf "%2.2f%%" ,va*100/vb}')

#echo $countf

#输出结果

echo "总人数 最高分 最低分 平均分 方差 "

echo "$count $max $min $ave $u "

echo "标准方差="

echo "scale=5;sqrt($u)" | bc

#算出标准方差

echo " 60分以下 60--69 70--79 80--89 90--100"

echo "人数" " $b $c $d $e $f"

echo "比例" "$countb $countc $countd $counte $countf"

5. 组态软件国内那家做的好推荐几个比较一下

国内组态软件大一点的分为四家:紫金桥RealHistorian、亚控组态王KingScada、力控ForceControl7.2 SP1、杰控FaMe。主要分析他们几个的优缺点,如下:

  1. 设备驱动:紫金桥RealHistorian常用硬件种类常用型号支持

    亚控组态王KingScada种类非常多,支持大量硬件型号

    力控ForceControl7.2 SP1种类比较多,支持常用驱动和部分总线;功能相对比较全(modbus驱动,可以控制起始地址,数据长度,校验高低位互换!可以很容易实现非标设备链接!)

    杰控FaMe主要集中在主要的几家国外厂家和网关等相关设备范围比较小

  2. 历史存储:紫金桥RealHistorian.周期和变化保存两种方式

    亚控组态王KingScada.无

    力控ForceControl7.2 SP1.周期和变化保存两种方式和数据插入模式(条件保存)

    杰控FaMe.无

  3. 点类型:紫金桥RealHistorian.内置多种点类型(模拟点、数字点、组合点、设备运行点、运算点等)

    亚控组态王KingScada.IO离散,IO长整型,IO整型,IO实型,IO双精度浮点,IO字符串

    力控ForceControl7.2 SP1.模拟、数字、累计、控制、运算、组合和雪崩过滤点等7种类型(建点那里,可以批量点链接,不同节点下,点名可以重名)

    杰控FaMe.无

  4. 关系库通讯:紫金桥RealHistorian.支持多种关系数据库,包括Oracle、sql Server、Access、mysql、sqlite。 支持一些国产的关系库例如:人大金仓,达梦

    亚控组态王KingScada.无

    力控ForceControl7.2 SP1.通过ADO,可以和所有的关系型数据库通信,但是配置比较繁琐。具体没测试。

    杰控FaMe.通过ADO方式把数据存储到关系库主要是acess、sqlsever。

  5. 脚本系统:紫金桥RealHistorian.完整的脚本语言,提供大量预定义函数,提供各种控制语句,可实现十分复杂的功能,同时有多种智能提示,使用方便简洁。

    亚控组态王KingScada.完整的脚本语言,类VC,提供大量预定义函数,没有中文注释,需要对函数属性比较熟悉才能熟练应用,使用较难

    力控ForceControl7.2 SP1.无

    杰控FaMe.直接内嵌的vb的脚本系统,脚本都是写在统一界面,多处共用,但是开发需要有vb的基础。

  6. 图库:紫金桥RealHistorian.为用户提供几千种具有立体效果的精美子图,覆盖各行各业,且可根据用户需求,快速定制相关行业子图。

    亚控组态王KingScada.KingScada提供较多的立体图形,覆盖各行各业,用户也可根据需求定制子图,比较精美

    力控ForceControl7.2 SP1.不精美,数量很多

    杰控FaMe.无

  7. HTML5:紫金桥RealHistorian.支持

    亚控组态王KingScada.

    力控ForceControl7.2 SP1.不支持

    杰控FaMe.不支持

  8. OPC Server组件:紫金桥RealHistorian.DA/UA

    亚控组态王KingScada.DA

    力控ForceControl7.2 SP1.支持DA(需要配置)

    杰控FaMe.不支持

  9. 跨平台支持能力:紫金桥RealHistorian.支持常用的Windows系列操作系统、支持国产麒麟系列操作系统以及RedHat、Ubuntu、CentOS等多种Linux桌面操作系统和各种Linux嵌入式操作系统。除支持通用的Intel、AMD处理器,还支持龙芯、兆芯、飞腾、申威、众志等国产处理器。

    亚控组态王KingScada. 支持的操作系统语言版本:中文简体、英文。支持的操作系统位数:32位、64位Windows Server 2008 R2 标准版、Windows Server 2012 R2 企业版、Windows Server 2016 R2 企业版、Windows 7 旗舰版、Windows 8 专业版、Windows 10

    力控ForceControl7.2 SP1.只支持Windows系列操作系统

    杰控FaMe.只支持Windows系列操作系统

  10. 嵌入式系统支持能力:紫金桥RealHistorian.系统采用可裁剪式架构,以及拥有良好的跨平台特性,能够适应多种不同配置的嵌入式设备及操作系统(嵌入式Linux、VxWorks、WinCE等)

    亚控组态王KingScada. 不支持

    力控ForceControl7.2 SP1.不支持

    杰控FaMe.不支持

  11. 单机容量:紫金桥RealHistorian.800万点

    亚控组态王KingScada.100W点

    力控ForceControl7.2 SP1.最大案例大庆石油天然气项目点数达40000点

    杰控FaMe.不知道

  12. 数据转储:紫金桥RealHistorian.支持通过数据转储功能配置,将实时数据和历史数据存储到各种关系库当中SQL Server、Access97-2000、Access2002-2003、Access2007、Oracle、Mysql。

    亚控组态王KingScada.KingDataLogger主要实现从KingIOServer工程中读取数据、缓存数据,并存储至不同种类的数据库、不同的表。目前支持的数据库包括:工业库KingHistorian、SQL Server、Access97-2000、Access2002-2003、Access2007、Oracle、Mysql

    力控ForceControl7.2 SP1. 不支持

    杰控FaMe. 不支持

希望对你有所帮助,通过数据分析得到你想要的

6. 急!用友U8误删UA_TASK 和 UA-TASKLOG怎么恢复啊坐等高手

你是删除了这两个表吗?
数据库是哪个版本?2000还是2005?注意ua_tasklog是表,ua_task是视图

在查询分析器或Microsoft SQL Server Management Studio中运行下面两个语句:
1、创建 ua_task:
USE [UFSystem]
GO
/****** 对象: View [dbo].[ua_Task] 脚本日期: 10/11/2013 15:54:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
---------------zhengyun增加字段,修改索引--------------------------------
CREATE VIEW [dbo].[ua_Task]
AS
SELECT [cAcc_Id], [iYear], [cUser_Id], [cAuth_Id], [cStation], [cTaskId], [iLogId], [cSub_id], [cAppServer], [cAuthClassCode],[iBeginYear]
FROM [UFSystem].[dbo].[ua_Task_Common]
union
SELECT [cAcc_Id], [iYear], [cUser_Id], [cAuth_Id], [cStation], [cTaskId], [iLogId], [cSub_id], [cAppServer], [cAuthClassCode] ,[iBeginYear]
FROM [UFSystem].[dbo].[UA_Task_Special]

2、创建 ua_tasklog:

USE [UFSystem]
GO
/****** 对象: Table [dbo].[UA_TaskLog] 脚本日期: 10/11/2013 15:51:46 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UA_TaskLog](
[cSub_Id] [nvarchar](2) COLLATE Chinese_PRC_CI_AS NULL,
[cSub_Name] [nvarchar](40) COLLATE Chinese_PRC_CI_AS NULL,
[cStation] [nvarchar](255) COLLATE Chinese_PRC_CI_AS NULL,
[dInTime] [datetime] NULL,
[cTaskId] [nvarchar](20) COLLATE Chinese_PRC_CI_AS NOT NULL,
[TaskState] [nvarchar](40) COLLATE Chinese_PRC_CI_AS NULL,
[cAppServer] [nvarchar](80) COLLATE Chinese_PRC_CI_AS NULL,
[uuid] [nvarchar](40) COLLATE Chinese_PRC_CI_AS NULL,
[cLSSubId] [nvarchar](4) COLLATE Chinese_PRC_CI_AS NULL,
[cStationSerial] [nvarchar](255) COLLATE Chinese_PRC_CI_AS NULL,
CONSTRAINT [aaaaaUA_TaskLog_PK] PRIMARY KEY NONCLUSTERED
(
[cTaskId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
EXEC sys.sp_bindefault @defname=N'[dbo].[UA_TaskLog_TaskState_D]', @objname=N'[dbo].[UA_TaskLog].[TaskState]' , @futureonly='futureonly'

给你现导的,纯手打。
求选

7. via浏览器如何使用脚本

脚本如下:

设置选项进入脚本选项即可。首先进入Via,点击“三”按钮;接着点击“设置”,进入设置页面,点击“脚本”;打开脚本页面,点击右上角“+”按钮即可添加脚本。

简介:

Via浏览器是一款安卓平台浏览器。该浏览器采用简洁的界面设计,提高搜索框权重,避免用户被其他新闻等信息干扰,让浏览器回归搜索与浏览的本质,以提高效率。

进阶:自定义浏览器标识ua;广告标记拦截;下载插件;查看网页源码;资源嗅探;导入导出书签;云同步;隐私防追踪;保存网页;离线网页;翻译网页;网页内查找;有图/无图模式。

8. 程序开发中模块开发什么意思呢

模块就是根据开发内容划分,比如会员模块,购物模块,新闻模块,广告模块
在交互模式下, Lu a 不断的显示提示符,并等待下一行输入。 一旦读到一行, 首先试着把这行解释为一个表达式。 如果成功解释,就打印表达式的值。 否则,将这行解释为语句。 如果你写了一行未完成的语句, 解释器会用一个不同的提示符来等待你写完。
当脚本中出现了未保护的错误, 解释器向标准错误流报告错误。 如果错误对象并非一个字符串,但是却有元方法 __tostring 的话, 解释器会调用这个元方法生成最终的消息。 否则,解释器将错误对象转换为一个字符串,并把栈回溯信息加在前面。
如果正常结束运行, 解释器会关闭主 L ua 状态机 ( l。a_close)。 脚本可以通过调用 os.exit 来结束,以回避这个步骤。
为了让 L ua 可以用于 Unix 系统的脚本解释器。 独立版解释器会忽略代码块的以 # 打头的第一行。 因此,Lu a 脚本可以通过 chmod +x 以及 #! 形式变成一个可执行文件。 类似这样
(当然, Lu a 解释器的位置对于你的机器来说可能不一样。 如果 lu a 在你的 PATH 中, 写成
这里我们列出了把程序从 Lua 5.2 迁移到 Lua 5.3 会碰到的不兼容的地方。 你可以在编译 Lua 时定义一些恰当的选项(), 来回避一些不兼容性。 然而,这些兼容选项以后会移除。
Lua 的版本更替总是会修改一些 C API 并涉及源代码的改变。 例如一些常量的数字值,用宏来实现一些函数。 因此,你不能假设在不同的 Lua 版本间可以做到二进制兼容。 当你使用新版时,一定要将使用了 Lu a API 的客户程序重新编译。
同样,Lu a 版本更替还会改变预编译代码块的内部呈现方式; 在不同的 Lu a 版本间,预编译代码块不兼容。
官方发布版的标准路径也可能随版本变化。
Lua 5.2 到 Lua 5.3 最大的变化是引入了数字的整数子类型。 虽然这个变化不会影响“一般”计算, 但一些计算 (主要是涉及溢出的) 会得到不同的结果。
你可以通过把数字都强制转换为浮点数来消除差异 (在 Lu a 5.2 中,所有的数字都是浮点数)。 比如你可以将所有的常量都以 .0 结尾, 或是使用 x = x + 0.0 来转换一个变量。 (这条建议仅用于偶尔快速解决一些不兼容问题; 这不是一条好的编程准则。 好好写程序的话,你应该在需要使用浮点数的地方用浮点数, 需要整数的地方用整数。)
把浮点数转为字符串的地方,现在都对等于整数的浮点数加了 .0 后缀。 (例如,浮点数 2.0 会被打印成 2.0, 而不是 2。) 如果你需要定制数字的格式,就必须显式的格式化它们。
(准确说这个不是兼容性问题, 因为 Lua 并没有规定数字如何格式化成字符串, 但一些程序假定遵循某种特别的格式。)
分代垃圾收集器没有了。 (它是 Lu a 5.2 中的一个试验性特性。)

9. bat脚本,用IBM ITM监控软件的UA调用,在windows2008上可用,在windowsXP上不能用

额……我胡乱猜的 错了别介意
你这个脚本是用jit2Clientfor命令从MYSQL里筛选制定数据对吧?
如果是 那么你可以在XP下手动执行这个命令(带参数)看看报错信息
同时可以逐渐减少参数 根据报错信息分析哪个参数有问题
你的数据库在XP本地么? 如果不是 也有可能是路径问题?

热点内容
微信娱乐源码 发布:2025-02-06 21:34:53 浏览:529
编译翻译运行 发布:2025-02-06 21:05:20 浏览:200
安卓源码版本 发布:2025-02-06 20:51:34 浏览:432
安卓系统网络播放器哪个好 发布:2025-02-06 20:42:02 浏览:818
头条缓存的视频格式 发布:2025-02-06 20:32:18 浏览:116
ftp不显示文件夹 发布:2025-02-06 20:30:37 浏览:127
苹果手机解压怎么打开 发布:2025-02-06 20:29:35 浏览:476
单片机程序存储器 发布:2025-02-06 20:29:31 浏览:209
串的c语言 发布:2025-02-06 20:25:44 浏览:750
编程函数总结 发布:2025-02-06 20:09:11 浏览:317