原生js实现 常见的jquery的功能

 

节点操作

 

1
2
3
4
5
var div2 = document.querySelector("#div2");
  div2.insertAdjacentHTML("beforebegin","<p>hello world</p>");//在调用元素外部前面添加一个元素
  div2.insertAdjacentHTML("afterbegin","<p>hello world</p>");//在调用元素的内部添加一个子元素并取代了第一个子元素
  div2.insertAdjacentHTML("beforeend","<p>hello world</p>");//在调用元素内部后面添加一个子元素 即取代了最后的子元素
  div2.insertAdjacentHTML("afterend","<p>hello world</p>");//在调用元素的外部后面添加一个元素

 

1
2
3
4
5
var  bes=document.getElementById("appends"),
  
 var  strs=  "<li>234</li>";
                
  bes.insertAdjacentHTML('beforebegin', strs);

  

extend 普通深拷贝

 

复制代码
    
        function extend() {
               var length = arguments.length;
               var target = arguments[0] || {};
               if (typeof target!="object" && typeof target != "function") {
                   target = {};
               }
               if (length == 1) {
                   target = this;
                   i--;
               }
                var hasOwn=Object.prototype.hasOwnProperty;
               for (var i = 1; i < length; i++) {
                   var source = arguments[i];
                   for (var key in source) {
                       // 使用for in会遍历数组所有的可枚举属性,包括原型。
                       if (hasOwn.call(source, key)) {
                           target[key] = source[key];
                       }
                   }
               }
               return target;
           }
复制代码

 

1
2
3
var obj1 = {'a': 'obj2','b':'2'};
var obj2 = {name: 'obj3'};
console.log('extend',extend({},obj1,obj2),'obj1',obj1,'obj2',obj2);

 jquery 深拷贝

 

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
77
78
79
80
81
82
83
84
85
86
87
function isArray(value) {
                return Array.isArray(value) || Object.prototype.toString.call(value) === '[object Array]';
            }
 
            function isFunction(fn) {
                return Object.prototype.toString.call(fn) === "[object Function]";
            }
 
            function isPlainObject(value) {
                if (typeof value !== 'object' || value === null) {
                    return false
                }
                if (Object.getPrototypeOf(value) === null) {
                    return true
                }
                var proto = value
                while (Object.getPrototypeOf(proto) !== null) {
                    proto = Object.getPrototypeOf(proto)
                }
                return Object.getPrototypeOf(value) === proto
            }
 
 
            function myExtend() {
 
                var src, copyIsArray, copy, name, options, clone,
                    target = arguments[0] || {},
                    i = 1,
                    length = arguments.length,
                    deep = false;
 
                // Handle a deep copy situation
                if (typeof target === "boolean") {
                    deep = target;
                    target = arguments[1] || {};
                    // skip the boolean and the target
                    i = 2;
                }
 
                // Handle case when target is a string or something (possible in deep copy)
                if (typeof target !== "object" && !isFunction(target)) {
                    target = {};
                }
 
                // extend jQuery itself if only one argument is passed
                if (length === i) {
                    target = this;
                    --i;
                }
 
                for (; i < length; i++) {
                    // Only deal with non-null/undefined values
                    if ((options = arguments[i]) != null) {
                        // Extend the base object
                        for (name in options) {
                            src = target[name];
                            copy = options[name];
 
                            // Prevent never-ending loop
                            if (target === copy) {
                                continue;
                            }
 
                            // Recurse if we're merging plain objects or arrays
                            if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
                                if (copyIsArray) {
                                    copyIsArray = false;
                                    clone = src && isArray(src) ? src : [];
 
                                } else {
                                    clone = src && isPlainObject(src) ? src : {};
                                }
 
                                // Never move original objects, clone them
                                target[name] = myExtend(deep, clone, copy);
 
                                // Don't bring in undefined values
                            } else if (copy !== undefined) {
                                target[name] = copy;
                            }
                        }
                    }
                }
 
                // Return the modified object
                return target;
            }

  

 

复制代码



            var obj1 = {
                a: 1,
                name: "张珊",
                title: {
                    text: 'hello world',
                    subtext: 'It/s my world.'
                }
            };
            var obj2 = {
                a: 2,
                name: "李四",
                title: {
                    subtext: 'Yes, your world.'
                }
            }

            //var    obj3= {...{},...obj1,...obj2 }
            // Object.assign(目标对象,...源对象)可以有多个源对象
            //var obj3 =Object.assign({},obj1,obj2)
            //var    obj3= myExtend({},obj1,obj2)
        
            //console.log("$",$.version)
            //var    obj3= $.extend(true,{},obj1,obj2)
            //var    obj3= myExtend({},obj1,obj2)
            var obj3 = myExtend2({}, obj1, obj2)


            obj3.name = '王五'
            console.log("obj1", obj1);
            console.log("obj2", obj2);
            console.log("obj3", obj3, "title", obj3.title);
复制代码

 

 

去掉JSON  中的  "undefined","null"  等字符串

复制代码
    function deleteEmptyProp(opt,delArr,del) {
               var delArr=delArr||["undefined","null",undefined,null,NaN];
               for (var key in opt) {
                    var val=opt[key];
                    
                        if (delArr.includes(val)) {
                               if(del){
                                    delete opt[key]; 
                               }else{
                                   var isValueNaN= (typeof val === 'number')&&(val !== val)?1:0;//判断NaN ,替换成0
                                   if(isValueNaN){
                                       opt[key]=0;    
                                   }else{
                                       opt[key]="";   
                                   }
                                    
                               }
                        
                        }
               }
               return opt;
           }
复制代码

var sas={a: 'duo', b: 0, c: null,d:"null",e:"undefined",f:NaN,g:undefined}
console.log((deleteEmptyProp(sas)))

var sas2={a: 'duo', b: 0, c: null,d:"null",e:"undefined",f:NaN,g:undefined,h:"NaN"}
console.log(deleteEmptyProp(sas2,["undefined","null",undefined,null,NaN]))

 

 合理化 字符串

 

复制代码
 // "true"  => true
  // "false" => false
  // "null"  => null
  // "42"    => 42
  // "42.5"  => 42.5
  // "08"    => "08"
  // JSON    => parse if valid
  // String  => self
  function deserializeValue(value) {
    var num
    try {
      return value ?
        value == "true" ||
        ( value == "false" ? false :
          value == "null" ? null :
          !/^0/.test(value) && !isNaN(num = Number(value)) ? num :
          /^[\[\{]/.test(value) ? $.parseJSON(value) :
          value )
        : value
    } catch(e) {
      return value
    }
  }
复制代码

 

 

原生选择器  $('#box')   利用 bind(this)绑定 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="box">
      <ul>
        <li >111  </li>
        <li class="lione">2222</li>
        <li class="lione">3333</li>
     </ul>
      
    
</div>
 
<div id="box2">
  <p>我是AAAA</p>
     <p>我是BBBB</p>
     </div>

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//选择器的实现
var element = document.querySelector('selectors');
var elementList = document.querySelectorAll('selectors');
 
 
var $=query = document.querySelector.bind(document);
var queryAll = document.querySelectorAll.bind(document);   //这个是最牛逼的  细细体会就会发现
var fromId = document.getElementById.bind(document);
var fromClass = document.getElementsByClassName.bind(document);
var fromTag = document.getElementsByTagName.bind(document);
 
 
//调用
var box=$('#box');
var lioneall=queryAll('li');
var lione=$('.lione');
console.log(box.innerHTML);  // 
console.log(lioneall[2].innerHTML); //333
 
box.addEventListener('click',function(){   
    console.log('click lione'+lione.innerHTML);  //click lione 2222
});

 另一个不错的  https://github.com/snandy/zchain/blob/master/%24/selector.js

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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/**
 * JavaScript Selector
 * Copyright (c) 2010 snandy
 * Blog: http://snandy.cnglogs.com
 * QQ群: 34580561
 *
 * $ 获取元素, 在DOM中使用频繁的,根据2/8原则只实现最常用的四种
 *
 * @param {Object} selector
 * @param {Object} context
 *
 * 1, 通过id获取,该元素是唯一的
 *    $('#id')
 *
 * 2, 通过className获取
 *    $('.cls') 获取文档中所有className为cls的元素
 *    $('.cls', el)
 *    $('.cls', '#id')
 *    $('span.cls') 获取文档中所有className为cls的span元素
 *    $('span.cls', el) 获取指定元素中className为cls的元素, el为HTMLElement (不推荐)
 *    $('span.cls', '#id') 获取指定id的元素中className为cls的元素
 *   
 * 3, 通过tagName获取
 *    $('span') 获取文档中所有的span元素
 *    $('span', el) 获取指定元素中的span元素, el为HTMLElement (不推荐)
 *    $('span', '#id') 获取指定id的元素中的span元素
 *
 * 4, 通过attribute获取
 *    $('[name]') 获取文档中具有属性name的元素
 *    $('[name]', el)
 *    $('[name]', '#id')
 *    $('[name=uname]') 获取文档中所有属性name=uname的元素
 *    $('[name=uname]', el)
 *    $('[name=uname]', '#id')
 *    $('input[name=uname]') 获取文档中所有属性name=uname的input元素
 *    $('input[name=uname]', el)
 *    $('input[name=uname]', '#id')
 */
~function(win, doc, undefined) {
     
// Save a reference to core methods
var slice = Array.prototype.slice
 
// selector regular expression
var rId = /^#[\w\-]+/
var rTag = /^([\w\*]+)$/
var rCls = /^([\w\-]+)?\.([\w\-]+)/
var rAttr = /^([\w]+)?\[([\w]+-?[\w]+?)(=(\w+))?\]/
 
// For IE9/Firefox/Safari/Chrome/Opera
var makeArray = function(obj) {
    return slice.call(obj, 0)
}
// For IE6/7/8
try{
    slice.call(doc.documentElement.childNodes, 0)[0].nodeType
} catch(e) {
    makeArray = function(obj) {
        var result = []
        for (var i = 0, len = obj.length; i < len; i++) {
            result[i] = obj[i]
        }
        return result
    }
}
 
function byId(id) {
    return doc.getElementById(id)
}
function check(attr, val, node) {
    var reg = RegExp('(?:^|\\s+)' + val + '(?:\\s+|$)')
    var attribute = attr === 'className'
            ? node.className
            : node.getAttribute(attr)
    if (attribute) {
        if (val) {
            if (reg.test(attribute)) return true
        } else {
            return true
        }
    }
    return false
}   
function filter(all, attr, val) {
    var el, result = []
    var i = 0, r = 0
    while ( (el = all[i++]) ) {
        if ( check(attr, val, el) ) {
            result[r++] = el
        }
    }
    return result
}
     
function query(selector, context) {
    var s = selector, arr = []
    var context = context === undefined
            ? doc
            : typeof context === 'string' ? query(context)[0] : context
             
    if (!selector) return arr
     
    // id和tagName 直接使用 getElementById 和 getElementsByTagName
 
    // id
    if ( rId.test(s) ) {
        arr[0] = byId( s.substr(1, s.length) )
        return arr
    }
     
    // Tag name
    if ( rTag.test(s) ) {
        return makeArray(context.getElementsByTagName(s))
    }
 
    // 优先使用querySelector,现代浏览器都实现它了
    if (context.querySelectorAll) {
        if (context.nodeType === 1) {
            var old = context.id, id = context.id = '__ZZ__'
            try {
                return context.querySelectorAll('#' + id + ' ' + s)
            } catch(e) {
                throw new Error('querySelectorAll: ' + e)
            } finally {
                old ? context.id = old : context.removeAttribute('id')
            }
        }
        return makeArray(context.querySelectorAll(s))
    }
     
    // ClassName
    if ( rCls.test(s) ) {
        var ary = s.split('.')
        var tag = ary[0]
        var cls = ary[1]
        if (context.getElementsByClassName) {
            var elems = context.getElementsByClassName(cls)
            if (tag) {
                for (var i = 0, len = elems.length; i < len; i++) {
                    var el = elems[i]
                    el.tagName.toLowerCase() === tag && arr.push(el)
                }
                return arr
            } else {
                return makeArray(elems)
            }
        } else {
            var all = context.getElementsByTagName(tag || '*')
            return filter(all, 'className', cls)
        }
    }
 
    // Attribute
    if ( rAttr.test(s) ) {
        var result = rAttr.exec(s)
        var all = context.getElementsByTagName(result[1] || '*')
        return filter(all, result[2], result[4])
    }
}
 
win.query = win.$ = query
}(this, document);

  

offset 函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var myOffest=function (obj){
var top=0,left=0;
if(obj){
 while(obj.offsetParent){
      top += obj.offsetTop;
      left += obj.offsetLeft;
      obj = obj.offsetParent;
   }
 }
 
  return{
  top : top,
  left : left
  }
}

  

1
2
3
4
5
6
var jqtop=jQuery('#box2').offset().top;
console.log('jQuery offsetTop  值'+jqtop);  // jQuery offsetTop  值274
 
 
var jstop=document.getElementById("box2");
console.log('js offsetTop  值'+myOffest(jstop).top); // js offsetTop  值274

 

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
getOffset2(node){
         
 
    var offest = {
            top: 0,
            left: 0
        };
        // 当前为IE11以下, 直接返回{top: 0, left: 0}
        if (!node.getClientRects().length) {
            return offest;
        }
        // 当前DOM节点的 display === 'node' 时, 直接返回{top: 0, left: 0}
        if (window.getComputedStyle(node)['display'] === 'none') {
            return offest;
        }
        // Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。
        // 返回值包含了一组用于描述边框的只读属性——left、top、right和bottom,单位为像素。除了 width 和 height 外的属性都是相对于视口的左上角位置而言的。
        // 返回如{top: 8, right: 1432, bottom: 548, left: 8, width: 1424…}
        offest = node.getBoundingClientRect();
        var docElement = node.ownerDocument.documentElement;
        return {
            top: offest.top + window.pageYOffset - docElement.clientTop,
            left: offest.left + window.pageXOffset - docElement.clientLeft
        };
         
    }

  

 

offset限定父类范围

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function myOffest(obj,parentObj){
                  var top=0,left=0;
                   
                  if(obj){
                   while(obj.offsetParent){
                      if(parentObj&&obj&&obj.className.indexOf(parentObj)!=-1){
                       break;
                      }
                        left += obj.offsetLeft;
                        obj = obj.offsetParent;
                     }
                   }
                  //console.log("222  55 最后obj---",obj)
                    return{
                    left : left
                    }
                  } 

 

getOffsetParent 

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
function getOffsetParent(element) {
              // NOTE: 1 DOM access here
              var offsetParent = element && element.offsetParent;
              var nodeName = offsetParent && offsetParent.nodeName;
             
              if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {
                if (element) {
                  return element.ownerDocument.documentElement;
                }
             
                return window.document.documentElement;
              }
             
              // .offsetParent will return the closest TD or TABLE in case
              // no offsetParent is present, I hate this job...
              //console.log("window.getComputedStyle(offsetParent, null).position",window.getComputedStyle(offsetParent, null).position)
              if (['TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 &&window.getComputedStyle(offsetParent, null).position=== 'static') {
                return getOffsetParent(offsetParent);
              }
             
              return offsetParent;
            }
             
             
 
             
            

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function getOffsetParent(elem) {
     
      var doc = elem.ownerDocument||document;
     
      var offsetParent = elem.offsetParent ;
      //console.log(elem,"offsetParent",offsetParent)
      var position= offsetParent&&window.getComputedStyle(offsetParent)[ "position"]
      while (offsetParent &&(offsetParent.nodeName !== 'HTML' ) &&position=== "static") {
        offsetParent = offsetParent.offsetParent;
      }
       
      var last=offsetParent|| doc.documentElement;
       
      return offsetParent|| doc.documentElement;
     
    }

  

 

//https://github.com/jquery/jquery/blob/main/src/offset.js  

 

get_position

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
function get_position(elem) {
     
 
        var offsetParent, offset,
            elem = elem,
            parentOffset = { top: 0, left: 0 };
 
        // Fixed elements are offset from window (parentOffset = {top:0, left: 0},
        // because it is its only offset parent
        if (window.getComputedStyle(elem)['position'] === "fixed" ) {
 
            // Assume getBoundingClientRect is there when computed position is fixed
            offset = elem.getBoundingClientRect();
 
        } else {
 
 
           // Get *real* offsetParent
           offsetParent =getOffsetParent(elem);
           
           // console.log("offsetParent nodeName",offsetParent.nodeName)
            //console.log("eaas",eaas)
           // console.log("offsetParent2",offsetParent2)
           // Get correct offsets
           offset = getOffest(elem);
            
             
             
           if ( offsetParent.nodeName !="html" ) {
            parentOffset =getOffest(offsetParent);;
           }
            
           
          
           var borderTopWidth=window.getComputedStyle(offsetParent)['borderTopWidth']||0;
           var borderLeftWidth=window.getComputedStyle(offsetParent)['borderLeftWidth']||0;
            
         
            
         // Add offsetParent borders
            parentOffset.top += parseFloat(borderTopWidth);
            parentOffset.left += parseFloat(borderLeftWidth) ;
     
 
      // Subtract parent offsets and element margins
      // 可以看出,$().position()的本质是目标元素的offset()减去父元素的offset(),同时还要算上目标元素的margin,因为盒子模型(关键)。
      //(注意:offset()的本质是getBoundingClientRect()的top、left + pageYOffset、pageXOffset)
 
     
        }
         
        // Subtract parent offsets and element margins
        var marginTop=window.getComputedStyle(elem)['marginTop']||0;
        var marginLeft=window.getComputedStyle(elem)['marginLeft']||0;
              console.log(marginTop,"marginLeft",marginLeft)
               
        var  top2=parseFloat(offset.top||0) - parseFloat(parentOffset.top||0) - parseFloat(marginTop) ;
        var  left2=parseFloat(offset.left||0) - parseFloat(parentOffset.left||0) - parseFloat(marginLeft)
        return {
            top: top2 ,
            left: left2
        };
    }

  

 

setOffset 

复制代码
function setOffset(elem,props,pixel){
                var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition;
                
                //console.log("setOffset---",elem)
                 //获取元素的position属性的值
                var   position =window.getComputedStyle(elem)['position'];
                 if ( position === "static" ) {
                      elem.style.position = "relative";
                 }
                 
        
                    //{left:8,top:16}
                     curOffset = getOffest(elem);;
                  //0px
                  curCSSTop = window.getComputedStyle(elem)['top']||0;;
                  //0px
                  curCSSLeft = window.getComputedStyle(elem)['left']||0; 
                 
                   calculatePosition = ( position === "absolute" || position === "fixed" ) &&( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
                 
                         if (calculatePosition ) {
                         // curPosition = elem.position();
                            curPosition = get_position(position);
                            curTop = parseFloat(curPosition.top)|| 0;
                            curLeft= parseFloat(curPosition.left)|| 0;
    
                        } else {
                          //0 0
                          curTop = parseFloat( curCSSTop ) || 0;
                          curLeft = parseFloat( curCSSLeft ) || 0;
                        }
                 
                   //解析:
                   //(1)先判断当前元素的 position 的值,没有设置 position 属性的话,默认为 relative,并获取元素的 top、left 属性的值
                   //(2)返回一个对象 obj,obj 的 top 是参数的 top - 默认偏移(offset)的 top + position 设置的 top(没有设置,默认为0),obj 的 left 同理。
                   
                  // 也就是说 offset({top:15,;eft:15}) 的本质为:
                  // 参数的属性减去对应的默认offset属性加上position上的对应属性。    
                 
                  //如果传的参数的有top值
                
                       //参数 top - offset().top + element.top
                      var top = ( props.top - parseFloat(curOffset.top) ) + curTop;
                      //参数 left - offset().left + element.left
                      var left = ( props.left - parseFloat(curOffset.left) ) + curLeft;
                      
                      var pixel=pixel||"px" 
                      //console.log("top",top,'left',left)
                      elem.style.top= top+pixel;
                      elem.style.left= left+pixel;
                
            }
复制代码

 

 

 setOffset(p2,{top:200,left:position.left})

$(".p1").offset({top:200,left:position.left});

getOffsetRect 获取大小

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function getOffsetRect(element) {
    var elementRect = {
        width: element.offsetWidth,
        height: element.offsetHeight,
        left: element.offsetLeft,
        top: element.offsetTop
    };
 
    elementRect.right = elementRect.left + elementRect.width;
    elementRect.bottom = elementRect.top + elementRect.height;
 
    // 位置
    return elementRect;
}

  

 找到指定父类元素

1
2
3
4
5
6
7
8
9
function getParent(element, className, limitClasss) {
                var nowName = element.getAttribute("class") || "";
                var isFind = nowName && nowName.indexOf(className) !== -1 || limitClasss && nowName && nowName
                    .indexOf(limitClasss) !== -1;
                if (isFind || !element.parentNode) {
                    return element; // 已达到文档根元素,未找到指定父元素
                }
                return getParent(element.parentNode, className); // 继续向上查找
            }

 找到子元素在父元素的索引值 

1
2
3
4
5
6
7
8
9
function getChildIndex(child) {
                    var parent = child.parentNode;
                    for (var i = 0; i < parent.children.length; i++) {
                        if (parent.children[i] === child) {
                            return i;
                        }
                    }
                    return -1; // 如果找不到子元素,返回-1
                }

var liEle = getParent(target, 'li-item', 'ul-item');
var liIndex = 0;
if (liEle) {
liIndex = getChildIndex(liEle);
console.log("liIndex", liIndex)
}

  

数组 forEach的实现

var unboundForEach = Array.prototype.forEach,forEach = Function.prototype.call.bind(unboundForEach);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id="box3">
   <p class="klasses">one</p>
   <p class="klasses">two</p>
   <p class="klasses">three</p>
</div>
 
<script>
var unboundForEach = Array.prototype.forEach,forEach = Function.prototype.call.bind(unboundForEach);
  
var box3=document.getElementById("box3");
var klasses=document.querySelectorAll('.klasses')
forEach(klasses, function (el) {
    el.addEventListener('click', function(){
        alert('点击我的序号'+this.innerHTML);   //点击我的序号 one
        });
});
 
</script>

jquery的静态方法 $.each

 

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
function jQueryEach(object, callback, args) {
    var name,
    i = 0,
    length = object.length;
    if (args) {
        if (length == undefined) {
            for (name in object) {
                if (callback.apply(object[name], args) === false) {
                    break
                }
            }
        } else {
            for (; i < length;) {
                if (callback.apply(object[i++], args) === false) {
                    break
                }
            }
        }
    } else {
        if (length == undefined) {
            for (name in object) {
                if (callback.call(object[name], name, object[name]) === false) {
                    break
                }
            }
        } else {
            for (var value = object[0]; i < length && callback.call(value, i, value) !== false; value = object[++i]) {}
        }
    }
    return object
};

 

1
2
3
4
5
6
7
8
9
10
11
var arr1 = [ "one", "two", "three", "four", "five" ];
jQueryEach(arr1, function(index){
   console.log(arr1[index]);
  // alert(this)
});
 
 
var obj = { one:'张珊', two:'李四', three:3, four:4, five:'王五' };
jQueryEach(obj, function(key, val) {
    console.log('val'+obj[key]);     
});

  

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    Array.prototype.forEach2=function(fun,context){
            var len=this.length;
            var context=arguments[1];     //即使为undefined,call函数也正常运行。
            if(typeof fun !=="function"){
                throw "输入正确函数!";
            }
            for(var i=0;i<len;i++){
                fun.apply(context,[i,this[i],this]);
                //fun.call(context,i,this[i],this);
            }
 };
var arr2=[5,6,7];
//arr.forEach2(function(item,index,arr){
//console.log(item,index,arr);
//});

 

hover 方法

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
77
78
79
80
81
82
83
84
85
86
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
</head>
 
<body>
 
 
运行以下代码,正好就是jquery的hover方法
<div id="dd" style="width:100px; height:100px; border:1px solid #3d3d3d; position:relative;">
<div id="dd2" style="width:50px; height:50px; overflow:hidden; background-color:#cccccc; position:absolute; left:30px; top:30px;"></div>
</div>
 
<script language="javascript">
 
function bind(elem,ev,callback)
 {
  if(document.all)
  {
   elem.attachEvent("on"+ev,callback);
  }else{
   elem.addEventListener(ev,callback,false);
  }
 }
 function unbind(elem,ev,callback)
 {
  if(typeof(callback)=="function")
  {
   if(document.all)
   {
    elem.detachEvent("on"+ev,callback);
   }else{
    elem.removeEventListener(ev,callback,false);
   }
  }else{
   if(document.all)
   {
    elem.detachEvent("on"+ev);
   }else{
    elem.removeEventListener(ev,false);
   }
  }
 }
 function hover(elem,overCallback,outCallback){//实现hover事件
  var isHover=false;//判断是否悬浮在上方
  var preOvTime=new Date().getTime();//上次悬浮时间
   
  function over(e){
   var curOvTime=new Date().getTime();
   isHover=true;//处于over状态
   if(curOvTime-preOvTime>10)
   {//时间间隔超过10毫秒,认为鼠标完成了mouseout事件
    overCallback(e,elem);
   }
   preOvTime=curOvTime;
  }
   
  function out(e)
  {
   var curOvTime=new Date().getTime();
   preOvTime=curOvTime;
   isHover=false;
   setTimeout(function(){
    if(!isHover)
    {
     outCallback(e,elem);
    }
   },10);
  }
  bind(elem,"mouseover",over);
  bind(elem,"mouseout",out);
 };
  
  
 hover(document.getElementById("dd"),
 function(){console.log("进来1"); document.getElementById("dd2").innerHTML="进来了";},
 function(){ console.log("出来2"); document.getElementById("dd2").innerHTML="出来了";  }
 );
 
 </script>
 
 
</body>
</html>

 

1
2
3
4
5
jQuery.fn.extend( {
    hover: function( fnOver, fnOut ) {
        return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
    }
} );

  

 

 

获取文档高度

1
2
3
4
5
6
7
//获取文档完整的高度
var getScrollHeight=function () {
    return Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
}
 
console.log('jquery文档高度'+jQuery(document).height());  //jquery文档高度1739
console.log('js文档高度'+getScrollHeight()); // js文档高度1739g滚动条

滚动条高度

 

1
2
3
4
5
6
7
document.getElementById("element").addEventListener("click",function(){
    var scrollTop1 = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
    var scrollTop2 = window.scrollY||document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
    console.log('scrollTop1'+scrollTop1)
     console.log('scrollTop2'+scrollTop2)
  
});

 

  

 

样式操作 

复制代码
// jQuery  
$('.el').addClass('class');  
$('.el').removeClass('class');  
$('.el').toggleClass('class');  
  
// 原生方法  
document.querySelector('.el').classList.add('class');  
document.querySelector('.el').classList.remove('class');  
document.querySelector('.el').classList.toggle('class');

// 原生方法 扩展添加多个 
DOMTokenList.prototype.adds = function(tokens) {
   tokens.split(" ").forEach(function(token) {
       this.add(token);
   }.bind(this));
   return this;
};

// adds 添加多个
document.querySelector(".el").classList.adds("child1 child2 child3");
复制代码

 

复制代码
function hasClass(ele, cls) {
    return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}
function addClass(ele, cls) {
    if (!this.hasClass(ele, cls)) ele.className += " " + cls;
}
function removeClass(ele, cls) {
    if (hasClass(ele, cls)) {
        var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
        ele.className = ele.className.replace(reg, ' ');
    }
}
复制代码

 

获取jsonp

 

 

复制代码
function getJSONP2(url,success,jsonpCallback,jsonp){
            var jsonp=jsonp||"callback",
             cn=jsonpCallback||"jsonpCallback",
             url=url.toString(),
             dataString = url.indexOf('?') == -1? '?': '&',
            s=document.createElement("script"),
            head=document.head||document.getElementsByTagName("head")[0];
            s.type="text/javascript";
            s.charset="UTF-8";s.src=url+dataString+"_="+(+new Date)+"&"+jsonp+"="+cn;

            head.insertBefore(s,head.firstChild);
            console.log("src",s.src);
            setTimeout(function(){
                window[cn]=function(data){
                    
                    
                    try{s.onload=s.onreadystatechange=function(){
                        var that=this;
                        if((!that.readyState||that.readyState==="loaded"||that.readyState==="complete")){
                            success&&success(data);
                            s.onload=s.onreadystatechange=null;if(head&&s.parentNode){
                                head.removeChild(s)}}}}catch(e){}finally{window[cn]=null}}
                },0)};
复制代码

 

 

复制代码
   var url44="http://api.map.baidu.com/geocoder/v2/?sa=1&location=30.290466116991468,120.00192773949404&output=json&pois=1&latest_admin=1&ak=ABq5yEuwLp5Z4yWlRDGX3vEhxxjGDu8L";
        getJSONP2(url44,function(data){
            var data=data;
               data.regeocode=data.result;
        //var  address = data.regeocode.formatted_address;


            console.log(data,"结果" ,  data.regeocode.formatted_address);
            
        })
复制代码

 

 

1
2
3
4
5
6
//document.addEventListener('click',function(){
getJSONP("https://api.github.com/repos/HubSpot/pace?callback=",function(json){
   alert('success!'+ json.data.id+'获取到的'+json.data.name);
   document.getElementById("testText").innerHTML='回调函数获取到了'+json.data.name;
   document.getElementById("testText").style.cssText='color:red;font-size:22px; border:1px solid #666'
});

清楚字符串空格

复制代码
function trimStr(str){return str.replace(/(^\s*)|(\s*$)/g,"");}


function TrimAll(str,is_global){ //删除全部空格
      var result;
      result = str.replace(/(^\s+)|(\s+$)/g,"");
      if(is_global.toLowerCase()=="g")
      {
         result = result.replace(/\s/g,"");
       }
      return result;
}
复制代码

 

1
2
3
4
5
6
7
8
9
10
11
12
13
tring.prototype.trim = function() {
    return this.replace(/(^\s*)|(\s*$)/g, "");
};
String.prototype.ltrim = function() {
    return this.replace(/(^\s*)/g, "");
};
String.prototype.rtrim = function() {
    return this.replace(/(\s*$)/g, "");
};
 String.prototype.trimAll = function () { 
    return this.replace(/\s+/g, ""); 
}   

  

 cookie的操作

复制代码
function addCookie(objName,objValue,objHours){
var str = objName + "=" + escape(objValue);
if(objHours > 0){
var date = new Date();
var ms = objHours*3600*1000;
date.setTime(date.getTime() + ms);
str += "; expires=" + date.toGMTString();
}
str += "; path=/";
document.cookie = str;

};   

function getCookie (objName){
var arrStr = document.cookie.split("; ");
for(var i = 0;i < arrStr.length;i ++){
var temp = arrStr[i].split("=");
if(temp[0] == objName) return unescape(temp[1]);
}
};
复制代码

原生ajax的操作

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
 * ajax封装
 *  var xmlhttp = new YAjax();
 *    xmlhttp.request({
 *         url : "./demo.php",  // get请求时 可以这样写 "./demo.php?name=zhangsan"
 *        method : "POST",
 *        data : "name=李四",  // 支持json传值 {"name":"zhangsan"}  get时不用该参数
 *        receiveType : "html",  // json html or xml
 *        timeout : 3000,  // 3秒
          async : true,            //默认true  可省略
 *        beforeSend:function(){},   //请求之前回调函数  就得 这边beforesent  s小写  beforesend
 *        success : function(d) {alert(d);},
 *        error : function(xmlhttp){alert('timeout');}
 *    });
 */

 

  

复制代码
function YAjax() {
    this._self = this;
    this.xmlhttp = this.init()
}
YAjax.prototype = {
    constructor: YAjax,
    init: function() {
        var xmlhttp = null;
        if (window.XMLHttpRequest) {
            xmlhttp = new XMLHttpRequest();
            if (xmlhttp.overrideMimeType) {
                xmlhttp.overrideMimeType("text/xml")
            }
        } else {
            if (window.ActiveXObject) {
                var activexName = ["MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];
                for (var i = 0; i < activexName.length; i++) {
                    try {
                        xmlhttp = new ActiveXObject(activexName[i]);
                        break
                    } catch(e) {}
                }
            }
        }
        return xmlhttp
    },
    extend: function(destination, source, override) {
        if (undefined == override) {
            override = true
        }
        if (typeof destination != "object" && typeof destination != "function") {
            if (!override) {
                return destination
            } else {
                destination = {}
            }
        }
        var property = "";
        for (property in source) {
            if (override || !(property in destination)) {
                destination[property] = source[property]
            }
        }
        return destination
    },
    json2String: function(jsonData) {
        var strArr = [];
        for (var k in jsonData) {
            strArr.push(k + "=" + jsonData[k])
        }
        return strArr.join("&")
    },
    request: function(opt) {
        var _self = this,
        isTimeout = false,
        timeFlag = 0,
        options = {
            url: "",
            data: "",
            method: "POST",
            receiveType: "html",
            timeout: 7000,
            async: opt.async || true,
            beforeSend: function() {},
            success: function() {
                alert("define your success function")
            },
            error: function(xmlhttp) {}
        };
        if ("data" in opt) {
            if (typeof opt.data == "string") {} else {
                opt.data = this.json2String(opt.data)
            }
        }
        options = this.extend(options, opt);
        this.xmlhttp.onreadystatechange = function() {
            if (_self.xmlhttp.readyState == 2) {
                options.beforeSend && options.beforeSend.apply(_self.xmlhttp, arguments)
            }
            if (_self.xmlhttp.readyState == 4) {
                if (!isTimeout && _self.xmlhttp.status == 200) {
                    clearTimeout(timeFlag);
                    var t = options.receiveType.toLowerCase();
                    if (t == "html") {
                        options.success(_self.xmlhttp.responseText)
                    } else {
                        if (t == "xml") {
                            options.success(_self.xmlhttp.responseXML)
                        } else {
                            if (t == "json") {
                                try {
                                    var obj = JSON.parse(_self.xmlhttp.responseText);
                                    options.success(obj)
                                } catch(e) {
                                    var str = "(" + _self.xmlhttp.responseText + ")";
                                    options.success(JSON.parse(str))
                                }
                            } else {}
                        }
                    }
                } else {
                    clearTimeout(timeFlag);
                    options.error(_self.xmlhttp)
                }
            }
        };
        clearTimeout(timeFlag);
        timeFlag = setTimeout(function() {
            if (_self.xmlhttp.readyState != 4) {
                isTimeout = true;
                _self.xmlhttp.abort();
                clearTimeout(timeFlag)
            }
        },
        options.timeout);
        this.xmlhttp.open(options.method.toUpperCase(), options.url, options.async);
        if (options.method.toUpperCase() == "POST") {
            this.xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            this.xmlhttp.send(options.data)
        } else {
            this.xmlhttp.send(null)
        }
    }
};
复制代码

 

 

原生延迟加载插件

复制代码
/*! echo.js v1.7.0 | (c) 2015 @toddmotto | https://github.com/toddmotto/echo */
(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(function() {
      return factory(root);
    });
  } else if (typeof exports === 'object') {
    module.exports = factory;
  } else {
    root.echo = factory(root);
  }
})(this, function (root) {

  'use strict';

  var echo = {};

  var callback = function () {};

  var offset, poll, delay, useDebounce, unload,effectClass;
  var classList= 'classList' in document.documentElement ?1:0;
  var isHidden = function (element) {
    return (element.offsetParent === null);
  };
  
  var inView = function (element, view) {
    if (isHidden(element)) {
      return false;
    }

    var box = element.getBoundingClientRect();
    return (box.right >= view.l && box.bottom >= view.t && box.left <= view.r && box.top <= view.b);
  };

  var debounceOrThrottle = function () {
    if(!useDebounce && !!poll) {
      return;
    }
    clearTimeout(poll);
    poll = setTimeout(function(){
      echo.render();
      poll = null;
    }, delay);
  };

  echo.init = function (opts) {
    opts = opts || {};
    var offsetAll = opts.offset || 0;
    
    var offsetVertical = opts.offsetVertical || offsetAll;
    var offsetHorizontal = opts.offsetHorizontal || offsetAll;
    var optionToInt = function (opt, fallback) {
      return parseInt(opt || fallback, 10);
    };
    offset = {
      t: optionToInt(opts.offsetTop, offsetVertical),
      b: optionToInt(opts.offsetBottom, offsetVertical),
      l: optionToInt(opts.offsetLeft, offsetHorizontal),
      r: optionToInt(opts.offsetRight, offsetHorizontal)
    };
    delay = optionToInt(opts.throttle, 80);
    useDebounce = opts.debounce !== false;
    effectClass=opts.effectClass;
    unload = !!opts.unload;
    callback = opts.callback || callback;
    echo.render();
    if (document.addEventListener) {
      root.addEventListener('scroll', debounceOrThrottle, false);
      root.addEventListener('load', debounceOrThrottle, false);
    } else {
      root.attachEvent('onscroll', debounceOrThrottle);
      root.attachEvent('onload', debounceOrThrottle);
    }
  };

  echo.render = function () {
    var nodes = document.querySelectorAll('img[data-echo], [data-echo-background]');
    var length = nodes.length;
    var src, elem;
    var view = {
      l: 0 - offset.l,
      t: 0 - offset.t,
      b: (root.innerHeight || document.documentElement.clientHeight) + offset.b,
      r: (root.innerWidth || document.documentElement.clientWidth) + offset.r
    };
    for (var i = 0; i < length; i++) {
      elem = nodes[i];
      if (inView(elem, view)) {

        if (unload) {
          elem.setAttribute('data-echo-placeholder', elem.src);
        }

        if (elem.getAttribute('data-echo-background') !== null) {
          elem.style.backgroundImage = "url(" + elem.getAttribute('data-echo-background') + ")";
            
        }
        else {
          elem.src = elem.getAttribute('data-echo');
                 
        }
        
        
        
        if (!unload) {
         if(effectClass){
                      if (classList){    
                      elem.classList.add(effectClass);
                      }else{
                      elem.className += " " + effectClass;      
                       }
                 }    
          elem.removeAttribute('data-echo');
          elem.removeAttribute('data-echo-background');
        }

        callback(elem, 'load');
      }
      else if (unload && !!(src = elem.getAttribute('data-echo-placeholder'))) {

        if (elem.getAttribute('data-echo-background') !== null) {
          elem.style.backgroundImage = "url(" + src + ")";
        }
        else {
          elem.src = src;
        }

        elem.removeAttribute('data-echo-placeholder');
        callback(elem, 'unload');
      }
    }
    if (!length) {
      echo.detach();
    }
  };

  echo.detach = function () {
    if (document.removeEventListener) {
      root.removeEventListener('scroll', debounceOrThrottle);
    } else {
      root.detachEvent('onscroll', debounceOrThrottle);
    }
    clearTimeout(poll);
  };

  return echo;

});
View Code
复制代码

使用方法

复制代码
  <img src="img/blank.gif" alt="Photo" data-echo="img/photo.jpg">

  <script src="../echo.js"></script>
  <script>
  echo.init({
    offset: 100,
    throttle: 250,
    unload: false,
    callback: function (element, op) {
      console.log(element, 'has been', op + 'ed')
    }
  });
复制代码

 

domready(fn)

复制代码
function Domready(readyFn) {
    if (document.addEventListener) {
        document.addEventListener("DOMContentLoaded", function() {
            readyFn && readyFn()
        }, false)
    } else {
        var bReady = false;
        document.attachEvent("onreadystatechange", function() {
            if (bReady) {
                return
            }
            if (document.readyState == "complete" || document.readyState == "interactive") {
                bReady = true;
                readyFn && readyFn()
            }
        });
        setTimeout(checkDoScroll, 1)
    }
    function checkDoScroll() {
        try {
            document.documentElement.doScroll("left");
            if (bReady) {
                return
            }
            bReady = true;
            readyFn && readyFn()
        } catch (e) {
            setTimeout(checkDoScroll, 1)
        }
    }
};
View Code
复制代码

 

为元素添加on方法

Element.prototype.on = Element.prototype.addEventListener;

 

为元素添加trigger方法

1
2
3
4
5
6
7
8
9
HTMLElement.prototype.trigger = function (type, data) {
    var event = document.createEvent('HTMLEvents');
    event.initEvent(type, true, true);
    event.data = data || {};
    event.eventName = type;
    event.target = this;
    this.dispatchEvent(event);
    return this;
};

  

 获取文档完整的高度 

1
2
3
4
//获取文档完整的高度
var getScrollHeight=function () {
    return Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
}

 

获取当前可是范围的高度

1
2
3
4
5
6
7
8
9
10
11
//获取当前可是范围的高度
var getClientHeight=function () {
      var clientHeight = 0;
      if (document.body.clientHeight && document.documentElement.clientHeight) {
      clientHeight = Math.min(document.body.clientHeight, document.documentElement.clientHeight);
      }
      else {
      clientHeight = Math.max(document.body.clientHeight, document.documentElement.clientHeight);
      }
      return clientHeight;
}

  

 getScrollParent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function getScrollParent(element, includeHidden, documentObj) {
                      let style = getComputedStyle(element);
                      const excludeStaticParent = style.position === 'absolute';
                      const overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/;
                   
                      if (style.position === 'fixed') {
                          return documentObj.body;
                      }
                      let parent = element.parentElement;
                      while (parent) {
                          style = getComputedStyle(parent);
                          if (excludeStaticParent && style.position === 'static') {
                              continue;
                          }
                          if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) {
                              return parent;
                          }
                          parent = parent.parentElement;
                      }
                   
                      return documentObj.body;
                  }

  

其他

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
'use strict';
 
module.exports = (object, onChange) => {
  const handler = {
    get(target, property, receiver) {
      try {
        return new Proxy(target[property], handler);
      } catch (err) {
        return Reflect.get(target, property, receiver);
      }
    },
    defineProperty(target, property, descriptor) {
      onChange();
      return Reflect.defineProperty(target, property, descriptor);
    },
    deleteProperty(target, property) {
      onChange();
      return Reflect.deleteProperty(target, property);
    }
  };
 
  return new Proxy(object, handler);
};

  

数组

 

Object.assign

复制代码
/**
     * The Object.assign() method is used to copy the values of all enumerable own properties from one or more source
     * objects to a target object. It will return the target object.
     * This polyfill doesn't support symbol properties, since ES5 doesn't have symbols anyway
     * Source: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
     * @function
     * @ignore
     */
    if (!Object.assign) {
        Object.defineProperty(Object, 'assign', {
            enumerable: false,
            configurable: true,
            writable: true,
            value: function(target) {
                if (target === undefined || target === null) {
                    throw new TypeError('Cannot convert first argument to object');
                }

                var to = Object(target);
                for (var i = 1; i < arguments.length; i++) {
                    var nextSource = arguments[i];
                    if (nextSource === undefined || nextSource === null) {
                        continue;
                    }
                    nextSource = Object(nextSource);

                    var keysArray = Object.keys(nextSource);
                    for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
                        var nextKey = keysArray[nextIndex];
                        var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
                        if (desc !== undefined && desc.enumerable) {
                            to[nextKey] = nextSource[nextKey];
                        }
                    }
                }
                return to;
            }
        });
    }
复制代码

 

 

复制代码
   /**
     * Get bounding client rect of given element
     * @function
     * @ignore
     * @param {HTMLElement} element
     * @return {Object} client rect
     */
    function getBoundingClientRect(element) {
        var rect = element.getBoundingClientRect();

        // whether the IE version is lower than 11
        var isIE = navigator.userAgent.indexOf("MSIE") != -1;

        // fix ie document bounding top always 0 bug
        var rectTop = isIE && element.tagName === 'HTML'
            ? -element.scrollTop
            : rect.top;

        return {
            left: rect.left,
            top: rectTop,
            right: rect.right,
            bottom: rect.bottom,
            width: rect.right - rect.left,
            height: rect.bottom - rectTop
        };
    }
复制代码

 

 。。。。剩下的慢慢添加...

 http://www.cnblogs.com/surfaces/

posted @   surfaces  阅读(3234)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示