给大家介绍款在线压缩JS的工具
首先说下该工具的域名:http://javascriptcompressor.com/
进入后界面如下:
具体要讲下它的功能点:在线压缩 Javascript 源码可以分不同的压缩级别;比如,一般情况下,即缺省情况,它只是把空格、换行、多余的注释等等清理掉,如果选择了“Base62 encode”选项,则会对文件进行编码,使它更小;尤其当选中 Shrink variables 选项时,该在线工具会把长的变量名缩减成单个字母的变量名,压缩比通常能达到50%甚至更小。比如,我压缩20k大的一个jquery lightbox插件,普通情况可压缩到9.25k,使用“Base62"后,变成5.5k,再使用 Shrink 后变成5.28k,是不是小了很多呀。现在很多网站都大量使用 AJAX 技术,JavaScript 文件越来越大,使用压缩的js文件可以减轻不少流量负担。而且缩减变量名后,程序并没有加密,但会使程序变得很难看懂,一定程度上也能保护一下版权吧。
该在线工具可以把压缩过的 JS 代码重新格式化成容易阅读的样子。当然如果是 javascriptcompressor.com 压缩时选了Shrink缩减变量名选项了,那是没法恢复原来有意义的变量名的。不过这个在线工具也有个问题,当用户上传非常大的 JS 文件进行格式化时,浏览器会报耗时过长,不过如果你有耐心等,它最终还是会完成格式化的。
这两款在线工具本身也是用纯 JavaScript 写的,该兴趣的话,可以下载下来离线使用,也是很方便的。
除了上面两个介绍的在线网站外,还有一些其它网站和本地工具可以参考:
javascriptcompressor.com (在线压缩)
shrinksafe.dojotoolkit.org (在线文件压缩)
dean.edwards.name/packer (在线压缩)
YUI Compressor (使用命令行来压缩,需要JAVA虚拟机来运行压缩程序)
记录一下最近开发web移动前端的过程
两个项目
第一个是公司网站的移动端,我所在的公司是做某方面的新闻站的。
所以说页面基本是以一条条的新闻+图文混排为主,顶部有一个自动slider+触屏滑动的功能,
使用的是swipe插件,轻量,简洁非常好用。一看就懂 特别赞。
采用的的是弹性布局(顺便吐槽我们设计,明明不懂移动端,却死吹自己做了很多年,导致设计稿.. 呵呵 都懂得)
---------------------------------------------------------------------------------
其中记录了一些兼容方面的css属性,做过移动端的基本可以跳过: )
1.input,button标签在iphone下会自动圆角,
这个比较简单,加一个-webkit-appearance:none;就可解决圆角问题。
2.写代码的时候经常需要加入padding这个属性来做,但是如何计算width+padding=?最终宽呢,比较简单的。
加入以下属性后,可让box的宽不受padding的干扰。
举例:假如宽为20em,左右内边距各为5em,则最终宽为30em,然而加入此属性后宽仍为20em。
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box;
box-sizing:border-box
3.标题文字自适应宽度,超出后为...
既然是弹性布局,那么宽度不一,但行文字又不能限制截取多少个字段,于是我考虑用以下代码。
宽了就显示多,窄了就显示少,显示不下去就变为...
width:95%;
white-space:nowrap;
text-overflow:ellipsis;
-o-text-overflow:ellipsis;
overflow:hidden
4.媒体查询,这个是作为弹性布局最关键的一点。
比如我五寸的屏幕,分享的icon我可以看的很清楚,但是在iphone4上用那么大的icon就导致页面变的笨重了。
还有如果横屏会发生什么?自己有时间可以试试。
5.表单控件模拟,如果你和我一样是半个设计出家的话..自己做一个点击前点击后的,写个切换的js就搞定了.
要么就上网找模拟控件的包自己引用,摘出来吧 ..
因为默认的表单控件在手机端确实是非常的不好用。要么太小,要么样子难看,反正我是没找到优点..放弃它吧..
6.最后一点有关用户体验的,click与tap。
这一点我承认没有做好,用click做了效果,导致页面每次点击都会有一些延迟,据资料上说是延迟0.3秒,虽然不多,但是确实不怎么友好,
公司主要也不是做手机端,也就属于能用就行阶段,对这个要求不是很严格,我也就没做..(偷懒了..)
tap属性的话需要用js封装,因为它不是一个可直接调用的方法,我对JS掌握的也不深,所以就抛弃了它..虽然网上能找到封装好的代码吧..
这是新闻页的一些总结,遇到的问题还算比较基础,做下来还是比较简单的,有问题找度娘没错 ~
最后一套页面下来一共是 10个html+12个CSS+图片总共下来是 720kb,压缩后应该是可以达到700KB的
新闻页还是比较简单的,因为不涉及过多的特效,以加载快为主,但是第二个项目就比较苦了..
第二个项目是通过微信+公司网站推广的一个讲述宣言的活动,把自己的留言通过微信记录下来发布到我们这个手机端的页面。
登录手机端页面通过html5来播放,每个页面要加载10个音频,不过由于是微信压缩过的,所以也并不是太大。
但是从技术层面要解决的问题有 :
1.手机端html5技术进行模拟控件,美化控件,保证美观的同时功能完善。
2.JS控制html5模拟,多个音频要考虑是否会冲突,失效问题。
3.就是兼容问题了,我自己用JS模拟了一个控件出来,我安卓的挺好用的,但是在iphone上就瘫了..于是含泪删掉自己辛苦攒(没错是我cuan出来的..)的JS..
上百度开始寻找解决方法了.. 最后用了据说是微信web版都在使用的第三方控件,拿来后发现确实好用,是开源的一个帖子 html5 mp3插件推荐系列的..
4.新的问题出来了,就是我点击播放的时候开始加载,如果音频过长加载过慢,影响用户体验,
但如果预加载的话太费流量了..这个我觉得好像解决不了
自己手贱用一首5MB的歌曲模拟了十个控件预加载,忘连公司wifi,结果过了几秒后弹出提示日流量已超20mb..我赶快给关掉了..
现在项目中又有一个头疼的问题..模拟app做一个底部固定留言块,浏览器垂直滚动也不会发生变化 . 可以输入文字,安卓是解决了,没问题,
但是在iphone下一点击固定的input框,这个框就跑屏幕中间去了,特别难看..整不知道怎么解决呢..而且还引得jquery mobile库,这么大的库也挺愁人的..
一时半会儿也想不到其他说的了..就先这样吧.. 没怎么写过博客 不知道写的是否有用 ,还请赐教,哈哈 ~
目录
背景非平衡二叉搜索树规则为什么叫非平衡?实现如何删除元素?完整代码备注背景返回目录
很多场景下都需要将元素存储到已排序的集合中。用数组来存储,搜索效率非常高: O(log n),但是插入效率比较低:O(n)。用链表来存储,插入效率和搜索效率都比较低:O(n)。如何能提供插入和搜索效率呢?这就是二叉搜索树的由来,本文先介绍非平衡二叉搜索树。
非平衡二叉搜索树返回目录
规则返回目录
所有节点的左节点小于节点,所有节点的右节点大于等于自身,即:node.value > node.left.value && node.value <= node.right.value。
示例
根据上面的规则,我们也很容易找到最大值和最小值,后面也会用到这种算法。最大值可以通过递归方法 node.right 得到,最小值可以递归 node.left 得到。
为什么叫非平衡?返回目录
说明:下图变成链表了,这会导致效率非常低,后面找机会再介绍平衡算法。
实现返回目录
搜索、遍历(前序、中序和后序)、添加算法都比较简单,可以直接看后面的代码,这里重点介绍一下删除算法。
如何删除元素?返回目录
第一步:要找到删除的元素(current)。
第二步:判断 current 满足如下哪种场景:
- current.Right == null
示例
代码
1 if (parent == null) 2 { 3 this.Root = current.Left; 4 } 5 else if (isLeft) 6 { 7 parent.Left = current.Left; 8 } 9 else 10 { 11 parent.Right = current.Left; 12 }
结果
- current.Right != null && current.Right.Left == null
示例
代码
1 current.Right.Left = current.Left; 2 3 if (parent == null) 4 { 5 this.Root = current.Right; 6 } 7 else if (isLeft) 8 { 9 parent.Left = current.Right; 10 } 11 else 12 { 13 parent.Right = current.Right; 14 }
结果
- current.Right != null && current.Right.Left != null
示例
代码
1 Node<T> currentRightSmallestParent = current.Right; 2 var currentRightSmallest = current.Right.Left; 3 4 this.FindSmallest(ref currentRightSmallestParent, ref currentRightSmallest); 5 6 currentRightSmallestParent.Left = currentRightSmallest.Right; 7 currentRightSmallest.Left = current.Left; 8 currentRightSmallest.Right = current.Right; 9 if (parent == null) 10 { 11 this.Root = currentRightSmallest; 12 } 13 else if (isLeft) 14 { 15 parent.Left = currentRightSmallest; 16 } 17 else 18 { 19 parent.Right = currentRightSmallest; 20 }
结果
说明
这里的重点是 FindSmallest,找出 current.Right.Left 子树中最小的元素,然后用它替换 current。
完整代码返回目录
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace DataStuctureStudy.Trees 8 { 9 class UnBalancedBinarySearchTree 10 { 11 class Node<T> 12 where T : IComparable<T> 13 { 14 public T Value { get; set; } 15 16 public Node<T> Left { get; set; } 17 18 public Node<T> Right { get; set; } 19 20 public void InOrderTraverse(Action<T> action) 21 { 22 if (this.Left != null) 23 { 24 this.Left.InOrderTraverse(action); 25 } 26 27 action(this.Value); 28 29 if (this.Right != null) 30 { 31 this.Right.InOrderTraverse(action); 32 } 33 } 34 35 public int Depth() 36 { 37 var leftDepth = 0; 38 var rightDepth = 0; 39 40 if (this.Left != null) 41 { 42 leftDepth = this.Left.Depth(); 43 } 44 if (this.Right != null) 45 { 46 rightDepth = this.Right.Depth(); 47 } 48 49 return 50 leftDepth > rightDepth 51 ? leftDepth + 1 52 : rightDepth + 1; 53 } 54 } 55 56 public class Tree<T> 57 where T : IComparable<T> 58 { 59 private Node<T> Root { get; set; } 60 61 public void Display() 62 { 63 Console.WriteLine(); 64 65 if (this.Root == null) 66 { 67 return; 68 } 69 70 var depth = this.Root.Depth(); 71 var buffers = new string[depth][]; 72 for (int i = 0; i < buffers.Length; i++) 73 { 74 buffers[i] = new string[(int)(Math.Pow(2, depth) - 1)]; 75 } 76 77 this.BuildArray(this.Root, depth, buffers, 0, 0); 78 79 for (int i = 0; i < buffers.Length; i++) 80 { 81 for (int j = 0; j < buffers[i].Length; j++) 82 { 83 if (buffers[i][j] == null) 84 { 85 Console.Write(new string(' ', 5)); 86 } 87 else 88 { 89 var leftPad = (5 - buffers[i][j].Length) / 2; 90 Console.Write(buffers[i][j] 91 .PadLeft(leftPad + buffers[i][j].Length) 92 .PadRight(5)); 93 } 94 } 95 Console.WriteLine(); 96 Console.WriteLine(); 97 } 98 } 99 100 private void BuildArray(Node<T> node, int nodeDepth, string[][] buffers, int row, int startColumn) 101 { 102 if (node == null) 103 { 104 return; 105 } 106 107 var nodeWidth = Math.Pow(2, nodeDepth) - 1; 108 var column = (int)(startColumn + nodeWidth / 2); 109 110 buffers[row][column] = node.Value.ToString(); 111 112 this.BuildArray(node.Left, nodeDepth - 1, buffers, row + 1, startColumn); 113 this.BuildArray(node.Right, nodeDepth - 1, buffers, row + 1, column + 1); 114 } 115 116 public bool Contains(T item) 117 { 118 var current = this.Root; 119 120 while (current != null) 121 { 122 if (item.CompareTo(current.Value) == 0) 123 { 124 return true; 125 } 126 else if (item.CompareTo(current.Value) < 0) 127 { 128 current = current.Left; 129 } 130 else 131 { 132 current = current.Right; 133 } 134 } 135 136 return false; 137 } 138 139 public void InOrderTraverse(Action<T> action) 140 { 141 if (this.Root != null) 142 { 143 this.Root.InOrderTraverse(action); 144 } 145 } 146 147 public void Insert(T item) 148 { 149 var node = new Node<T> { Value = item }; 150 151 Node<T> parent = null; 152 var current = this.Root; 153 var isLeft = false; 154 155 while (current != null) 156 { 157 parent = current; 158 159 if (item.CompareTo(current.Value) < 0) 160 { 161 current = current.Left; 162 isLeft = true; 163 } 164 else 165 { 166 current = current.Right; 167 isLeft = false; 168 } 169 } 170 171 if (parent == null) 172 { 173 this.Root = node; 174 } 175 else if (isLeft) 176 { 177 parent.Left = node; 178 } 179 else 180 { 181 parent.Right = node; 182 } 183 } 184 185 public bool Delete(T item) 186 { 187 Node<T> parent = null; 188 var current = this.Root; 189 var isLeft = false; 190 191 this.Find(item, ref parent, ref current, ref isLeft); 192 193 if (current == null) 194 { 195 return false; 196 } 197 198 if (current.Right == null) 199 { 200 if (parent == null) 201 { 202 this.Root = current.Left; 203 } 204 else if (isLeft) 205 { 206 parent.Left = current.Left; 207 } 208 else 209 { 210 parent.Right = current.Left; 211 } 212 } 213 else if (current.Right != null && current.Right.Left == null) 214 { 215 current.Right.Left = current.Left; 216 217 if (parent == null) 218 { 219 this.Root = current.Right; 220 } 221 else if (isLeft) 222 { 223 parent.Left = current.Right; 224 } 225 else 226 { 227 parent.Right = current.Right; 228 } 229 } 230 else 231 { 232 Node<T> currentRightSmallestParent = current.Right; 233 var currentRightSmallest = current.Right.Left; 234 235 this.FindSmallest(ref currentRightSmallestParent, ref currentRightSmallest); 236 237 currentRightSmallestParent.Left = currentRightSmallest.Right; 238 currentRightSmallest.Left = current.Left; 239 currentRightSmallest.Right = current.Right; 240 if (parent == null) 241 { 242 this.Root = currentRightSmallest; 243 } 244 else if (isLeft) 245 { 246 parent.Left = currentRightSmallest; 247 } 248 else 249 { 250 parent.Right = currentRightSmallest; 251 } 252 } 253 254 return true; 255 } 256 257 private void Find(T item, ref Node<T> parent, ref Node<T> current, ref bool isLeft) 258 { 259 while (current != null) 260 { 261 if (item.CompareTo(current.Value) == 0) 262 { 263 break; 264 } 265 266 parent = current; 267 268 if (item.CompareTo(current.Value) < 0) 269 { 270 current = current.Left; 271 isLeft = true; 272 } 273 else 274 { 275 current = current.Right; 276 isLeft = false; 277 } 278 } 279 } 280 281 private void FindSmallest(ref Node<T> parent, ref Node<T> current) 282 { 283 while (current != null) 284 { 285 if (current.Left == null) 286 { 287 break; 288 } 289 290 parent = current; 291 current = current.Left; 292 } 293 } 294 } 295 } 296 }
备注返回目录
学完这个树的最大收获就是,找到了一种输出树形结构相对高效的方法,比我之前用的高效,这种算法可以用在组织结构图的生成中。