最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

利用不到200行代码写一款属于你自己的js类库

来源:动视网 责编:小采 时间:2020-11-27 21:54:13
文档

利用不到200行代码写一款属于你自己的js类库

利用不到200行代码写一款属于你自己的js类库:前言 JavaScript 的核心是支持面向对象的,同时它也提供了强大灵活的 OOP 语言能力。本文将使用面向对象的方式,来教大家用原生js写出一个类似jQuery这样的类库。我们将会学到如下知识点: 闭包:减少变量污染,缩短变量查找范围 自执行函数在对象中的运用
推荐度:
导读利用不到200行代码写一款属于你自己的js类库:前言 JavaScript 的核心是支持面向对象的,同时它也提供了强大灵活的 OOP 语言能力。本文将使用面向对象的方式,来教大家用原生js写出一个类似jQuery这样的类库。我们将会学到如下知识点: 闭包:减少变量污染,缩短变量查找范围 自执行函数在对象中的运用


前言

JavaScript 的核心是支持面向对象的,同时它也提供了强大灵活的 OOP 语言能力。本文将使用面向对象的方式,来教大家用原生js写出一个类似jQuery这样的类库。我们将会学到如下知识点:

  • 闭包:减少变量污染,缩短变量查找范围
  • 自执行函数在对象中的运用
  • extend的实现原理
  • 如何实现跨浏览器的事件监听
  • 原型链与继承
  • 接下来我会对类库的核心api进行讲解和展示,文章最后后附带类库的完整源码,在我之前的文章《3分钟教你用原生js实现具有进度监听的文件上传预览组件》中也使用了类似的方式,感兴趣的可以一起学习,交流。

    更加完整的类库地址,请移步github《Xuery——仿jquery API风格的轻量级可扩展的原生js框架》(本地下载)

    类库设计思路

    API介绍和效果展示

    1、事件绑定 Xuery.on(eventName, fn)案例如下:

    Xuery('#demo').on('click', function(e){
     alert('hello world!')
    })

    2、访问和设置css Xuery.css(string|object, ?[string])案例如下:

    // 访问css
    Xuery('#demo').css('width')
    // 设置css
    Xuery('#demo').css('width', '1024px')
    // 设置css
    Xuery('#demo').css({
     width: '1024px',
     height: '1024px'
    })

    3、访问和设置属性 Xuery.attr(string|object, ?[string])案例如下:

    // 访问attr
    Xuery('#demo').attr('title')
    // 设置attr
    Xuery('#demo').attr('title', '1024px')
    // 设置attrs
    Xuery('#demo').attr({
     title: '1024px',
     name: '1024px'
    })

    4、访问和设置html案例如下:

    // 访问
    Xuery('#demo').html()
    // 设置
    Xuery('#demo').html('前端学习原生框架')

    还有其他几个常用的API在这里就不介绍了,大家可以在我的github上查看,或者基于这套基础框架,去扩展属于自己的js框架。

    核心源码

    以下源码相关功能我做了注释,建议大家认真阅读,涉及到原型链和构造函数的指向的问题,是实现上述调用方式的核心,又不懂可以在评论区交流沟通。

    /**
     * 链模式实现自己的js类库
     */
    (function(win, doc){
     var Xuery = function(selector, context) {
     return new Xuery.fn.init(selector, context)
     };
    
     Xuery.fn = Xuery.prototype = {
     constructor: Xuery,
     init: function(selector, context) {
     // 设置元素长度
     this.length = 0;
     // 默认获取元素的上下文document
     context = context || document;
     // id选择符,则按位非将-1转化为0
     if(~selector.indexOf('#')) {
     this[0] = document.getElementById(selector.slice(1));
     this.length = 1;
     }else{
     // 在上下文中选择元素
     var doms = context.getElementsByTagName(selector),
     i = 0,
     len = doms.length;
     for(; i<len; i++){
     this[i] = doms[i];
     }
     }
     this.context = context;
     this.selector = selector;
     return this
     },
     // 增强数组
     push: [].push,
     sort: [].sort,
     splice: [].splice
     };
    
     // 方法扩展
     Xuery.extend = Xuery.fn.extend = function(){
     // 扩展对象从第二个参数算起
     var i = 1,
     len = arguments.length,
     target = arguments[0],
     j;
     if(i === len){
     target = this;
     i--;
     }
     // 将参数对象合并到target
     for(; i<len; i++){
     for(j in arguments[i]){
     target[j] = arguments[i][j];
     }
     }
     return target
     }
    
     // 扩展事件方法
     Xuery.fn.extend({
     on: (function(){
     if(document.addEventListener){
     return function(type, fn){
     var i = this.length -1;
     for(; i>=0;i--){
     this[i].addEventListener(type, fn, false)
     }
     return this
     }
     // ie浏览器dom2级事件
     }else if(document.attachEvent){
     return function(type, fn){
     var i = this.length -1;
     for(; i>=0;i--){
     this[i].addEvent('on'+type, fn)
     }
     return this
     }
     // 不支持dom2的浏览器
     }else{
     return function(type, fn){
     var i = this.length -1;
     for(; i>=0;i--){
     this[i]['on'+type] = fn;
     }
     return this
     }
     }
     })()
     })
    
     // 将‘-'分割线转换为驼峰式
     Xuery.extend({
     camelCase: function(str){
     return str.replace(/\-(\w)/g, function(all, letter){
     return letter.toUpperCase();
     })
     }
     })
    
     // 设置css
     Xuery.extend({
     css: function(){
     var arg = arguments,
     len = arg.length;
     if(this.length < 1){
     return this
     }
     if(len === 1) {
     if(typeof arg[0] === 'string') {
     if(this[0].currentStyle){
     return this[0].currentStyle[arg[0]];
     }else{
     return getComputedStyle(this[0], false)[arg[0]]
     }
     }else if(typeof arg[0] === 'object'){
     for(var i in arg[0]){
     for(var j=this.length -1; j>=0; j--){
     this[j].style[Xuery.camelCase(i)] = arg[0][i];
     }
     }
     }
     }else if(len === 2){
     for(var j=this.length -1; j>=0; j--){
     this[j].style[Xuery.camelCase(arg[0])] = arg[1];
     }
     }
     return this
     }
     })
    
     // 设置属性
     Xuery.extend({
     attr: function(){
     var arg = arguments,
     len = arg.length;
     if(len <1){
     return this
     }
     if(len === 1){
     if(typeof arg[0] === 'string'){
     return this[0].getAttribute(arg[0])
     }else if(typeof arg[0] === 'object'){
     for(var i in arg[0]){
     for(var j=this.length -1; j>= 0; j--){
     this[j].setAttribute(i, arg[0][i])
     }
     }
     }
     }
     else if(len === 2){
     for(var j=this.length -1; j>=0; j--){
     this[j].setAttribute(arg[0], arg[1]);
     }
     }
     return this
     }
     })
    
     // 获取或者设置元素内容
     Xuery.fn.extend({
     html: function(){
     var arg = arguments,
     len = arg.length;
     if(len === 0){
     return this[0] && this[0].innerHTML
     }else{
     for(var i=this.length -1; i>=0; i--){
     this[i].innerHTML = arg[0];
     }
     }
     return this
     }
     })
    
     Xuery.fn.init.prototype = Xuery.fn;
     window.Xuery = Xuery;
    })(window, document);
     

    总结

    文档

    利用不到200行代码写一款属于你自己的js类库

    利用不到200行代码写一款属于你自己的js类库:前言 JavaScript 的核心是支持面向对象的,同时它也提供了强大灵活的 OOP 语言能力。本文将使用面向对象的方式,来教大家用原生js写出一个类似jQuery这样的类库。我们将会学到如下知识点: 闭包:减少变量污染,缩短变量查找范围 自执行函数在对象中的运用
    推荐度:
    标签: js 类库 的类库
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top