澳门新萄京官方网站-www.8455.com-澳门新萄京赌场网址

澳门新萄京官方网站:前端基础进阶,Resig自己封

2019-06-29 作者:澳门新萄京赌场网址   |   浏览(95)

前面多个基础进级(10):面向对象实战之封装拖拽对象

2017/04/02 · JavaScript · 面向对象

原来的书文出处: 波同学   

澳门新萄京官方网站 1

终于

面前几篇小说,小编跟我们分享了JavaScript的一部分基础知识,那篇文章,将会进去第多少个实战环节:利用前边几章的所涉嫌到的学问,封装三个拖拽对象。为了能够扶助大家明白越多的秘诀与实行对照,作者会使用二种不相同的措施来促成拖拽。

  • 不封装对象直接促成;
  • 应用原生JavaScript封装拖拽对象;
  • 经过增加jQuery来促成拖拽对象。

正文的例子会停放于codepen.io中,供大家在读书时一向查看。要是对于codepen不打听的同窗,能够花点时间某个了然一下。

拖拽的贯彻进度会提到到充足多的实用小知识,由此为了加固自身要好的学识储存,也为了大家能够学到越来越多的学问,笔者会尽量详细的将一部分细节分享出去,相信我们认真阅读之后,一定能学到一些东西。

复制代码 代码如下:

JavaScript常用脚本集中(三)

 本文给大家享受的常用脚本有经过数组,拓展字符串拼接轻易导致品质的主题素材、页面 视口 滚动条的职位的帮带函数、调度因素光滑度的函数、获取鼠标地点的多少个通用的函数、使用cssdisplay属性来切换来分可知性的一组函数、样式相关的通用函数、获取成分当前的万丈和增幅。

 

 

透过数组,拓展字符串拼接轻松变成品质的标题

 

代码如下:

function StringBuffer() {
this.__strings__ = new Array();
}
StringBuffer.prototype.append = function (str) {
this.__strings__.push(str);
return this;
}
StringBuffer.prototype.toString = function () {
return this.__strings__.join("");
}
var buffer = new StringBuffer();
buffer.append("Hello ").append("javascript");
var result = buffer.toString();
alert(result); //Hello javascript

页面 视口 滚动条的岗位的鼎力相助函数

 

代码如下:

/*明确当前页面中度和幅度的多少个函数*/
function pageHeight() {
return document.body.scrollHeight;
}
function pageWidth() {
return document.body.scrollWidth;
}
/*规定滚动条水平和垂直的职分*/
function scrollX() {
var de = document.documentElement;
return self.pageXOffset || (de && de.scrollLeft) || document.body.scrollLeft;
}
function scrollY() {
var de = document.documentElement;
return self.pageYOffset || (de && de.scrollTop) || document.body.scrollTop;
}
/*规定浏览器视口的莫大和增长幅度的多个函数*/
function windowHeight() {
var de = document.documentElement;
return self.innerHeight || (de && de.clientHeight) || document.body.clientHeight;
}
function windowWidth() {
var de = document.documentElement;
return self.innerWidth || (de && de.clientWidth) || document.body.clientWidth;
}

调解因素发光度的函数

 

代码如下:

/*调整因素折射率的函数*/
function setOpacity(elem, level) {
//IE管理反射率
if (elem.filters) {
elem.style.filters = 'alpha(opacity=' level ')';
} else {
elem.style.opacity = level / 100;
}
}

取得鼠标地点的几个通用的函数

 

代码如下:

/*三个通用函数,用于获取鼠标相对于任何页面包车型地铁脚下岗位*/
function getX(e) {
e = e || window.event;
return e.pageX || e.clientX document.body.scrollLeft;
}
function getY(e) {
e = e || window.event;
return e.pageY || e.clientY document.body.scrollTop;
}
/*三个获得鼠标相对于当下元素地方的函数*/
function getElementX(e) {
return (e && e.layerX) || window.event.offsetX;
}
function getElementY(e) {
return (e && e.layerY) || window.event.offsetY;
}

采纳cssdisplay属性来切换到分可知性的一组函数

 

代码如下:

/**
* 使用display来隐藏成分的函数
* */
function hide(elem) {
var curDisplay = getStyle(elem, 'display');

 

if (curDisplay != 'none') {
elem.$oldDisplay = curDisplay;
}
elem.style.display = 'none';
}
/**
* 使用display来浮现存分的函数
* */
function show(elem) {
elem.style.display = elem.$oldDisplay || '';
}

体制相关的通用函数

 

代码如下:

/**
* 获取钦点成分(elem)的体裁属性(name)
* */
function getStyle(elem, name) {
//假使存在于style[]中,那么它已被设置了(并且是当下的)
if (elem.style[name]) {
return elem.style[name];
}
//否则,测试IE的方法
else if (elem.currentStyle) {
return elem.currentStyle[name];
}
//或者W3C的方法
else if(document.defaultView && document.defaultView.getComputedStyle){
name = name.replace(/(A-Z)/g, "-$1");
name = name.toLowerCase();
var s = document.defaultView.getComputedStyle(elem, "");
return s && s.getPropertyValue(name);
}
//不然,用户使用的是其余浏览器
else {
return null;
}
}

收获成分当前的中度和宽窄

 

代码如下:

/**
* 获取成分的真人真事高度
* 重视的getStyle见上面的函数。
* */
function getHeight(elem) {
return parseInt(getStyle(elem, 'height'));
}
/**
* 获取成分的量体裁衣宽度
* 正视的getStyle见上面包车型客车函数
* */
function getWidth(elem) {
return parseInt(getStyle(elem, 'width'));
}

如上就是本文分享的javascript常用脚本了,希望大家可以欣赏。

本文给大家享用的常用脚本有通过数组,拓展字符串拼接轻便变成品质的标题、页面 视口 滚动条的义务的协助...

JavaScript常用脚本集中(三),javascript脚本聚焦

经过数组,拓展字符串拼接轻易导致质量的难点

复制代码 代码如下:
function StringBuffer() {
    this.__strings__ = new Array();
}
StringBuffer.prototype.append = function (str) {
    this.__strings__.push(str);
    return this;
}
StringBuffer.prototype.toString = function () {
    return this.__strings__.join("");
}
var buffer = new StringBuffer();
buffer.append("Hello ").append("javascript");
var result = buffer.toString();
alert(result);    //Hello javascript

代码来源:

页面 视口 滚动条的地方的补助函数

复制代码 代码如下:
/*规定当前页面低度和宽窄的八个函数*/
function pageHeight() {
    return document.body.scrollHeight;
}
function pageWidth() {
    return document.body.scrollWidth;
}
/*分明滚动条水平和垂直的岗位*/
function scrollX() {
    var de = document.documentElement;
    return self.pageXOffset || (de && de.scrollLeft) || document.body.scrollLeft;
}
function scrollY() {
    var de = document.documentElement;
    return self.pageYOffset || (de && de.scrollTop) || document.body.scrollTop;
}
/*规定浏览器视口的惊人和增长幅度的四个函数*/
function windowHeight() {
    var de = document.documentElement;
    return self.innerHeight || (de && de.clientHeight) || document.body.clientHeight;
}
function windowWidth() {
    var de = document.documentElement;
    return self.innerWidth || (de && de.clientWidth) || document.body.clientWidth;
}

代码来源:

调度因素发光度的函数

复制代码 代码如下:
/*调护医疗因素光滑度的函数*/
function setOpacity(elem, level) {
    //IE管理折射率
    if (elem.filters) {
        elem.style.filters = 'alpha(opacity=' level ')';
    } else {
        elem.style.opacity = level / 100;
    }
}

代码来源:

获得鼠标地方的多少个通用的函数

复制代码 代码如下:
/*七个通用函数,用于获取鼠标相对于全体页面包车型大巴前段时间岗位*/
function getX(e) {
    e = e || window.event;
    return e.pageX || e.clientX document.body.scrollLeft;
}
function getY(e) {
    e = e || window.event;
    return e.pageY || e.clientY document.body.scrollTop;
}
/*七个获得鼠标相对于当下因素地点的函数*/
function getElementX(e) {
    return (e && e.layerX) || window.event.offsetX;
}
function getElementY(e) {
    return (e && e.layerY) || window.event.offsetY;
}

代码来源:

应用cssdisplay属性来切换到分可知性的一组函数

复制代码 代码如下:
/**
 * 使用display来隐藏成分的函数
 * */
function hide(elem) {
    var curDisplay = getStyle(elem, 'display');

    if (curDisplay != 'none') {
        elem.$oldDisplay = curDisplay;
    }
    elem.style.display = 'none';
}
/**
 * 使用display来体现有分的函数
 * */
function show(elem) {
    elem.style.display = elem.$oldDisplay || '';
}

代码来源:

体制相关的通用函数

复制代码 代码如下:
/**
 * 获取钦命成分(elem)的样式属性(name)
 * */
function getStyle(elem, name) {
    //倘使存在于style[]中,那么它已被安装了(并且是近期的)
    if (elem.style[name]) {
        return elem.style[name];
    }
    //否则,测试IE的方法
    else if (elem.currentStyle) {
        return elem.currentStyle[name];
    }
    //或者W3C的方法
    else if(document.defaultView && document.defaultView.getComputedStyle){
        name = name.replace(/(A-Z)/g, "-$1");
        name = name.toLowerCase();
        var s = document.defaultView.getComputedStyle(elem, "");
        return s && s.getPropertyValue(name);
    }
    //不然,用户选择的是别的浏览器
    else {
        return null;
    }
}

代码来源:

收获成分当前的莫斯科大学和宽窄

复制代码 代码如下:
/**
 * 获取成分的真正中度
 * 依赖的getStyle见上面的函数。
 * */
function getHeight(elem) {
    return parseInt(getStyle(elem, 'height'));
澳门新萄京官方网站:前端基础进阶,Resig自己封装的javascript。}
/**
 * 获取成分的实在宽度
 * 依赖的getStyle见上边的函数
 * */
function getWidth(elem) {
    return parseInt(getStyle(elem, 'width'));
}

代码来源:

以上便是本文分享的javascript常用脚本了,希望大家能够欣赏。

通过数组,拓展字符串拼接容易导致品质的主题素材 复制代码 代码如下: function StringBuffer() {...

function stopBubble(e) {
if (e && e.stopPropagation) {//要是传入了风浪目的,那么正是非IE浏览器
e.stopPropagation();
} else {
window.event.cancelBubble = true;//使用IE的点子来撤废事件冒泡
}
}
function stopDefault(e) {
if (e && e.preventDefault) {
e.preventDefault();//防止暗许浏览器行为(W3C)
} else {
window.event.returnValue = false;
}
return false;
}

1、怎么着让叁个DOM成分动起来

咱俩日常会通过修改成分的top,left,translate来其的地方产生变动。在底下的例证中,每点击三回开关,对应的因素就能够活动5px。大家可点击查阅。

点击查看多个让成分动起来的小例子

由于修改三个要素top/left值会挑起页面重绘,而translate不会,因而从质量优化上来剖断,大家会预先接纳translate属性。

//获取元素的样式值。
function getStyle(elem,name){
if(elem.style[name]){
return elem.style[name];
}else if(elem.currentStyle){
return elem.currentStyle[name];
}else if(document.defaultView&&document.defaultView.getComputedStyle){
name=name.replace(/([A-Z])/g,”-$1″);
name=name.toLowerCase();
var s=document.defaultView.getComputedStyle(elem,”");
return s&&s.getPropertyValue(name);
}else{
return null
}
}
//获取成分相对于那个页面包车型地铁x和y坐标。
function pageX(elem){
return elem.offsetParent?(elem.offsetLeft pageX(elem.offsetParent)):elem.offsetLeft;
}
function pageY(elem){
return elem.offsetParent?(elem.offsetTop pageY(elem.offsetParent)):elem.offsetTop;
}
//获取成分相对于父成分的x和y坐标。
function parentX(elem){
return elem.parentNode==elem.offsetParent?elem.offsetLeft:pageX(elem)-pageX(elem.parentNode);
}
function parentY(elem){
return elem.parentNode==elem.offsetParent?elem.offsetTop:pageY(elem)-pageY(elem.parentNode);
}
//获取使用css定位的因素的x和y坐标。
function posX(elem){
澳门新萄京官方网站:前端基础进阶,Resig自己封装的javascript。return parseInt(getStyle(elem,”left”));
}
function posY(elem){
return parseInt(getStyle(elem,”top”));
}
//设置元素地方。
function setX(elem,pos){
elem.style.left=pos ”px”;
}
function setY(elem,pos){
elem.style.top=pos ”px”;
}
//增港成分X和y坐标。
function addX(elem,pos){
set(elem,(posX(elem) pos));
}
function addY(elem,pos){
set(elem,(posY(elem) pos));
}
//获取成分运用css调节大小的中度和宽窄
function getHeight(elem){
return parseInt(getStyle(elem,”height”));
}
function getWidth(elem){
return parseInt(getStyle(elem,”width”));
}
//获取成分大概,完整的中度和幅度
function getFullHeight(elem){
if(getStyle(elem,”display”)!=”none”){
return getHeight(elem)||elem.offsetHeight;
}else{
var old=resetCss(elem,{display:”block”,visibility:”hidden”,position:”absolute”});
var h=elem.clientHeight||getHeight(elem);
restoreCss(elem,old);
return h;
}
}
function getFullWidth(elem){
if(getStyle(elem,”display”)!=”none”){
return getWidth(elem)||elem.offsetWidth;
}else{
var old=resetCss(elem,{display:”block”,visibility:”hidden”,position:”absolute”});
var w=elem.clientWidth||getWidth(elem);
restoreCss(elem,old);
return w;
}
}
//设置css,并保留旧的css
function resetCss(elem,prop){
var old={};
for(var i in prop){
old[i]=elem.style[i];
elem.style[i]=prop[i];
}
return old;
}
function restoreCss(elem,prop){
for(var i in prop){
elem.style[i]=prop[i];
}
}
//呈现和潜伏
function show(elem){
elem.style.display=elem.$oldDisplay||” “;
}
function hide(elem){
var curDisplay=getStyle(elem,”display”);
if(curDisplay!=”none”){
elem.$oldDisplay=curDisplay;
elem.style.display=”none”;
}
}
//设置折射率
function setOpacity(elem,num){
if(elem.filters){
elem.style.filter=”alpha(opacity=” num ”)”;
}else{
elem.style.opacity=num/100;
}
}
//滑动
function slideDown(elem){
var h=getFullHeight(elem);
elem.style.height=”0px”;
show(elem);
for(var i=0;i<=100;i =5){
new function(){
var pos=i;
setTimeout(function(){elem.style.height=(pos/100*h) ”px”;},(pos*10));
}
}
}
//渐变
function fadeIn(elem){
show(elem);
setOpacity(elem,0);
for(var i=0;i<=100;i =5){
new function(){
var pos=i;
setTimeout(function(){setOpacity(elem,pos);},(pos 1)*10);
}
}
}
//获取鼠标光标相对于全部页面包车型客车岗位。
function getX(e){
e=e||window.event;
return e.pageX||e.clientX document.body.scrollLeft;
}
function getY(e){
e=e||window.event;
return e.pageY||e.clientY document.body.scrollTop;
}
//获取鼠标光标绝对于当下成分的任务。
function getElementX(e){
return (e&&e.layerX)||window.event.offsetX;
}
function getElementY(e){
return (e&&e.layerY)||window.event.offsetY;
}
//获取页面包车型大巴惊人和宽度
function getPageHeight(){
var de=document.documentElement;
return document.body.scrollHeight||(de&&de.scrollHeight);
}
function getPageWidth(){
var de=document.documentElement;
return document.body.scrollWidth||(de&&de.scrollWidth);
}
//获取滚动条的职位。
function scrollX(){
var de=document.documentElement;
return self.pageXOffset||(de&&de.scrollLeft)||document.body.scrollLeft;
}
function scrollY(){
var de=document.documentElement;
return self.pageYOffset||(de&&de.scrollTop)||document.body.scrollTop;
}
//获取视口的可观和宽度。
function windowHeight() {
var de = document.documentElement;
return self.innerHeight||(de && de.offsetHeight)||document.body.offsetHeight;
}
function windowWidth() {
var de = document.documentElement;
return self.innerWidth||( de && de.offsetWidth )||document.body.offsetWidth;
}

连锁小说

有关搜索:

前些天看啥

搜索才具库

回来首页

  • 隐性调用php程序的方法
  • 浅谈JavaScript中的Math.atan()方法的行使
  • JavaScript中反正弦函数Math.asin()的利用简要介绍
  • JavaScript中的acos()方法应用详解
  • 介绍JavaScript中Math.abs()方法的选用
  • JavaScript中Math.SQRT2属性的选用详解

连带频道: HTML/CSS  HTML5  Javascript  jQuery  AJax教程  前者代码  正则说明式  Flex教程  WEB前端教程  

function addEvent(element, type, handler) {
if (!handler.$$guid) {//为每二个事件管理函数赋予叁个单身的ID
handler.$$guid = addEvent.guid ;
}
if (!element.events) {//为元素创设八个事件类型的散列表
element.events = {};
}
var handlers = element.events[type];
if (!handler) {
handlers = element.events[type] = {};
if (element["on" type]) {//存储已有的事件管理函数(假如已经存在七个)
handlers[0] = element["on" type];
}
}
handlers[handler.$$guid] = handler;//在散列表中存在该事件管理函数
element["on" type] = handleEvent;
}
addEvent.guid = 1;//创立独立ID的计数器
function removeEvent(element, type, handler) {//从散列表中除去事件处理函数
if (element.events && element.events[type]) {
delete element.events[type][handler.$$guid];
}
}
function handleEvent(event) {
var returnValue = true;
event = event || fixEvent(window.event);//获得事件目的(IE使用全局的风云指标)
var handlers = this.events[event.type];//获得事件处理函数散列表的援用
for (var i in handlers) {//依次执行各种事件处理函数
this.$$handlerEvent = handlers[i];
if (this.$$handlerEvent(event) === false) {
returnValue = false;
}
}
return returnValue;
}
function fix伊夫nt(event) {//扩展一些IE事件指标的缺少的措施
event.preventDefault = fix伊夫nt.preventDefault;//增添W3C标准事件措施
event.stopPropagation = fixEvent.stopPropagation;
return event;
}
fixEvent.preventDefault = function () {
this.returnValue = false;
}
fixEvent.stopPropagation = function () {
this.cancelBubble = true;
}
//获取内定成分elem的体制属性
function getStyle(elem, name) {
if (elem.style[name]) {//假设属性存在于style[]中,那么它已棉被服装置了(并且是现阶段的)
return elem.style[name];
} else {
if (elem.currentStyle) {//尝试使用IE的措施
return elem.currentStyle[name];
} else if (document.defaultView && document.defaultView.getComputedStyle) {//大概W3C的法子,假诺存在的话
//name=name.replace(/([A-Z)/g,"-$1");
name = name.toLowerCase();
var s = document.defaultView.getComputedStyle(elem, '');//获取样式对象并得到属性(存在的话)值
return s && s.getPropertyValue(name);
} else {
return null;
}
}
}
//获取成分的X(水平、左端)地点
function pageX(elem) {
return elem.offsetParent ?//查看大家是不是位于根成分
elem.offsetLeft pageX(elem.offsetParent) ://假诺大家能继续取得上贰个要素,扩充当前的偏移量并卫冕前行递归
elem.offsetLeft;//不然获得当前的偏移量
}
//获得元素Y(垂直、最上部)地方
function pageY(elem) {
return elem.offsetParent ?//查看大家是不是位于根成分
elem.offsetTop pageY(elem.offsetParent) ://假设能承接获得上三个元素,扩大当前的偏移量并连续升高递归
elem.offsetTop;//不然获取当前的偏移量
}
//获取成分相对于阿爹的水平地点
function parentX(elem) {
return elem.parentNode == elem.offsetParent ?//假若offsetParent是因素的阿爹,那么提前退出
elem.offsetLeft :
pageX(elem) - pageX(elem.parentNode);//否则,大家必要找到元素和因素的阿爹绝对于整个页面地方,并总计他们事先的差
}
//获取成分相对于老爸的垂直地点
function parentY(elem) {
return elem.parentNode == elem.offsetParent ?//倘使offsetParent是因素的阿爸,那么提前退出
elem.offsetTop :
pageX(elem) - pageY(elem.parentNode);//不然,我们需求找到成分和因素的老爸绝对于整个页面地方,并企图他们前边的差
}
//苏醒css原的天性值 防止reset css函数副作用的函数
function restoreCSS(elem, prop) {
for (var i in prop) {//重新恢复设置全数属性,恢复生机它们的原有值
elem.style[i] = prop[i];
}
}
//设置CSS一组属性的函数,它能够苏醒到原有设置
function resetCSS(elem, prop) {
var old = [];
for (var i in prop) {
old[i] = elem.style[i];//记录旧的属性值
elem.style[i] = prop[i];//并安装新的值
}
return old;//重回已经更改的值会集,预留给restoreCSS函数使用
}
function getHeight(elem) {//得到元素的忠实高度
return parseInt(getStyle(elem, 'height'));//获得CSS的末梢值并分析出可用的数值
}
function getWidth(elem) {//得到成分的真正宽度
return parseInt(getStyle(elem, 'width'));//获得CSS的最后值并分析出可用的数值
}
//查找成分完整的,恐怕的万丈
function fullHeight(elem) {
//如若元素是显得的,那么使用offsetHeight就能够获得可观,若无offsetHeight,则利用getHeight()
if (getStyle(elem, 'display') != 'none') {
return elem.offsetHeight || getHeight(elem);
}
//管理display为none的因素,所以重新载入参数它的css属性以得到更确切的读数
var old = resetCSS(elem, {
display: '',
visibility: 'hidden',
position: 'absolute'
});
var h = elem.clientHeight || getHeight(elem);//使用clientHeihgt找到成分的完全中度,假若还不奏效,则选取getHeight函数
restoreCSS(elem, old);//复苏css原的性质
return h;//重临成分的一体化高度
}
//查找成分完整的,恐怕的小幅度
function fullWidth(elem) {
//要是成分是展现的,那么使用offsetWidth就能够收获可观,若无offsetHeight,则动用getHeight()
if (getStyle(elem, 'display') != 'none') {
return elem.offsetWidth || getWidth(elem);
}
//管理display为none的元素,所以重新设置它的css属性以赢得越来越纯粹的读数
var old = resetCSS(elem, {
display: '',
visibility: 'hidden',
position: 'absolute'
});
var h = elem.clientWidth || getWidth(elem);//使用clientWidth找到元素的总体中度,假诺还不奏效,则选取getWidth函数
restoreCSS(elem, old);//恢复生机css原的性格
return h;//重临成分的完全中度
}

2、如何得到当前浏览器扶助的transform包容写法

transform是css3的本性,当大家接纳它时就只能面临兼容性的标题。分裂版本浏览器的特别写法大约有如下两种:

['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform']

故而大家供给看清当前浏览器境况辅助的transform属性是哪个种类,方法如下:

JavaScript

// 获取当前浏览器扶助的transform包容写法 function getTransform() { var transform = '', divStyle = document.createElement('div').style, // 也许涉嫌到的两种包容性写法,通过巡回寻觅浏览器度和胆识别的那些 transformArr = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform'], i = 0, len = transformArr.length; for(; i < len; i ) { if(transformArr[i] in divStyle) { // 找到之后登时回去,停止函数 return transform = transformArr[i]; } } // 若无找到,就向来回到空字符串 return transform; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 获取当前浏览器支持的transform兼容写法
function getTransform() {
    var transform = '',
        divStyle = document.createElement('div').style,
        // 可能涉及到的几种兼容性写法,通过循环找出浏览器识别的那一个
        transformArr = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform'],
 
        i = 0,
        len = transformArr.length;
 
    for(; i < len; i )  {
        if(transformArr[i] in divStyle) {
            // 找到之后立即返回,结束函数
            return transform = transformArr[i];
        }
    }
 
    // 如果没有找到,就直接返回空字符串
    return transform;
}

该方式用于获取浏览器帮助的transform属性。如若回去的为空字符串,则表示近日浏览器并不补助transform,这一年我们就供给使用left,top值来改换成分的地方。如若支持,就改成transform的值。

您大概感兴趣的稿子:

  • jQuery常用知识点总计以及常常包裹常用函数
  • 依照jquery封装的贰个js分页
  • jquery数组封装使用格局分享(jquery数组遍历)
  • Jquery封装tab自动切换效果的具体贯彻
  • jquery自动将form表单封装成json的切实可行落实
  • jquery datatable后台封装数据示例代码
  • jQuery宗旨图切换特效插件封装实例
  • 依附jquery的用dl模拟达成可自定义样式的SELECT下拉列表(已打包)
  • jQueryUI的Dialog的简约包装
  • 【非凡源码收藏】基于jQuery的类型常见函数封装集结

帮客商量

function hide(elem) {//隐藏成分
var curDisplay = getStyle(elem, 'display');//找到成分display的当下场馆
if (curDisplay != 'none') {//记录它的display状态
elem.$oldDisplay = curDisplay;
}
elem.style.display = 'none';//设置display为none 隐藏成分
}
function show(elem) {//显示成分
elem.style.display = elem.$oldDisplay || '';//设置display属性为它的原始值,如未有记录原始值 则动用block
}

3、 怎样获得成分的初始地方

咱俩先是必要得到到对象成分的启幕地方,由此这里我们需求多个专程用来博取成分样式的成效函数。

不过获取成分样式在IE浏览器与其它浏览器有局地例外,因而我们供给多个包容性的写法。

JavaScript

function getStyle(elem, property) { // ie通过currentStyle来取得成分的样式,别的浏览器通过getComputedStyle来获得return document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(elem, false)[property] : elem.currentStyle[property]; }

1
2
3
4
function getStyle(elem, property) {
    // ie通过currentStyle来获取元素的样式,其他浏览器通过getComputedStyle来获取
    return document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(elem, false)[property] : elem.currentStyle[property];
}

有了这几个方法之后,就足以起来入手写获取指标成分初步地点的主意了。

JavaScript

function getTargetPos(elem) { var pos = {x: 0, y: 0}; var transform = getTransform(); if(transform) { var transformValue = getStyle(elem, transform); if(transformValue == 'none') { elem.style[transform] = 'translate(0, 0)'; return pos; } else { var temp = transformValue.match(/-?d /g); return pos = { x: parseInt(temp[4].trim()), y: parseInt(temp[5].trim()) } } } else { if(getStyle(elem, 'position') == 'static') { elem.style.position = 'relative'; return pos; } else { var x = parseInt(getStyle(elem, 'left') ? getStyle(elem, 'left') : 0); var y = parseInt(getStyle(elem, 'top') ? getStyle(elem, 'top') : 0); return pos = { x: x, y: y } } } }

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
function getTargetPos(elem) {
    var pos = {x: 0, y: 0};
    var transform = getTransform();
    if(transform) {
        var transformValue = getStyle(elem, transform);
        if(transformValue == 'none') {
            elem.style[transform] = 'translate(0, 0)';
            return pos;
        } else {
            var temp = transformValue.match(/-?d /g);
            return pos = {
                x: parseInt(temp[4].trim()),
                y: parseInt(temp[5].trim())
            }
        }
    } else {
        if(getStyle(elem, 'position') == 'static') {
            elem.style.position = 'relative';
            return pos;
        } else {
            var x = parseInt(getStyle(elem, 'left') ? getStyle(elem, 'left') : 0);
            var y = parseInt(getStyle(elem, 'top') ? getStyle(elem, 'top') : 0);
            return pos = {
                x: x,
                y: y
            }
        }
    }
}

在拖拽进度中,大家须要不停的装置指标成分的新职责,那样它才会移动起来,由此大家须求三个装置指标成分地点的主意。

JavaScript

// pos = { x: 200, y: 100 } function setTargetPos(elem, pos) { var transform = getTransform(); if(transform) { elem.style[transform] = 'translate(' pos.x 'px, ' pos.y 'px)'; } else { elem.style.left = pos.x 'px'; elem.style.top = pos.y 'px'; } return elem; }

1
2
3
4
5
6
7
8
9
10
11
// pos = { x: 200, y: 100 }
function setTargetPos(elem, pos) {
    var transform = getTransform();
    if(transform) {
        elem.style[transform] = 'translate(' pos.x 'px, ' pos.y 'px)';
    } else {
        elem.style.left = pos.x 'px';
        elem.style.top = pos.y 'px';
    }
    return elem;
}

function setOpacity(elem, level) {//设置元素反射率 品级从0-100
if (elem.filters) {//假如存在filters那么些属性 则它是IE 所以设置成分的Alpha滤镜
elem.style.filters = "alpha(opacity=" level ")";
} else {
elem.style.opacity = level / 100;//使用W3C的opacity属性
}
}
function slideDown(elem) {
elem.style.height = '0px';//从0高度开头滑动
show(elem);//先展现成分(不过看不到它,因为它的莫斯科大学是0)
var h = fullHeight(elem);//找到成分的完好的潜在中度
for (var i = 0; i <= 100; i = 5) {//在一分钟内施行贰个20帧的卡通片
//保障能够维持精确的i的闭包函数
(function () {
var pos = i;
setTimeout(function () {
elem.style.height = ((pos / 100) * h) 'px';
}, (pos 1) * 10);
})();
}
}
function fadeIn(elem) {
setOpacity(elem, 0);//从0光滑度初步
show(elem);//先展现成分(然则看不到它,因为它的反射率是0)
for (var i = 0; i <= 100; i = 5) {//在一分钟内实践多少个20帧的动画
//有限支撑可以维持准确的i的闭包函数
(function () {
var pos = i;
setTimeout(function () {
setOpacity(elem, pos);
}, (pos 1) * 10);
})();
}
}
function getX(e) {//获取光标的档案的次序地方
e = e || window.event;//规范化事件目的
return e.pageX || e.clientX document.body.scrollLeft;//先检查非IE浏览器的地方,再检查IE的岗位
}
function getY(e) {//获取光标的垂直地方
e = e || window.event;//规范化事件指标
return e.pageY || e.clientY document.body.scrollTop;//先检查非IE浏览器的地点,再自己商议IE的岗位
}
function getElementX(e) {//获得鼠标相对于当下因素(事件对象e的性质target)的X地方
return (e && e.layerX) || window.event.offsetX;//得到正确的偏移量
}
function getElementY(e) {//获得鼠标相对于如今因素(事件对象e的属性target)的Y地点
return (e && e.layerY) || window.event.offsetY;//获得不错的偏移量
}
function pageHeight() {//重临页面包车型地铁惊人(扩大内容的时候或许会变动)
return document.body.scrollHeight;
}
function pageWidth() {//重返页面包车型地铁宽窄(扩大内容的时候或然会变动)
return document.body.scrollWidth;
}
function scrollX() {//分明浏览器水平滚动地点的函数
var de = document.documentElement;
return self.pageXOffset ||//倘使浏览器存在pageXOffset属性 则使用它
(de || de.scrollLeft) ||//尝试获取根节点的左端滚动的偏移量
document.body.scrollLeft;//尝试获取body元素的左端滚动的偏移量
}
function scrollY() {//明显浏览器垂直滚动地点的函数
var de = document.documentElement;
return self.pageYOffset ||//假若浏览器存在pageYOffset属性 则动用它
(de || de.scrollTop) ||//尝试获取根节点的上面滚动的偏移量
document.body.scrollTop;//尝试获得body成分的上方滚动的偏移量
}
function windowHeight() {//获取视口的惊人
var de = document.documentElement;
return self.innerHeight ||////纵然浏览器存在innerHeight属性 则使用它
(de && de.clientHeight) ||//尝试获取根节点的万丈偏移量
document.body.clientHeight;//尝试获取body成分的惊人偏移量
}
function windowWidth() {//获取视口的增长幅度
var de = document.documentElement;
return self.innerWidth ||////假使浏览器存在innerWidth属性 则使用它
(de && de.clientWidth) ||//尝试获取根节点的万丈偏移量
document.body.clientWidth;//尝试获取body成分的惊人偏移量
}

5、大家供给用到怎么着事件?

在pc上的浏览器中,结合mousedown、mousemove、mouseup那八个事件能够帮忙大家贯彻拖拽。

  • mousedown 鼠标按下时接触
  • mousemove 鼠标按下后拖动时接触
  • mouseup 鼠标松手时触发

而在移动端,分别与之对应的则是touchstart、touchmove、touchend

当我们将成分绑定这么些事件时,有一个事变指标将会作为参数字传送递给回调函数,通过事件目的,大家能够取获得近些日子鼠标的标准地点,鼠标地方音信是完成拖拽的要害。

事件指标十三分最首要,个中蕴涵了充裕多的管用的信息,这里本身就不扩张了,大家能够在函数上校事件目的打字与印刷出来查看里面的切实性质,这些办法对于记不清事件指标首要性质的童鞋非常管用。

 随机数公式:

6、拖拽的规律

当事件触发时,我们能够透过事件目的得到到鼠标的精切地点。那是落到实处拖拽的根本。当鼠标按下(mousedown触发)时,大家要求牢记鼠标的开头地方与对象成分的发端地方,大家的对象正是实现当鼠标移动时,指标成分也随即移动,根据原理大家能够吸收如下事关:

运动后的鼠标地方 - 鼠标起初地点 = 移动后的对象成分地方 - 指标成分的启幕地点

1
移动后的鼠标位置 - 鼠标初始位置 = 移动后的目标元素位置 - 目标元素的初始位置

若果鼠标地方的差值我们用dis来表示,那么指标元素的岗位就极度:

一抬手一动脚后指标成分的职分 = dis 目的成分的起始地点

1
移动后目标元素的位置 = dis 目标元素的初始位置

透过事件目的,大家得以正确的接头鼠标的当下地点,由此当鼠标拖动(mousemove)时,我们得以不停的测算出鼠标移动的差值,以此来求出目的成分的日前岗位。那几个历程,就贯彻了拖拽。

而在鼠标松手(mouseup)截至拖拽时,大家供给处理局地说尽工作。实际情况见代码。

澳门新萄京官方网站 2

7、 笔者又来推举思维导图辅助写代码了

时常有新人朋友跑来问笔者,纵然逻辑思维技巧不强,能否写代码做前端。作者的答案是:能。因为依赖思维导图,能够相当轻巧的弥补逻辑的短板。而且比在投机头脑中脑补逻辑更是清晰明了,不易出错。

上边第六点笔者介绍了规律,由此如何做就呈现不是那么难了,而现实的步子,则在底下的思念导图中分明给出,我们只须要遵照这么些手续来写代码就可以,试试看,一定很自在。

澳门新萄京官方网站 3

行使思维导图清晰的表明出全方位拖拽进度大家须求干的事情

 

8、代码完毕

part1、希图干活

JavaScript

// 获取目的成分对象 var oElem = document.getElementById('target'); // 表明2个变量用来保存鼠标早先地方的x,y坐标 var startX = 0; var startY = 0; // 证明2个变量用来保存目的成分伊始地方的x,y坐标 var sourceX = 0; var sourceY = 0;

1
2
3
4
5
6
7
8
9
10
// 获取目标元素对象
var oElem = document.getElementById('target');
 
// 声明2个变量用来保存鼠标初始位置的x,y坐标
var startX = 0;
var startY = 0;
 
// 声明2个变量用来保存目标元素初始位置的x,y坐标
var sourceX = 0;
var sourceY = 0;

part2、成效函数

因为在此以前早就贴过代码,就不再另行

JavaScript

// 获取当前浏览器帮衬的transform包容写法 function getTransform() {} // 获取成分属性 function getStyle(elem, property) {} // 获取成分的开第三人置 function getTargetPos(elem) {} // 设置成分的早先地方 function setTargetPos(elem, potions) {}

1
2
3
4
5
6
7
8
9
10
11
// 获取当前浏览器支持的transform兼容写法
function getTransform() {}
 
// 获取元素属性
function getStyle(elem, property) {}
 
// 获取元素的初始位置
function getTargetPos(elem) {}
 
// 设置元素的初始位置
function setTargetPos(elem, potions) {}

part3、注解五个事件的回调函数

这多个措施便是促成拖拽的着力所在,小编将从严遵守地方思维导图中的步骤来实现大家的代码。

JavaScript

// 绑定在mousedown上的回调,event为流传的风云目标 function start(event) { // 获取鼠标早先地点 startX = event.pageX; startY = event.pageY; // 获取成分伊始位置 var pos = getTargetPos(oElem); sourceX = pos.x; sourceY = pos.y; // 绑定 document.addEventListener('mousemove', move, false); document.addEventListener('mouseup', end, false); } function move(event) { // 获取鼠标当前岗位 var currentX = event.pageX; var currentY = event.pageY; // 计算差值 var distanceX = currentX - startX; var distanceY = currentY - startY; // 总结并设置成分当前岗位 setTargetPos(oElem, { x: (sourceX distanceX).toFixed(), y: (sourceY distanceY).toFixed() }) } function end(event) { document.remove伊夫ntListener('mousemove', move); document.removeEventListener('mouseup', end); // do other things }

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
// 绑定在mousedown上的回调,event为传入的事件对象
function start(event) {
    // 获取鼠标初始位置
    startX = event.pageX;
    startY = event.pageY;
 
    // 获取元素初始位置
    var pos = getTargetPos(oElem);
 
    sourceX = pos.x;
    sourceY = pos.y;
 
    // 绑定
    document.addEventListener('mousemove', move, false);
    document.addEventListener('mouseup', end, false);
}
 
function move(event) {
    // 获取鼠标当前位置
    var currentX = event.pageX;
    var currentY = event.pageY;
 
    // 计算差值
    var distanceX = currentX - startX;
    var distanceY = currentY - startY;
 
    // 计算并设置元素当前位置
    setTargetPos(oElem, {
        x: (sourceX distanceX).toFixed(),
        y: (sourceY distanceY).toFixed()
    })
}
 
function end(event) {
    document.removeEventListener('mousemove', move);
    document.removeEventListener('mouseup', end);
    // do other things
}

OK,三个粗略的拖拽,就像此喜欢的兑现了。点击下边包车型地铁链接,能够在线查看该例子的demo。

接纳原生js达成拖拽

9、封装拖拽对象

在前边一章笔者给大家享受了面向对象怎么着达成,基于那个基础知识,我们来将地方达成的拖拽封装为二个拖拽对象。大家的对象是,只要大家声惠氏(WYETH)个拖拽实例,那么传入的对象成分将电动具有能够被拖拽的效率。

在实际上付出中,三个目的大家平日会独自放在二个js文件中,那些js文件将单身作为一个模块,利用各类模块的主意组织起来使用。当然这里未有复杂的模块交互,因为这么些例子,大家只必要二个模块就能够。

澳门新萄京官方网站,为了防止变量污染,咱们供给将模块放置于叁个函数自实施措施模拟的块级功效域中。

JavaScript

; (function() { ... })();

1
2
3
4
;
(function() {
    ...
})();

在一般的模块协会中,大家只是一味的将洋洋js文件减弱成为叁个js文件,由此这里的第多个分行则是为着幸免上二个模块的末段不用分号导致报错。至关重要。当然在经过require大概ES6模块等方法就不会出现如此的情况。

作者们领略,在卷入三个目标的时候,大家能够将品质与方法放置于构造函数大概原型中,而在加码了自实行函数之后,我们又足以将质量和情势幸免与模块的里边效率域。那是闭包的文化。

那正是说大家面前境遇的挑战就在于,怎么样客观的管理属性与形式的职位。

本来,每贰个对象的场所都不均等,不能够等量齐观,大家须要分明的驾驭那二种职位的表征工夫做出最符合的决定。

  • 构造函数中: 属性与艺术为当下实例单独具备,只可以被眼下实例访问,并且每声美赞臣(Meadjohnson)(Dumex)个实例,当中的法子都会被重新创造二次。
  • 原型中: 属性与方法为持有实例共同持有,能够被全部实例访问,新表明实例不会再一次创立方法。
  • 模块功效域中:属性和措施不可能被其它实例访问,不过能被里面方法访问,新注解的实例,不会再一次成立同样的办法。

对此措施的判定比较轻巧。

因为在构造函数中的方法总会在宣称三个新的实例时被重新创设,由此我们注解的法门都尽量制止出现在构造函数中。

而借使您的法子中需求用到构造函数中的变量,恐怕想要公开,那就需求放在原型中。

设若方式供给个人不被外面访问,那么就放置在模块功效域中。

对此属性放置于怎么样岗位有个别时候很难做出精确的推断,因而小编很难交付贰个正确精确的定义告诉您如何性质一定要放在什么地点,那亟需在事实上支出中穿梭的总计经验。然而总的来说,依旧要组成那八个岗位的性状来做出最合适的剖断。

假若属性值只好被实例单独具有,比方person对象的name,只好属于某叁个person实例,又举例这里拖拽对象中,某多少个成分的始发地点,也仅仅只是那些因素的近日岗位,那本本性,则吻合放在构造函数中。

而即便叁性格能仅仅供内部方法访问,那性情子就符合放在模块效率域中。

关于面向对象,上边包车型大巴几点思考自身感到是那篇作品最值得认真思虑的经典。如若在封装时未有思想清楚,很恐怕会碰着多数您意外的bug,所以提议我们结合自身的开支经历,多多思量,总括出本人的见识。

基于那几个思虑,大家能够和煦尝试封装一下。然后与自家的做一些对待,看看大家的主张有怎么着不相同,在下边例子的讲明中,笔者将和睦的主见表明出来。

点击查阅已经封装好的demo

js 源码

JavaScript

; (function() { // 那是贰个个体属性,无需被实例访问 var transform = getTransform(); function Drag(selector) { // 放在构造函数中的属性,都以属于每种实例单独具有 this.elem = typeof selector == 'Object' ? selector : document.getElementById(selector); this.startX = 0; this.startY = 0; this.sourceX = 0; this.sourceY = 0; this.init(); } // 原型 Drag.prototype = { constructor: Drag, init: function() { // 起始时需求做些什么业务 this.setDrag(); }, // 稍作退换,仅用于获取当前成分的个性,类似于getName getStyle: function(property) { return document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(this.elem, false)[property] : this.elem.currentStyle[property]; }, // 用来博取当前因素的职分消息,注意与事先的区别之处 getPosition: function() { var pos = {x: 0, y: 0}; if(transform) { var transformValue = this.getStyle(transform); if(transformValue == 'none') { this.elem.style[transform] = 'translate(0, 0)'; } else { var temp = transformValue.match(/-?d /g); pos = { x: parseInt(temp[4].trim()), y: parseInt(temp[5].trim()) } } } else { if(this.getStyle('position') == 'static') { this.elem.style.position = 'relative'; } else { pos = { x: parseInt(this.getStyle('left') ? this.getStyle('left') : 0), y: parseInt(this.getStyle('top') ? this.getStyle('top') : 0) } } } return pos; }, // 用来设置当前成分的岗位 setPostion: function(pos) { if(transform) { this.elem.style[transform] = 'translate(' pos.x 'px, ' pos.y 'px)'; } else { this.elem.style.left = pos.x 'px'; this.elem.style.top = pos.y 'px'; } }, // 该方法用来绑定事件 setDrag: function() { var self = this; this.elem.add伊芙ntListener('mousedown', start, false); function start(event) { self.startX = event.pageX; self.startY = event.pageY; var pos = self.getPosition(); self.sourceX = pos.x; self.sourceY = pos.y; document.add伊芙ntListener('mousemove', move, false); document.addEventListener('mouseup', end, false); } function move(event) { var currentX = event.pageX; var currentY = event.pageY; var distanceX = currentX - self.startX; var distanceY = currentY - self.startY; self.setPostion({ x: (self.sourceX distanceX).toFixed(), y: (self.sourceY distanceY).toFixed() }) } function end(event) { document.remove伊夫ntListener('mousemove', move); document.removeEventListener('mouseup', end); // do other things } } } // 私有方法,仅仅用来获得transform的优良写法 function getTransform() { var transform = '', divStyle = document.createElement('div').style, transformArr = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform'], i = 0, len = transformArr.length; for(; i < len; i ) { if(transformArr[i] in divStyle) { return transform = transformArr[i]; } } return transform; } // 一种对外揭发的主意 window.Drag = Drag; })(); // 使用:注脚2个拖拽实例 new Drag('target'); new Drag('target2');

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
;
(function() {
    // 这是一个私有属性,不需要被实例访问
    var transform = getTransform();
 
    function Drag(selector) {
        // 放在构造函数中的属性,都是属于每一个实例单独拥有
        this.elem = typeof selector == 'Object' ? selector : document.getElementById(selector);
        this.startX = 0;
        this.startY = 0;
        this.sourceX = 0;
        this.sourceY = 0;
 
        this.init();
    }
 
 
    // 原型
    Drag.prototype = {
        constructor: Drag,
 
        init: function() {
            // 初始时需要做些什么事情
            this.setDrag();
        },
 
        // 稍作改造,仅用于获取当前元素的属性,类似于getName
        getStyle: function(property) {
            return document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(this.elem, false)[property] : this.elem.currentStyle[property];
        },
 
        // 用来获取当前元素的位置信息,注意与之前的不同之处
        getPosition: function() {
            var pos = {x: 0, y: 0};
            if(transform) {
                var transformValue = this.getStyle(transform);
                if(transformValue == 'none') {
                    this.elem.style[transform] = 'translate(0, 0)';
                } else {
                    var temp = transformValue.match(/-?d /g);
                    pos = {
                        x: parseInt(temp[4].trim()),
                        y: parseInt(temp[5].trim())
                    }
                }
            } else {
                if(this.getStyle('position') == 'static') {
                    this.elem.style.position = 'relative';
                } else {
                    pos = {
                        x: parseInt(this.getStyle('left') ? this.getStyle('left') : 0),
                        y: parseInt(this.getStyle('top') ? this.getStyle('top') : 0)
                    }
                }
            }
 
            return pos;
        },
 
        // 用来设置当前元素的位置
        setPostion: function(pos) {
            if(transform) {
                this.elem.style[transform] = 'translate(' pos.x 'px, ' pos.y 'px)';
            } else {
                this.elem.style.left = pos.x 'px';
                this.elem.style.top = pos.y 'px';
            }
        },
 
        // 该方法用来绑定事件
        setDrag: function() {
            var self = this;
            this.elem.addEventListener('mousedown', start, false);
            function start(event) {
                self.startX = event.pageX;
                self.startY = event.pageY;
 
                var pos = self.getPosition();
 
                self.sourceX = pos.x;
                self.sourceY = pos.y;
 
                document.addEventListener('mousemove', move, false);
                document.addEventListener('mouseup', end, false);
            }
 
            function move(event) {
                var currentX = event.pageX;
                var currentY = event.pageY;
 
                var distanceX = currentX - self.startX;
                var distanceY = currentY - self.startY;
 
                self.setPostion({
                    x: (self.sourceX distanceX).toFixed(),
                    y: (self.sourceY distanceY).toFixed()
                })
            }
 
            function end(event) {
                document.removeEventListener('mousemove', move);
                document.removeEventListener('mouseup', end);
                // do other things
            }
        }
    }
 
    // 私有方法,仅仅用来获取transform的兼容写法
    function getTransform() {
        var transform = '',
            divStyle = document.createElement('div').style,
            transformArr = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform'],
 
            i = 0,
            len = transformArr.length;
 
        for(; i < len; i )  {
            if(transformArr[i] in divStyle) {
                return transform = transformArr[i];
            }
        }
 
        return transform;
    }
 
    // 一种对外暴露的方式
    window.Drag = Drag;
})();
 
// 使用:声明2个拖拽实例
new Drag('target');
new Drag('target2');

这么四个拖拽对象就封装完结了。

提出我们依照自家提供的构思格局,多多尝试封装一些零件。比如封装三个弹窗,封装二个巡回轮播等。练得多了,面向对象就不再是难点了。这种思虑方法,在今后其余时候都以力所能致运用的。

下一章深入分析jQuery对象的兑现,与什么将我们这里封装的拖拽对象扩充为jQuery插件。

2 赞 1 收藏 评论

澳门新萄京官方网站 4

本文由澳门新萄京官方网站发布于澳门新萄京赌场网址,转载请注明出处:澳门新萄京官方网站:前端基础进阶,Resig自己封

关键词: