堂的博客

给岁月以学习,而不是给学习以岁月


  • 首页

  • 归档

  • 分类

  • 标签

  • 关于

  • 搜索

使用handsontable插件修改bug心得

发表于 2016-10-18 | 更新于: 2019-07-10 | 分类于 前端 | 评论: | 阅读次数:

这段日子有个坑爹的项目——南网,这篇文章就来纪念它。里面有用到一个jq插件:handsontable,作用是生成一个类似excel的表格,不得不说功能十分强大,实现了类似excel的各种功能,使用的api也比较简单,然而…后面有些莫名其妙的bug,奈何于水平有限,其源码也太长(30000+),各种嵌套,无法从正确的逻辑中找到出问题的地方,只能在关键的地方强制使用自己的逻辑,下面就说说怎么找这个bug关键的地方

平时修改bug

  1. js的bug:我总是想一遍过程,整个流程构思的跑一遍,然后哪儿的逻辑出了问题或者疏忽了,自然就知道了对应的地方。
  2. 页面的bug:google浏览器,你懂得。我对页面渲染理解着实不深,所以经常”不求甚解”。

这次修改handsontable插件bug的经验

bug1:要渲染的数据很多,但是只显示了一部分:

Created with Raphaël 2.1.2根据官方demo发现handsontable是先渲染一部分数据,然后滚动的时候渲染新数据在页面上使用开发者工具查看handsontable的绑定事件,发现事件:wheel查看绑定事件的地方,发现嵌套多层,理不清楚,转而在源码中搜索关键字:wheel搜索发现wheel都与方法:onTableScroll()有关在onTableScroll()内打断点,查看代码执行的步骤,通过对比官方demo发现步骤中不同的地方在自己使用handsontable的地方加一个全局变量:window.flag,在onTableScroll()中使用此变量来强制执行正确的步骤

注:使用全局变量window.flag是为了在其他地方不影响

阅读全文 »

不同浏览器通用的事件处理

发表于 2016-10-08 | 更新于: 2019-07-10 | 分类于 前端 | 评论: | 阅读次数:

摘抄自:马云云_理想青年

封装的ie和其他浏览器的事件处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// event(事件)工具集
markyun.Event = {
// 页面加载完成后
readyEvent : function(fn) {
if (fn==null) {
fn=document;
}
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = fn;
} else {
window.onload = function() {
oldonload();
fn();
};
}
},
// 视能力分别使用dom0||dom2||IE方式 来绑定事件
// 参数: 操作的元素,事件名称 ,事件处理程序
addEvent : function(element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent('on' + type, function() {
handler.call(element);
});
} else {
element['on' + type] = handler;
}
},
// 移除事件
removeEvent : function(element, type, handler) {
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if (element.datachEvent) {
element.detachEvent('on' + type, handler);
} else {
element['on' + type] = null;
}
},
// 阻止事件 (主要是事件冒泡,因为IE不支持事件捕获)
stopPropagation : function(ev) {
if (ev.stopPropagation) {
ev.stopPropagation();
} else {
ev.cancelBubble = true;
}
},
// 取消事件的默认行为
preventDefault : function(event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
// 获取事件目标
getTarget : function(event) {
return event.target || event.srcElement;
},
// 获取event对象的引用,取到事件的所有信息,确保随时能使用event;
getEvent : function(e) {
var ev = e || window.event;
if (!ev) {
var c = this.getEvent.caller;
while (c) {
ev = c.arguments[0];
if (ev && Event == ev.constructor) {
break;
}
c = c.caller;
}
}
return ev;
}
}

浏览器中常用的存储

发表于 2016-10-08 | 更新于: 2019-07-10 | 分类于 前端 | 评论: | 阅读次数:

本文参考:

  • 邹润阳
  • Storage的用法:Storage的API

localStorage 与 sessionStorage

localStorage与sessionStorage都是h5中出现的,都继承于Storage,用法完全相同

localStorage

  • 大小一般都是5M左右。
  • 除非被手动清除,否则永久保存

sessionStorage

  • 大小一般也是5M左右。
  • 仅在当前会话下有效,关闭 tab 或 浏览器(window) 后被清除
    • 刷新页面时不会清除
    • 页面跳转时,如果还在当前网站范围内则不清除。如果跳转到了其他网站则清除
      阅读全文 »

html我们应该知道的

发表于 2016-09-30 | 更新于: 2019-07-10 | 分类于 前端 | 评论: | 阅读次数:

document.documentElement

html页面按大小排序:

  1. window:整个浏览器窗口,包含工具栏、菜单栏…
  2. document:整个html,包含<DOCTYPE>
  3. html:根节点,document.documentElement就是html节点
  4. body: 页面主体

然后有这样一个问题:如何获取如图的高度?

高度
这样获取:

1
2
document.documentElement.clientHeight;
//document.documentElement.offsetHeight不可以,有时候会出错

调试鼠标hover时提示框的样式

我们经常需要设计提示框,在hover时浮现,但是如何在控制台调试这个提示框的样式呢,每次鼠标移开提示框就消失,不胜其烦,这儿有个小技巧

  1. 在提示框上右键检查,找到对应的dominspect
  2. 添加dom断点给node removal:debugger

然后就可以在断点阻塞到提示框显示的时候开心的调试样式了

在location中传递中文参数

传递的时候:

1
location.href = window.encodeURI(url + '?key=你妹');

获取的时候:

1
2
let search = window.decodeURI(location.search);
// 结果是 ?key=你妹

jq的promise

发表于 2016-09-30 | 更新于: 2019-07-10 | 分类于 前端 | 评论: | 阅读次数:

之前用angular的$http向接口发起请求,里面的回调写法感觉很好看,最近用jquery,也找到相同的写法,展示于此处。

jq Ajax中的Promise

常规的ajax写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
$.ajax({
type : "post",
dataType : "json",
url : "project_getProJect.action",
async : true,//默认就是true,表示异步
data:{proUuid:uuid},
success : function(result) {
},
error: function(error){
},
complete: function(){
}
});

为了方便使用ajax,封装如下:

1
2
3
4
5
6
7
8
function AjaxServer(url,data){
return $.ajax({
type:'POST',
url:url,
data:data,
dataType:'json'
});
}

阅读全文 »

seajs使用中的坑

发表于 2016-09-21 | 更新于: 2019-07-10 | 分类于 前端 | 评论: | 阅读次数:

早有耳闻模块化的优点,最近在使用的过程中才慢慢加深了感触,恩…确实方便,下面讲讲我遇到的坑,提一下,seajs是CMD规范

seajs约定的书写规范:

1
2
var path='./test';
require(path);

恩,没错,这样是错误的。require只能使用直接量,即:字符串常量

替换的方案:

1
2
3
4
var moduleName='test';
require.async('./'+moduleName,function(m){
m.render();
})

阅读全文 »

Grunt实例全解

发表于 2016-08-29 | 更新于: 2019-07-10 | 分类于 杂说 | 评论: | 阅读次数:

早闻自动化部署大名,可惜我性子懒散,至今才了解了解。官网看了是一头雾水,直到跟着叶小钗一笔一画,才了解这个Grunt是怎么一回事,回头再看官方案例。对它也再无神秘的面纱,纸上得来终觉浅,绝知此事要躬行。

安装grunt的环境

首先需要node环境,用npm安装grunt

1
npm install -g grunt-cli

基础实例

新建一个空文件夹,并添加两个文件:package.json与Gruntfile.js

这两个文件要在项目的根目录下

新建的grunt项目

package.json中添加如下代码,Gruntfile.js中暂且不管:

1
2
3
4
5
6
7
8
9
10
{
"name": "my-project-name",
"version": "0.1.0",
"devDependencies": {
"grunt": "~0.4.5",
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-nodeunit": "~0.4.1",
"grunt-contrib-uglify": "~0.5.0"
}
}

调用npm命令安装:

1
npm install

结果如图:
npm install后结果图

阅读全文 »

.shtml中include标签的用法

发表于 2016-07-13 | 更新于: 2019-07-10 | 分类于 前端 | 评论: | 阅读次数:

我们的html文件类似的有.shtml、shtm,这种和html文件的区别在于:

  • html是一种静态生成的页面
  • shtml是一种基于SSI(Server Side Include)技术的文件,它的机制是动态包含。
    • SSI 就是在 HTML 文件中,可以通过注释行调用的命令;
    • 当我们向 web服务器比如 apache 请求访问页面时,如果解析到其中有 SSI 包含指令时,就会自动包含被包含的页面;
    • 包含动作是在每次用户请求页面时发生,所以如果被包含的页面内容有变化,也能实时的反应出来,正因为如此,就很容易用来实现静态页面的动态嵌入,我们就可以把出现很多的重复区域内容发布成一个独立静态页面,然后在需要的地方用SSI指令包含进去,比如像全站的头部和尾部,全站最新新闻等等;

深入理解参考:http://www.cnblogs.com/zichi/p/5111159.html

那么,常用的SSI指令是什么呢?是include,用例如下:

1
2
<!-- 通过注释的方法来嵌入 -->
<!--#include virtual="/modelExample/common/title.shtml"-->

阅读全文 »

js我们应该知道的

发表于 2016-07-08 | 更新于: 2019-07-10 | 分类于 前端 | 评论: | 阅读次数:

eval()方法的替换方法

js里有个神奇的方法:eval(),但是不建议使用,原因看看知乎的回答,但是有时候我们确实需要一个这样作用的方法,下面是替换的方法:
来源于这位前辈的文章

1
2
3
4
5
//计算表达式的值
function evil(fn) {
var Fn = Function; //一个变量指向Function,防止有些前端编译工具报错
return new Fn('return ' + fn)();
}

解释一下:
我们创建方法通常有三种方式:

1
2
3
4
5
6
7
8
/*1.函数声明*/
function fun(){}
/*2.函数表达式*/
var aaa=function(){}
/*3.用Function构造函数:
* 可接受多个参数,但最后一个参数总是函数体,前面的才是新方法的参数
*/
var aaa=new Function(arg1,arg2...argn);

所以,利用Function()构造方法就可以实现eval()的功能

阅读全文 »

git常用命令

发表于 2016-06-24 | 更新于: 2020-08-07 | 分类于 杂说 | 评论: | 阅读次数:

仅以此记录自己常忘记的命令

基本配置

安装完之后需要一些基本配置:

  1. 生成公钥私钥: ssh-keygen
  2. 在配置用户名和邮箱:

    1
    2
    $ git config --global user.name "用户名"
    $ git config --global user.email "邮箱"
  3. 可以用 git config --list 查看配置,所有的自定义配置存放在 ~/.gitconfig 里

本地仓库 关联 远程仓库

1
git remote add origin 远程git仓库地址

如果是 git clone 下来的仓库,本地仓库与远程仓库是自动关联的。有时候我们本地做了demo,做完之后想上传到github去,就在github上新建了一个仓库,但加上了init README,当我用上面的命令将本地仓库与远程仓库关联之后,由于远程仓库有 README.md 文件,所以需要先 pull , 但报了下面的错误:

1
2
fatal: refusing to merge unrelated histories
Error redoing merge 1234deadbeef1234deadbeef

解决方案:

1
git pull origin master --allow-unrelated-histories # git 2.9后可用

本地分支 关联 远程分支

1
git branch --set-upstream-to=origin/master master

创建新分支并关联到远程分支,需要先commit或stash本地change

1
git checkout -b 本地分支名x origin/远程分支名x

创建新分支并关联到远程分支,不需要先commit或stash本地change。直接以远程分支名生成本地分支名,本地的change依然存在

1
git checkout -t origin/远程分支名x

查看本地分支与远程分支的关联关系

1
git branch -vv

如果关联错了先取消与远程仓库的关联,再重新关联分支

1
git remote remove origin # 注意是取消了仓库的关联,还需要重新关联仓库

阅读全文 »
1…5678
堂

堂

道不同不相为谋,懒懒的继续编程......

74 日志
8 分类
49 标签
RSS
GitHub 知乎 QQ群
Creative Commons
友情链接
  • 飞哥的博客
  • 治元的博客
  • 长安曹公子
  • IT姑凉博客
0%
© 2020 堂
由 Hexo 强力驱动
|
主题 — NexT.Gemini v6.1.0