/**
* moyuQuery的大部分API方法名和jQuery保持一致,可以结合jQuery的文档来阅读本库
* www.moyu-edu.com
*
*/
//立即函数自执行
//把window传进来,可以不用每次访问都去全局作用域,提高代码执行速度
//因为在有的低版本IE中undefined的值有可能改写,所以传进来,但是调用的时候实参没有这个,所以保证是正确的undefined
;(function(window,undefined){
//代码9到96行的作用在于选择出来了我们要的一组DOM对象,并存到我们的moyuQuery对象中作为一个属性名为arr的数组中
//moyuQuery构造器
function moyuQuery(str){
//防止非法访问
if(this === window){
return new moyuQuery(str);
}
//Sizzle解析引擎,模拟jQuery的sizzle
function Sizzle(str){
var str = str.toLowerCase();
//如果是类似$("#abc")这样的形式,直接返回,提高性能
var quickMatchIdReg = /^#[a-z]+$/;
if(quickMatchIdReg.test(str)){
return [document.getElementById(str)];
}
var list = str.split(" ");
var eleArr = [];
var tempArr = [];
for(var i=0;i<list.length;i++){
if(eleArr.length === 0){
eleArr = manipuEasyDom(list[i],document);
}else{
tempArr = [];//每次进来执行的时候置空tempArr
for(var j=0;j<eleArr.length;j++){
tempArr = tempArr.concat(manipuEasyDom(list[i],eleArr[j]));
}
eleArr = tempArr;
}
}
// 只考虑了最简单的三种情况选择器 id,class,标签
function manipuEasyDom(str,fatherDom){
var reg1 = /^#(\w+)/;//匹配id
var reg2 = /^\.(\w+)/;//匹配class
var reg3 = /^\w+/;//匹配标签
var myArr = [];
//str代表的是传进来的参数 "#abc" ".abc" "abc"
if(reg1.test(str) === true){
var arr = reg1.exec(str);
//console.log(arr);
var oDiv = fatherDom.getElementById(arr[1]);
myArr.push(oDiv);
}
if(reg2.test(str) === true){
var arr = reg2.exec(str);
var aList = fatherDom.getElementsByClassName(arr[1]);
myArr = Array.prototype.slice.call(aList,0);
}
if(reg3.test(str) === true){
var aList = fatherDom.getElementsByTagName(str);
myArr = Array.prototype.slice.call(aList,0);
}
return myArr;
}
return eleArr;
}
//判断是 $(function(){})、$("#demo") 还是其他的调用类型
switch(typeof str){
case "function"://如果是$(function(){})这种方式,那就是简写的ready形式
moyuQuery.ready(str);
break;
case "string"://只考虑像 $("#a div") $(".a div") $("div .item") $("div") $(".item") $("#a")这些形式,不考虑伪类、CSS3选择器
this.arr = Sizzle(str);
break;
case "object":
//说明是用getElementsByTagName,getElementsByClassName选择出来的
if(str.toString().indexOf("Element") > -1){
this.arr = [str];
//说明是用getElementsByTagName,getElementsByClassName选择出来的
}else if(str.toString().indexOf("Collection") > -1){
this.arr = str;
//出错了
}else{
return {};
}
break;
default:
//出错了
return {};
break;
}
}
//eq就是等于的意思
//eq(0) --> 把arr数组的第1个拿出来
moyuQuery.prototype.eq = function(num){
return new moyuQuery(this.arr[num]);
}
//获取第一个元素DOM对象并转换成moyuQuery对象
moyuQuery.prototype.first = function(){
return new moyuQuery(this.arr[0]);
}
//获取最后一个元素DOM对象并转换成moyuQuery对象
moyuQuery.prototype.last = function(){
return new moyuQuery(this.arr[this.arr.length - 1]);
}
//求整个moyuQuery对象中的DOM元素的个数
moyuQuery.prototype.length = function(){
return this.arr.length;
}
//求整个moyuQuery对象中的DOM元素的个数
moyuQuery.prototype.size = moyuQuery.prototype.length;
//+++++++++++++++++++++++++++++事件模块开始+++++++++++++++++++++++++++++++++++++++++++
//on相当于给this.arr里所有的元素对象加事件
moyuQuery.prototype.on = function(eventType,fn){
for(var i=0;i<this.arr.length;i++){
this.arr[i].addEventListener(eventType,fn,false);
}
return this;
}
//给一些常见的事情设置一些快捷方式,比如click可以直接 $("div").click(function(){})这样用
var eventList = 'click mouseover mouseout mousedown mousemove mouseup keydown keyup dblclick contextmenu input propertychange change blur focus resize scroll load'.split(" ");
for(var i=0;i<eventList.length;i++){
//这里用到了闭包的技巧
moyuQuery.prototype[eventList[i]] = (function(eventType){
var eventFn = function(fn){
this.on(eventType,fn);
}
return eventFn;
})(eventList[i]);
}
//ele.removeEventListener("click",fnName);
//off相当于给this.arr里面所有的元素对象移除事件
moyuQuery.prototype.off = function(eventType,fn){
for(var i=0;i<this.arr.length;i++){
this.arr[i].removeEventListener(eventType,fn);
}
return this;
}
//类似css中的hover伪类
moyuQuery.prototype.hover = function(fn1,fn2){
for(var i=0;i<this.arr.length;i++){
this.arr[i].addEventListener("mouseenter",fn1,false);
this.arr[i].addEventListener("mouseleave",fn2,false);
}
}
//++++++++++++++++++++++++++++++++事件模块结束++++++++++++++++++++++++++++++++++++++++
//++++++++++++++++++++++++++++++++DOM模块开始++++++++++++++++++++++++++++++++++++++++
//show给this.arr里所有的元素让它显示出来
moyuQuery.prototype.show = function(){
for(var i=0;i<this.arr.length;i++){
this.arr[i].style.display = "block";
}
return this;
}
//hide给this.arr里所有的元素让它隐藏出来
moyuQuery.prototype.hide = function(){
console.log(this.arr);
for(var i=0;i<this.arr.length;i++){
this.arr[i].style.display = "none";
}
return this;
}
//如果显示,就隐藏,否则显示
moyuQuery.prototype.toggle = function(){
for(var i=0;i<this.arr.length;i++){
this.arr[i].addEventListener("click",function(){
if(getStyle(this).display === "block"){
this.style.display = "none";
}else{
this.style.display = "block";
}
},false);
}
}
//获取计算后样式
function getStyle(ele){
if(window.getComputedStyle){
return getComputedStyle(ele);
}else{
return ele.currentStyle;
}
}
//如果传进来一个参数是获取,否则是设置
moyuQuery.prototype.css = function(styleName,styleValue){
if(styleValue === undefined){
return getStyle(this.arr[0])[styleName];
}else{
for(var i=0;i<this.arr.length;i++){
this.arr[i].style[styleName] = styleValue;
}
}
}
//如果传进来一个参数是获取,否则是设置
moyuQuery.prototype.attr = function(attrName,attrValue){
if(attrValue === undefined){
return this.arr[0].getAttribute(attrName);
}else{
for(var i=0;i<this.arr.length;i++){
this.arr[i].setAttribute(attrName,attrValue);
}
}
}
//如果传进来一个参数是获取,否则是设置
moyuQuery.prototype.val = function(valName,valValue){
if(valName === undefined){
return this.arr[0][valName];
}else{
for(var i=0;i<this.arr.length;i++){
this.arr[i][valName] = valValue;
}
}
}
// 给this.arr里所有的元素加一个className "abc def"
moyuQuery.prototype.addClass = function(str){
for(var i=0;i<this.arr.length;i++){
//"abc" "abc def"
this.arr[i].className += " " + str;
}
}
//移出类名
moyuQuery.prototype.removeClass = function(str){
for(var i=0;i<this.arr.length;i++){
//"abc def abc"
var reg = new RegExp("\\b" + str + "\\b","g");
this.arr[i].className = this.arr[i].className.replace(reg,"");
// this.arr[i].className += " " + str;
}
}
//如果存在(不存在)就删除(添加)一个类。
//原型
moyuQuery.prototype.toggleClass = function(str){
for(var i=0;i<this.arr.length;i++){
var reg = new RegExp("\\b" + str + "\\b","g");
"abc def"
if(reg.test(this.arr[i].className) === true){
this.arr[i].className = this.arr[i].className.replace(reg,"");
}else{
this.arr[i].className += " " + str;
}
}
}
// myObj.html("abc");
moyuQuery.prototype.html = function(str){
if(str === undefined){
return this.arr[0].innerHTML;
}
for(var i=0;i<this.arr.length;i++){
this.arr[i].innerHTML = str;
}
}
//参考innerText的功能
moyuQuery.prototype.text = function(str){
if(str === undefined){
return this.arr[0].innerText;
}
for(var i=0;i<this.arr.length;i++){
this.arr[i].innerHTML = str;
}
}
//清空moyuQuery中的DOM对象的innerHTML
moyuQuery.prototype.empty = function(){
for(var i=0;i<this.arr.length;i++){
this.arr[i].innerHTML = "";
}
}
//删除moyuQuery中的DOM对象
moyuQuery.prototype.remove = function(){
for(var i=0;i<this.arr.length;i++){
this.arr[i].parentNode.removeChild(this.arr[i]);
}
}
//获取和设置
moyuQuery.prototype.width = function(widthValue){
if(widthValue === undefined){
return getStyle(this.arr[0]).width;
}else{
for(var i=0;i<this.arr.length;i++){
this.arr[i].style.width = widthValue + "px";
}
}
}
//获取和设置
moyuQuery.prototype.height = function(heightValue){
if(heightValue === undefined){
return getStyle(this.arr[0]).height;
}else{
for(var i=0;i<this.arr.length;i++){
this.arr[i].style.height = heightValue + "px";
}
}
}
moyuQuery.prototype.innerWidth = function(){
var styleObj = getStyle(this.arr[0]);
return parseInt(styleObj["width"]) + parseInt(styleObj["paddingLeft"]) + parseInt(styleObj["paddingRight"]);
}
moyuQuery.prototype.innerHeight = function(){
var styleObj = getStyle(this.arr[0]);
return parseInt(styleObj["height"]) + parseInt(styleObj["paddingTop"]) + parseInt(styleObj["paddingBottom"]);
}
moyuQuery.prototype.outerWidth = function(check){
var styleObj = getStyle(this.arr[0]);
if(check === true){
return parseInt(styleObj["width"]) + parseInt(styleObj["paddingLeft"]) + parseInt(styleObj["paddingRight"]) + parseInt(styleObj["borderLeftWidth"]) + parseInt(styleObj["borderRightWidth"]) + parseInt(styleObj["marginLeft"]) + parseInt(styleObj["marginRight"]);
}else{
return parseInt(styleObj["width"]) + parseInt(styleObj["paddingLeft"]) + parseInt(styleObj["paddingRight"]) + parseInt(styleObj["borderLeftWidth"]) + parseInt(styleObj["borderRightWidth"]);
}
}
moyuQuery.prototype.outerHeight = function(){
var styleObj = getStyle(this.arr[0]);
if(check === true){
return parseInt(styleObj["height"]) + parseInt(styleObj["paddingTop"]) + parseInt(styleObj["paddingBottom"]) + parseInt(styleObj["borderTopWidth"]) + parseInt(styleObj["borderBottomWidth"]) + parseInt(styleObj["marginTop"]) + parseInt(styleObj["marginBottom"]);
}else{
return parseInt(styleObj["height"]) + parseInt(styleObj["paddingTop"]) + parseInt(styleObj["paddingBottom"]) + parseInt(styleObj["borderTopWidth"]) + parseInt(styleObj["borderBottomWidth"]);
}
}
//获取当前元素与CSS定位上的父级的偏移量
moyuQuery.prototype.offset = function(){
return {
left:this.arr[0].offsetLeft,
top:this.arr[0].offsetTop
};
}
function getPos(ele){
var posObj = {
left:ele.offsetLeft + parent.clientLeft - parent.scrollLeft,
top:ele.offsetTop + parent.clientTop- parent.scrollTop
}
var parent = ele.offsetParent;
while(parent!=null){
posObj.left += parent.offsetLeft + parent.clientLeft - parent.scrollLeft;
posObj.top += parent.offsetTop + parent.clientTop- parent.scrollTop;
parent = parent.offsetParent;
}
return posObj;
}
// 把moyuQuery中的DOM对象包一层父级
moyuQuery.prototype.position = function(){
return getPos(this.arr[0]);
}
moyuQuery.prototype.scrollLeft = function(){
return this.arr[0].scrollLeft;
}
moyuQuery.prototype.scrollTop = function(){
return this.arr[0].scrollTop;
}
//获取第1个DOM对象与视窗的偏移坐标
moyuQuery.wrap = function(str){
var fragment = document.createDocumentFragment();
var oDiv = document.createElement("div");
fragment.appendChild(oDiv);
oDiv.innerHTML = str;
var myEle = oDiv.children[0];
for(var i=0;i<this.arr.length;i++){
var myEle1 = myEle.cloneNode(true);
this.arr[i].parentNode.insertBefore(myEle1,this.arr[i]);
myEle1.appendChild(this.arr[i]);
}
}
//把当前的DOM对象这一层去掉
moyuQuery.prototype.unwrap = function(){
for(var i=0;i<this.arr.length;i++){
//找出来所有的当前DOM对象的子元素,先加到对应的位置,再把当前DOM对象删除掉
var myChildren = this.arr[i].children;
for(var j=0;j<myChildren.length;j++){
this.arr[i].parentNode.insertBefore(this.arr[i].children,this.arr[i]);
}
this.arr[i].parentNode.removeChild(this.arr[i]);
}
}
//++++++++++++++++++++++++++++++++DOM模块结束++++++++++++++++++++++++++++++++++++++++
//++++++++++++++++++++++++++++++++ajax&jsonp模块开始++++++++++++++++++++++++++++++++++++++++
//jsonp方式获取数据
moyuQuery.jsonp = function(link,fn){
window.fn = fn;
var oScript = document.createElement("script");
oScript.src = link;
}
//args代表的是传的参数
moyuQuery.get = function(link,args,fn){
var xhr = null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open("GET",link+"?a="+(new Date()).getTime()+"&"+args);
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200){
if(typeof fn === "function"){
fn();
}
}
}
xhr.send(null);
}
//ajax的POST方式提交数据
moyuQuery.post = function(){
var xhr = null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open("POST",link);
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200){
if(typeof fn === "function"){
fn();
}
}
}
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send(args);
}
//++++++++++++++++++++++++++++++++ajax&jsonp模块结束++++++++++++++++++++++++++++++++++++++++
//缓存数据
moyuQuery.prototype.data = function(valName,valValue){
if(valValue === undefined){
return this[valName];
}else{
this[valName] = valValue;
}
}
//表单序列化
moyuQuery.prototype.serialize = function(){
var list = this.arr[0].getElementsByTagName('*');
var tempStr = "";
for(var i=0;i<list.length;i++){
if(list[i].tagName.toLowerCase() === "input"){
if(list[i].getAttribute("type").search(/text|password|email|date|range|color|url/)){
tempStr += list[i].getAttribute("name") + "=" + list[i].value + "&";
}
}
}
return tempStr.replace(/&$/,"");
}
//裁剪
moyuQuery.prototype.slice = function(m,n){
this.arr.slice(m,n);
return this;
}
//插件化
moyuQuery.prototype.extend = function(obj){
for(var i in obj){
this[i] = obj[i];
}
}
//each
//fn默认形参 index ele
moyuQuery.prototype.each = function(fn){
for(var i=0;i<this.arr.length;i++){
fn.call(window,i,this.arr[i]);
}
}
//当DOM载入就绪可以查询及操纵时绑定一个要执行的函数。
moyuQuery.ready = function(fn){
if(document.addEventListener){
document.addEventListener("DOMContentLoaded",function(){
if(typeof fn === "function"){
fn();
}
},false);
}else{
document.onreadystatechange = function(evt){
evt = evt || event;
if(evt.readyState === "complete"){
if(typeof fn === "functioin"){
fn();
}
}
}
}
}
moyuQuery.each = function(arr,fn){
for(var i=0;i<arr.length;i++){
fn(i,arr[i]);
}
}
//exObj对象的属性拷贝到srcObj身上
moyuQuery.extend = function(srcObj,exObj){
for(var i in exObj){
srcObj[i] = exObj[i];
}
}
//检测该字符串是否像数字
moyuQuery.isNumeric = function(str){
if(typeof str === "number"){
return true;
}
var reg = /^\d+$/;
if(reg.test(str)){
return true;
}else{
return false;
}
}
//检测是否是数组类型数据
moyuQuery.isArray = function(arr){
if(Object.prototype.toString.call(arr).indexOf("Array") > -1){
return true;
}else{
return false;
}
}
moyuQuery.isPlainObject = function(obj){
if(Object.prototype.toString.call(obj) === "[object Object]"){
return true;
}else{
return false;
}
}
moyuQuery.type = function(ele){
switch(Object.prototype.toString.call(ele)){
case "[object Array]":
return "array";
break;
case "[object Date]":
return "date";
break;
case "[object RegExp]":
return "regexp";
break;
case "[object String]":
return "string";
break;
case "[object Function]":
return "function";
break;
case "[object Number]":
return "number";
break;
case "[object Boolean]":
return "boolean";
break;
case "[object Null]":
return "null";
case "[object Undefined]":
return "undefined";
break;
}
}
moyuQuery.merge = function(arr1,arr2){
return arr1.concat(arr2);
}
//保证数组中没有元素相同,去重
moyuQuery.unique = function(arr1){
var arr = [];
for(var i=0;i<arr1.length;i++){
if(arr.indexOf(arr1[i]) === -1){
arr.push(arr[i]);
}
}
return arr;
}
moyuQuery.makeArray = function(list){
return Object.prototype.slice.call(list);
}
moyuQuery.inArray = function(item,arr){
if(arr.indexOf(item) > -1){
return true;
}else{
return false;
}
}
//过滤函数
moyuQuery.grep = function(arr,fn){
var myArr = [];
for(var i=0;i<arr.length;i++){
if(fn(arr[i]) === true){
myArr.push(arr[i]);
}
}
return myArr;
}
moyuQuery.noop = function(){}
moyuQuery.trim = function(str){
var reg = /^\s+|\s+$/g;
return str.replace(reg,"");
}
moyuQuery.map = function(arr,fn){
var newArr = [];
for(var i=0;i<arr.length;i++){
newArr.push(fn(arr[i]));
}
return newArr;
}
//把"background-color"转换成"backgroundColor"
moyuQuery.camelCase = function(str){
var reg = /-(\w)/g;
return str.replace(reg,function(a,b){
return b.toUpperCase();
});
}
//检查元素的
moyuQuery.now = function(){
return (new Date());
}
//防冲突
moyuQuery._$ = window.$;
moyuQuery.noConflict = function(){
window.$ = moyuQuery._$;
}
moyuQuery.VERSION = "0.01";
//var a = 1;
//window.a = a;
//暴露给全局只有moyuQuery和$对象
window.moyuQuery = moyuQuery;//设置了一个全局变量名字叫$,值是moyuQuery
window.$ = moyuQuery
}(window));