PaddyWang
paddy-03.js 较完善
paddy 对象是一个伪数组
paddy 框架里面所有的处理对象都是按照伪数组 paddy 来处理的
这样做的好处就是:不管传过来的参数是什么类型的都把它包装成 paddy 对象
并做了兼容性处理
分为以下几个模块进行实现:
(function(windown, undefined){
function paddy(p){
return new paddy.fn.init(p);
}
windown.P = windown.paddy = paddy;
})(windown);
对传入的参数 p 进行判断
等页面加载完成之后再进行执行的函数体
有三种处理方法:
1 > 在IE中执行顺序会出现问题
window.onload = fn;
if(window.addEventListener){
window.addEventListener('load', fn);
}else {
window.attachEvent('onload', fn);
}
2 >
var arr = [ ];
function load( fn ){
arr.push( fn );
wondow.onload = function( ){
for(var i = 0; i < arr.length; i++){
arr[ i ]( );
}
}
}
3 >
function load( fn ){
var oldLoad = window.onload;
if(typeof oldLoad != 'function'){
window.onload = fn;
}else {
oldLoad( );
fn( );
}
}
添加静态方法和添加实例方法公用一个 extend 方法
paddy-03.js 采用的是在沙箱全局声明一个 select 函数
paddy-04.js 则把 select 当成 paddy 的一个静态方法来处理
id选择器:
需要注意的是:当页面中没有指定 id 的标签时会返回 null
此时的处理是:进行判断如果不为 null 则添加到数组中 否则将数组赋值为 null
class选择器:
在IE低版本中不支持 getElementsByClassName 方法
兼容处理:
判断技巧:
tag 和 * 选择器:
将标签和 * 选择器放一块处理是因为它们公用一个 getElementsByTagName 方法
这里采用了一个小技巧:利用 exec 方法的返回值,匹配到有值,匹配不到 undefined
扩展:
为了让选择引擎更加强大可以调用 select.js (暂时实现了基本选择器和后代选择器)
也可以调用 jQuery 的 Sizzle.js
paddy.select = Sizzle;
'<div><div>div</div><p>p</p></div>'
当传入的是 html 字符串时,需要将其解析成对应的标签
利用的是 innerHTML 可以将 html 字符串解析成对应的标签这一特性
再将解析出来的标签放入一个数组中,并返回
最后再把 select 和 parseHTML 方法添加到 paddy 的静态成员上
- 两个参数:一是数组或对象,二是回调函数
当为数组时进行 for 循环遍历
当为对象时进行 for-in 循环遍历
回调函数可以传入两个参数:一个是循环的当前项,一个是当前项的值,即键值对
这里的回调函数用 call 上下文调用的
将函数中的 this 指向到循环的当前项的值
当回调函数返回 false 时,则终止循环
注意:如果数组里面是基本类型的值则 this 会把基本类型的值变成包装对象
- 去除字符串两端的空格
IE 低版本中不支持该方法
兼容性处理:进行 replace 字符串两端空格替换为 ''
- 将调用者添加到指定的对象中,并返回调用者 paddy 对象
调用者是 paddy 对象,指定者也是 paddy 对象
循环遍历指定对象和调用者对象
方法 1 > 通过双重 for 循环进行遍历
方法 2 > 通过 each 套 each 的方法进行双重循环遍历
最终都是通过 appendChild 方法将调用者添加到指定对象中
为了达到链式编程的效果这里返回的是 paddy 对象
注意:每个标签对象只能有一个父元素
所以要对标签进行深克隆
在进行克隆的时候进行判断
如果是指定对象的最后一个标签则不需要进行克隆
这里通过指定对象的长度来进行判断
demo
P('<div><p>p</p><div>').appendTo('.box');
// 将 P 中的的标签添加到所有的 .box 中
P('.div').appendTo('.box');
// 将所有的 .div 标签添加到 .box 中
将指定对象添加到调用者中,返回指定对象 paddy
直接调用appendTo方法即可
demo
P('.box').append('<div><p>p</p><div>');
// 将 append 中的的标签添加到所有的 .box 中
P('.box').appendTo('.div');
// 将所有的 .div 标签添加到 .box 中
移除调用者元素 ,无返回值
each 遍历,removeChild
demo
P('.box').remove( );
// 移除所有的 .box
- 将调用者添加到指定对象的最前面,返回调用者 paddy 对象
firstChild(dom)
node.firstChild 用于获取 node 节点的第一个子节点, 包括换行和文本
node.firstElementChild 用于获取 node 节点的第一个子标签节点, IE 低版本不支持
于是需要一个通用的 firstChild 方法
- 兼容处理:
- 获取 node 的所有子节点进行循环遍历
- 通过 nodeType 进行节点类型判断
demo
P('<div>div</div>').prependTo('.box');
// 将 P 中的元素添加到所有的 .box 最前面
P('.div').prependTo('.box');
// 将所有的 .div 元素添加到所有的 .box 最前面
将指定元素添加到调用对象最前面,返回指定对象 paddy 对象
内部直接调用 prependTo 方法
demo
P('.box').prepend('<div>div</div>');
// 将 prepend 中的指定元素添加到所有的 .box 中
P('.box').prepend('.div');
// 将 prepend 中的所有的 .div 元素添加到所有的 .box 中
获取下一个兄弟标签元素 ,无参数, 返回符合要求的标签元素的 paddy 对象
node.nextSibling 获取下一个元素, 包含换行和空格
node.nextElementSibling 获取下一个标签元素, IE 低版本不支持
nextSibling(dom)
- 兼容处理:
- 通过 while 循环的同时进行赋值
- 在赋值的同时再进行判断
- 当 = 右边为空时跳出循环
while(dom = dom.nextSibling){ }
demo
P('div').next( );
// 获取所有的 div 标签的下一个标签元素
获取后面的所有的兄弟标签,无参数, 返回所有的符合要求的 paddy 对象
思路和处理方式同上
demo
P('#box').nextAll( );
// 返回 #box 后面的所有兄弟标签
P('div').nextAll( );
// 返回所有 div 标签后面的所有兄弟标签
// 这里会出现重复的标签
给实例对象添加一个 each 方法
用于遍历 paddy 对象,传入一个回调函数
回调函数内的 this 指向每个 DOM 对象
内部调用了 paddy 对象的 each 静态方法
demo
P('div').each(function(){ });
// 对 paddy 对象进行循环遍历
给 paddy 对象添加一个 Event 对象
Event 为自定义事件对象
该对象中包含对原始事件对象 e 的修改
实际上是对 e 的属性进行处理
并将 Event 的原型对象的 constructor 设值
用于绑定事件
可以同时绑定一个或多个事件
多个事件通过 , 号分隔
实现思路:
遍历当前调用对象,给每个对象绑定由 on 指定的事件
同时将事件通过 split 分开,并进行遍历
用 call 调用回调函数,并将自定义的 Event 对象作参数传进行
demo
P('div').on('click, keydown', fn);
// 给所有的 div 标签添加 click 和 keydown 事件
用于移除绑定的事件
需要注意的是:
移除的对应事件中的回调函数要与 on 绑定的一致
即:同一个函数
通过 each 遍历添加单独的事件
给每个原型上遍历,动态添加每个单独的事件
鼠标经过和离开时触发
两个参数 fn1 ,fn2
经过执行 fn1 ,离开执行 fn2
demo
P('#box').hover(fn1, fn2);
// 鼠标经过 #box 时执行 fn1 ,离开时执行 fn2
鼠标点击时触发
可以传一个或多个参数
demo
P('#box').toggle(fn1, fn2, fn3...);
// 鼠标点击 #box 第一次执行 fn1 ,点击第二次执行 fn2 ...
// 点击一圈之后继续从 fn1 开始
获取或设置css样式
当一个参数时:用于获取当前对象的样式,这里获取的是第一个对象的样式
当两个参数时:第一个代表样式属性,第二个代表属性的值
当一个 json 格式的样式时,可以设置多个样式
实现思路:
函数有两个形参,先判断第一个形参是否是一个对象
如果第一个参数是一个对象,则直接遍历调用对象,
并参数对象遍历添加到调用对象的样式上
两个参数时:
如果第二个参数不存在则代表获取样式值
这里用的是 window 对象上计算后的样式
window.getComputedStyle(this[0])[cssName];
否则则是对一个样式进行赋值
demo
P('#box').css('width');
// 获取 #box 的 width 样式值
P('#box').css('width', '300px');
// 设置 #box 的width 的值为 300px
P('div').css({
width: '300px',
height: '100px'
});
// 给所有的 div 标签设置 width 和 height 样式值
// width 等键可加引号也可不加
判断调用对象是否含有指定的 class
这里查找的是调用对象的第一个对象
demo
P('div').hasClass('box');
// 查找第一个 div 标签是否含有 box 类名
// 如果存在返回 true ,否则返回 false
给所有的调用对象添加指定的 class 值
demo
P('div').addClass('box');
// 给所有的 div 标签添加 box 类名
用于移除调用对象中的类名
有参数时删除指定的类名
没有参数时删除所有的类名
实现思路:
有参数时:先获取到调用对象的类名,
然后给类名两端添加空格
并给参数两端添加空格
最后进行 replace 匹配替换
无参数时直接设置空
demo
P('div').removeClass('box');
// 移除所有 div 标签中包含的 box 类名
P('div').removeClass();
// 移除所有 div 标签中的所有类名
调用对象有指定的类名则移除,无则添加
实现思路:
对 hasClass ,removeClass 和 addClass 的结合
调用上面封装好的三个方法即可
demo
P('div').toggleClass('box');
// 移除所有所有当前 div 标签中包含的 box 类名
// 并给所有当前 div 标签中没有 box 类名的添加一个 box 类名
获取、修改或添加属性
当一个参数的时候:获取指定的属性,只获取第一个调用对象的指定属性
当两个参数的时候,修改或添加指定的属性
实现思路:
判断是否存在第二个参数,如果不存在则进行属性获取操作
两种方法:可以以动态获取或添加属性的方法操作
也可以利用 get 或 set 进行操作
demo
P('img').attr('src');
// 获取第一个 img 标签的 src 属性
P('div').attr('title', 'haha');
// 给所有的 div 标签添加一个 title 属性,值为 ‘haha’
设置或获取指定标签的 value 值
可传入一个或不传参数
当无参数时:用于获取第一个调用对象的 value 值
当有参数时:用于设置所有调用对象的 value值
demo
P('input').val();
// 获取第一个 input 标签的 value 值
P('input').val('haha');
// 给所有的 input 标签设置 value 值为 ‘haha’
用于获取或设置 innerHTML 内容
当无参数时:用于获取第一个调用对象的 innerHTML 内容
当有参数时:用于设置所有调用对象的 innerHTML 内容
内部调用了 innerHTML 方法
demo
P('div').html();
// 获取第一个 div 标签的 innerHTML 信息
P('div').html('<p>p</p>');
// 给所有的 div 标签 innerHTML 添加一个‘<p>p</p>’
// innerHTML 会将 div 标签内的所有内容替换为 <p> 标签
用于获取或设置 innerText
无参数时:用于获取
有参数时:用于设置
兼容性解决:IE低版本不支持 innerText 方法
这里提供一个 getText 和一个 setText 方法
getText :递归获取所有的文本信息
即 nodeType === 3 时的 nodeValue 的值
setText :直接创建一个问题节点 appendChild 里面
createTextNode
demo
P('div').text();
// 获取 第一个 div 标签内个文本信息
P('div').text('<p>p</p>');
// 给所有的 div 标签设置 ‘<p>p</p>’ 字符串
动画函数:在指定时间内,以指定的效果完成指定的样式,最后执行指定的函数
四个参数:
target :样式对象,json 对象的形式
dur :执行时间,毫秒
easingName :动画效果
callback :执行完动画之后的回调函数
实现思路:
样式对象有:top | left | width | height
将其样式值看出一个总路程,然后在指定的时间内走总路程的长度
辅助性方法:
attrs :存放着样式名
getDisctance :路程处理函数
总路程 = 终止点 - 起始点
getLocation :获取初始状态的函数
easings :动画效果出来函数
setStyle :设置动画样式的函数
easing :动画效果对象 liner :匀速 | minusspeed :匀减速
t :当前时间 b :起始位置 c :终点位置 d:总时间
所有的辅助性方法都是返回一个对象
在 animate 函数中是对所有的辅助性方法返回对象的处理
demo
P('div').animate({
width: '300px',
top: '50px',
left: '100px'
}, 1000, 'liner', fn);
// 所有的 div 标签在 1000 毫秒内,
// 以匀速的效果,将宽度变为 300px,top 为50px ,left 为 100px
// 最后完成之后执行函数 fn
停止当前的动画
清除当前动画的定时器即可
判断是否有动画在执行
在最外层设置一个 timerId 属性用于记录当前是否有动画在执行
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。