Asas menulis pemalam spring jQuery 'Lihat tetingkap pop timbul semula'_jquery

WBOY
Lepaskan: 2016-05-16 15:26:23
asal
1178 orang telah melayarinya

Artikel ini akan memperkenalkan beberapa butiran pembangunan pemalam jQuery melalui contoh Pertama, kami akan memperkenalkan beberapa pengetahuan asas pembangunan pemalam jQuery.

Pembangunan pemalam jQuery terbahagi terutamanya kepada dua kategori:

1. Tahap kelas, iaitu, melanjutkan kaedah pada kelas jQuery itu sendiri, serupa dengan $.ajax, $.get, dsb.

2. Objek yang dipanggil di sini merujuk kepada objek jQuery yang dipilih melalui kaedah Tambah pada objek. Contohnya: $('div').css(), $('div').show() dsb.

Dalam pembangunan sebenar, kami biasanya menggunakan kaedah peringkat objek untuk membangunkan pemalam yang berkuasa dan operasi objek jQuery adalah sebab utama kami memilih kaedah ini.

Seterusnya mari kita lihat kaedah penulisan khusus kedua-dua kaedah:

Pembangunan pemalam peringkat kelas

$.extend({
  foo: function() {
    //...
  },
  bar: function() {
    //...
  }
})
//调用
$.foo();
Salin selepas log masuk

Di sini, penamaan kaedah sambungan perlu lebih berhati-hati agar tidak mempunyai nama yang sama dengan kaedah asal dalam kelas jQuery. Walaupun begitu, konflik penamaan mungkin masih berlaku apabila kita perlu melanjutkan berbilang kaedah pada kelas, yang mana kita boleh mencipta ruang nama tersuai:

$.myPlugin = {
  foo: function() {
    //...
  },
  bar: function() {
    //...
  }
}
 //调用
$.myPulgin.foo();
Salin selepas log masuk

Pembangunan pemalam peringkat objek

$.fn.foo = function() {
  //doSomething...
}
//调用(假设拥有一个id为obj的元素)
$('#obj').foo();
有个会问 fn 是什么东东?粘一段别人截取的jQuery源码就明白了:
jQuery.fn = jQuery.prototype = {
  init: function(selector, context) {
    //....
  }
}
Salin selepas log masuk

Ia ternyata menjadi rantai prototaip. . .

Terima parameter konfigurasi

Apabila menulis pemalam, kami boleh membenarkan orang yang menggunakan pemalam untuk menetapkan beberapa sifat pemalam mengikut kehendak mereka. Ini memerlukan pemalam untuk mempunyai fungsi menerima parameter masa, apabila orang yang menggunakan pemalam tidak memasukkan parameter, pemalam akan Terdapat juga satu set parameter konfigurasi lalai secara dalaman.

$.fn.foo = function(options) {
  var defaults = {
    color: '#000',
    backgroundColor: 'red'
  };
  var opts = $.extend({}, defaults, options); 
  alert(opts.backgroundColor); //yellow
}
$('#obj').foo({
  backgroundColor: 'yellow'  
})
Salin selepas log masuk

Kunci di sini ialah kaedah $.extend, yang boleh menggabungkan objek. Untuk sifat yang sama, objek seterusnya akan menimpa objek sebelumnya. Mengapakah parameter pertama kaedah lanjutan objek kosong? Oleh kerana kaedah ini akan menggabungkan yang terakhir ke dalam yang pertama, parameter pertama ditetapkan kepada objek kosong untuk mengelakkan lalai daripada diubah.

Jika kami membenarkan orang menggunakan pemalam untuk menetapkan parameter lalai, kami perlu mendedahkannya:

$.fn.foo = function(options) {
  var opts = $.extend({}, $.fn.foo.defaults, options); 
  alert(opts.backgroundColor);
}
$.fn.foo.defaults = {
  color: '#000',
  backgroundColor: 'red'
}
Salin selepas log masuk

Dengan cara ini, parameter lalai pemalam boleh diubah suai secara luaran.

Dedahkan beberapa kaedah dengan sewajarnya

$.fn.foo = function(options) {
  var opts = $.extend({}, $.fn.foo.defaults, options); 
  $.fn.foo.sayColor(opts.backgroundColor);
}
$.fn.foo.sayColor = function(bgColor) {
  alert(bgColor);
}
$.fn.foo.defaults = {
  color: '#000',
  backgroundColor: 'red'
}
Salin selepas log masuk

Ditulis semula:

$.fn.foo.sayColor = function(bgColor) {
  alert('background color is ' + bgColor);
}
Salin selepas log masuk

Mendedahkan beberapa kaedah dalam pemalam adalah sangat menarik, ia membolehkan orang lain melanjutkan dan mengatasi kaedah anda. Tetapi apabila orang lain mengubah suai parameter atau kaedah anda, ia mungkin menjejaskan banyak perkara lain. Oleh itu, anda harus berhati-hati apabila mempertimbangkan sama ada untuk mendedahkan kaedah tersebut Jika anda tidak pasti, jangan dedahkannya.

Pastikan fungsi peribadi

Apabila perlu merahsiakan sesuatu, apakah perkara pertama yang terlintas di fikiran? Betul, ini adalah penutupan:

;(function($) {
  $.fn.foo = function(options) {
    var opts = $.extend({}, $.fn.foo.defaults, options); 
    debug(opts.backgroundColor);
  }
  function debug(bgColors) {
    console.log(bgColors);
  }
  $.fn.foo.defaults = {
    color: '#000',
    backgroundColor: 'red'
  }
})(jQuery)
Salin selepas log masuk

Ini ialah kaedah pembangunan plug-in rasmi yang diberikan oleh jQuery Faedahnya termasuk: 1. Tiada kebergantungan global 2. Elakkan kerosakan oleh orang lain 3. Serasi dengan operator '$' dan 'jQuery'.

Seperti di atas, kaedah nyahpepijat menjadi kaedah peribadi di dalam pemalam dan tidak boleh diubah suai secara luaran. Menambah ; di hadapan penutupan menghalang ralat daripada dilaporkan kemudian jika kod sebelum penutupan tidak mempunyai titik koma semasa penggabungan kod.

Gabung

;(function($) {
  //定义插件
  $.fn.foo = function(options) {
    //doSomething...
  }
  //私有函数
  function debug() {
    //doSomething...
  }
  //定义暴露函数
  $.fn.foo.sayColor = function() {
    //doSomething...
  }
  //插件默认参数
  $.fn.foo.default = {
    color: '#000',
    backgroundColor: 'red'
  }
})(jQuery);
Salin selepas log masuk

Kod di atas mencipta rangka pemalam yang lengkap dan standard Walaupun ia kelihatan sangat mudah, masih terdapat banyak kemahiran dan langkah berjaga-jaga dalam pembangunan sebenar.

Setelah memikirkannya untuk masa yang lama, saya merasakan adalah lebih sesuai untuk menjadikan tetingkap pop timbul sebagai pemalam sebagai contoh. Sebelum pembangunan, mari kita bayangkan dahulu struktur dan fungsi pemalam pop timbul ini:

Daripada gambar di atas, kita dapat melihat bahawa ia terdiri daripada tiga bahagian, tajuk, kandungan dan kumpulan butang. Perlu dinyatakan di sini bahawa kita tidak mahu hanya membuat kotak amaran lalai dalam pelayar yang mengandungi hanya satu butang, tetapi pengguna boleh menyesuaikan bilangan butang, supaya kotak pop timbul juga boleh melengkapkan fungsi yang serupa dengan kotak pengesahan.

Bina rangka pemalam

function SubType($ele, options) {
  this.$ele = $ele;
  this.opts = $.extend({}, $.fn.popWin.defaults, options);
}
SubType.prototype = {
  createPopWin: function() {
  }
};
$.fn.popWin = function(options) {
  //this指向被jQuery选择器选中的对象
  var superType = new SubType(this, options);
  superType.createPopWin();
};
$.fn.popWin.defaults = {};
Salin selepas log masuk

1. Kami mencipta kaedah berasaskan objek bernama popWin dan mendedahkan parameter konfigurasi lalai supaya pengguna boleh mengubah suainya;

2. Di sini kami menggunakan kaedah berorientasikan objek untuk mengurus fungsi peribadi kami Kaedah createPopWin ialah fungsi peribadi kami yang digunakan untuk mencipta tetingkap timbul.

3. Apabila pemalam dipanggil, hantar objek jq dan parameter tersuai ke dalam pembina dan buat seketika.

panggilan

Bayangkan bagaimana kami memanggil pemalam ini? Kami boleh memasukkan elemen div di lokasi yang sesuai dalam pepohon dokumen kami, pilih div dan panggil kaedah popWin yang kami takrifkan pada objek jQuery.

$('#content').popWin({
  a: 1,
  b: 2,
  callback: function() {}
});
Salin selepas log masuk
Apabila memanggil popWin, masukkan parameter konfigurasi tersuai, dan kemudian elemen div yang dipilih akan ditukar secara ajaib menjadi tetingkap timbul! Sudah tentu, ini hanyalah imaginasi kita, mari kita mulakan pengekodan.

Tentukan konfigurasi lalai

$.fn.popWin.defaults = {
  width: '600', //弹窗宽
  height: '250', //弹窗高
  title: '标题', //标题
  desc: '描述', //描述
  winCssName: 'pop-win', //弹窗的CSS类名
  titleCssName: 'pop-title', //标题区域的CSS类名
  descCssName: 'pop-desc', //描述区域的CSS类名
  btnAreaCssName: 'pop-btn-box', //按钮区域的CSS类名
  btnCssName: 'pop-btn', //单个按钮的CSS类名
  btnArr: ['确定'], //按钮组
  callback: function(){} //点击按钮之后的回调函数
}
Salin selepas log masuk

我们定义了如上的参数,为什么有要传入这么多的CSS类名呢?1. 为了保证JS与CSS尽可能的解耦。 2. 你的样式有很大可能别人并不适用。所以你需要配置一份样式表文件来对应你的默认类名,当别人需要更改样式时可以传入自己编写的样式。

按钮组为一个数组,我们的弹窗需要根据其传入的数组长度来动态的生成若干个按钮。回调函数的作用是在用户点击了某个按钮时返回他所点击按钮的索引值,方便他进行后续的操作。

弹窗DOM创建

var popWinDom,titleAreaDom,descAreaDom,btnAreaDom;
SubType.prototype = {
  createPopWin: function() {
    var _this = this;
    //首次创建弹窗
    //背景填充整个窗口
    this.$ele.css({
      position: 'fixed',
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
      backgroundColor: 'rgba(0,0,0,0.4)',
      overflow: 'hidden'
    });
    
    //窗口区域
    popWinDom = $('<div><div></div><div></div><div></div></div>').css({
      width: this.opts.width,
      height: this.opts.height,
      position: 'absolute',
      top: '30%',
      left: '50%',
      marginLeft: '-' + (this.opts.width.split('px')[0] / 2) + 'px'
    }).attr('class',this.opts.winCssName);
    
    //标题区域
    titleAreaDom = popWinDom.find('div:eq(0)')
              .text(this.opts.title)
              .attr('class',this.opts.titleCssName);
    
    //描述区域
    descAreaDom = popWinDom.find('div:eq(1)')
            .text(this.opts.desc)
            .attr('class',this.opts.descCssName);
    //按钮区域   
    btnAreaDom = popWinDom.find('div:eq(2)')
            .attr('class',this.opts.btnAreaCssName);
    
    //插入按钮
    this.opts.btnArr.map(function(item, index) {
      btnAreaDom.append($('<button></button>')
        .text(item)
        .attr({'data-index':index, 'class':_this.opts.btnCssName})
        .on('click', function() {
          _this.opts.callback($(this).attr('data-index'));
        }));
      });
    
    this.$ele.append(popWinDom);
  }
}
Salin selepas log masuk

1. 首先命名了四个变量用来缓存我们将要创建的四个DOM,将传入的jQuery对象变形成覆盖整个窗口半透明元素;

2. 创建窗口DOM,根据传入的高、宽来设置尺寸并居中,之后另上传入的窗口CSS类名;

3. 创建标题、描述、按钮组区域,并将传入的标题、描述内容配置上去;

4. 动态加入按钮,并为按钮加上data-index的索引值。注册点击事件,点击后调用传入的回调函数,将索引值传回。

好了,我们先看下效果。调用如下:

$('#content').popWin({
  width: '500',
  height: '200',
  title: '系统提示',
  desc: '注册成功',
  btnArr: ['关闭'],
  callback: function(clickIndex) {
    console.log(clickIndex);
  }
});
Salin selepas log masuk

可以看到一个弹窗的DOM已被渲染到页面中了,当点击关闭按钮时控制台会打印出 "0",因为按钮组只有一个值嘛,当然是第0个了。

如果我们需要多次调用这个弹窗,每次都要传入高、宽我会觉得很麻烦。这时我们可以直接在一开始修改插件内部的默认配置,这也是我们将默认配置暴露的好处:

$.fn.popWin.defaults.width = '500';
$.fn.popWin.defaults.height = '200';
Salin selepas log masuk

要注意的当然是不能直接改变defaults的引用,以免露掉必须的参数。 这样以后的调用都无需传入尺寸了。

我们加一个按钮并且传入一个自定义的样式看看好使不呢?

$('#content').popWin({
  title: '系统提示',
  desc: '是否删除当前内容',
  btnArr: ['确定','取消'],
  winCssName: 'pop-win-red',
  callback: function(clickIndex) {
    console.log(clickIndex);
  }
});
Salin selepas log masuk

可以看到都是生效了的,当点击“确定”按钮时回调函数返回 0,点击“取消”按钮时回调函数返回 1。这样使用插件的人就知道自己点击的是哪一个按钮,以完成接下来的操作。

显示&隐藏

接下来要进行打开、关闭弹窗功能的开发。回想上面介绍的概念,我们想让使用该插件的人能够对这两个方法进行扩展或者重写,所以将这两个方法暴露出去:

$.fn.popWin.show = function($ele) {
  $ele.show();
}
$.fn.popWin.hide = function($ele) {
  $ele.hide();
}
Salin selepas log masuk

之后在createPopWin方法中需要的地方调用这两个方法。

这里多强调一点,也是做弹窗控件不可避免的一点:只有当我们点击按钮以及灰色背景区域时允许弹窗关闭,点击弹窗其他地方不允许关闭。由于弹窗属于整个灰色区域的子节点,必然牵扯到的就是事件冒泡的问题。

所以在给最外层加上点击关闭的事件时,要在弹窗区域阻止事件冒泡。

popWinDom = $('<div><div></div><div></div><div></div></div>').css({
  width: this.opts.width,
  height: this.opts.height,
  position: 'absolute',
  top: '30%',
  left: '50%',
  marginLeft: '-' + (this.opts.width.split('px')[0] / 2) + 'px'
}).attr('class',this.opts.winCssName).on('click', function(event) {
  event.stopPropagation();
});
Salin selepas log masuk

二次打开

我们只需要在第一次调用插件时创建所有创建DOM,第二次调用时只更改其参数即可,所以在createPopWin方法最前面加入如下方法:

if (popWinDom) { //弹窗已创建
  popWinDom.css({
    width: this.opts.width,
    height: this.opts.height
  }).attr('class',this.opts.winCssName);
  titleAreaDom.text(this.opts.title).attr('class',this.opts.titleCssName);
  descAreaDom.text(this.opts.desc).attr('class',this.opts.descCssName);
  btnAreaDom.html('').attr('class',this.opts.btnAreaCssName);
  this.opts.btnArr.map(function(item, index) {
    btnAreaDom.append($('<button></button>')
      .text(item)
      .attr('data-index',index)
      .attr('class',_this.opts.btnCssName)
      .on('click', function() {
        _this.opts.callback($(this).attr('data-index'));
        $.fn.popWin.hide(_this.$ele);
      }));
    });
  $.fn.popWin.show(this.$ele);
  return;
}
Salin selepas log masuk

合并整个插件代码

;(function($) {
  function SubType(ele, options) {
    this.$ele = ele;
    this.opts = $.extend({}, $.fn.popWin.defaults, options);
  }
  var popWinDom,titleAreaDom,descAreaDom,btnAreaDom;
  SubType.prototype = {
    createPopWin: function() {
      var _this = this;
      if (popWinDom) { //弹窗已创建
        popWinDom.css({
          width: this.opts.width,
          height: this.opts.height
        }).attr('class',this.opts.winCssName);
        titleAreaDom.text(this.opts.title).attr('class',this.opts.titleCssName);
        descAreaDom.text(this.opts.desc).attr('class',this.opts.descCssName);
        btnAreaDom.html('').attr('class',this.opts.btnAreaCssName);
        this.opts.btnArr.map(function(item, index) {
          btnAreaDom.append($('<button></button>')
            .text(item)
            .attr('data-index',index)
            .attr('class',_this.opts.btnCssName)
            .on('click', function() {
              _this.opts.callback($(this).attr('data-index'));
              $.fn.popWin.hide(_this.$ele);
            }));
        });
        $.fn.popWin.show(this.$ele);
        return;
      }
      //首次创建弹窗
      this.$ele.css({
        position: 'fixed',
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        backgroundColor: 'rgba(0,0,0,0.4)',
        overflow: 'hidden',
        display: 'none'
      }).on('click', function() {
        $.fn.popWin.hide(_this.$ele);
      });
      popWinDom = $('<div><div></div><div></div><div></div></div>').css({
        width: this.opts.width,
        height: this.opts.height,
        position: 'absolute',
        top: '30%',
        left: '50%',
        marginLeft: '-' + (this.opts.width.split('px')[0] / 2) + 'px'
      }).attr('class',this.opts.winCssName).on('click', function(event) {
        event.stopPropagation();
      });
      titleAreaDom = popWinDom.find('div:eq(0)')
              .text(this.opts.title)
              .attr('class',this.opts.titleCssName);
      descAreaDom = popWinDom.find('div:eq(1)')
              .text(this.opts.desc)
              .attr('class',this.opts.descCssName);
      btnAreaDom = popWinDom.find('div:eq(2)')
              .attr('class',this.opts.btnAreaCssName);
      this.opts.btnArr.map(function(item, index) {
        btnAreaDom.append($('<button></button>')
          .text(item)
          .attr({'data-index':index, 'class':_this.opts.btnCssName})
          .on('click', function() {
            _this.opts.callback($(this).attr('data-index'));
            $.fn.popWin.hide(_this.$ele);
          }));
      });
      this.$ele.append(popWinDom);
      $.fn.popWin.show(this.$ele);
    }
  }
  $.fn.popWin = function(options) {
    var superType = new SubType(this, options);
    superType.createPopWin();
    return this;
  }
  $.fn.popWin.show = function($ele) {
    $ele.show();
  }
  $.fn.popWin.hide = function($ele) {
    $ele.hide();
  }
  $.fn.popWin.defaults = {
    width: '600',
    height: '250',
    title: 'title',
    desc: 'description',
    winCssName: 'pop-win',
    titleCssName: 'pop-title',
    descCssName: 'pop-desc',
    btnAreaCssName: 'pop-btn-box',
    btnCssName: 'pop-btn',
    btnArr: ['确定'],
    callback: function(){}
  }
})(jQuery);
Salin selepas log masuk

如上,一个完整的弹窗插件就在这里了。

说下这个标红的 return this 是干什么用的,前面已说过 this 在这里是被选中的jQuery对象。将其return就可以在调用完我们的插件方法后可以继续调用jQ对象上的其他方法,也就是jQuery的链式操作,说玄乎点就叫级联函数。

OK!趁热打铁,我们来看看暴露出去的两个方法重写之后效果怎么样,毕竟对插件暴露部分的扩展和重写是很牛逼的一块东西。

想象个情景,你用了这个插件后觉得简单的show和hide效果简直是low爆了,决定重写这个弹出和隐藏的效果:

$.fn.popWin.show = function($ele) {
  $ele.children().first().css('top','-30%').animate({top:'30%'},500);
  $ele.show();
}
$.fn.popWin.hide = function($ele) {
  $ele.children().first().animate({top:'-30%'},500,function() {
    $ele.hide();
  });
}
Salin selepas log masuk

你在自己的代码里加上上面两段,然后发现弹窗有了一个简单的上下滑动进入屏幕的效果,同时又不会影响我们弹窗的创建,证明我们的暴露方法还算合理。

当然你也可以让它竖着进、横着进、翻着跟头进,这就看你自己了。

最后贴上默认的样式表,为了急着想粘回去试试的同学们。

.pop-win {
  border: 1px solid #fff;
  padding: 10px;
  background-color: #fff;
  -wekbit-border-radius: 6px;
  border-radius: 6px;
  -webkit-box-shadow: 0 3px 9px rgba(0,0,0,0.3);
  box-shadow: 0 3px 9px rgba(0,0,0,0.3);
}
.pop-win-red {
  padding: 10px;
  background-color: red;
  -wekbit-border-radius: 6px;
  border-radius: 6px;
  -webkit-box-shadow: 0 3px 9px rgba(0,0,0,0.3);
  box-shadow: 0 3px 9px rgba(0,0,0,0.3);
}
.pop-title {
  width: 100%;
  height: 20%;
  line-height: 40px;
  padding-left: 10px;
  box-sizing: border-box;
  border-bottom: 1px solid #eee;
  font-size: 17px;
  font-weight: bold;
}
.pop-desc {
  width: 100%;
  height: 60%;
  box-sizing: border-box;
  padding: 10px 0 0 10px;
  border-bottom: 1px solid #eee;
}
.pop-btn-box {
  width: 100%;
  height: 20%;
  text-align: right;
}
.pop-btn {
  margin: 10px 10px 0 0;
  width: 60px;
  height: 30px;
}
Salin selepas log masuk

当然这只是个编写插件的例子,如果要拿出去使用还需要仔细打磨。例子虽然简单,旨在抛砖引玉。

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!