首页 > web前端 > js教程 > 使用原型无痛的JavaScript

使用原型无痛的JavaScript

William Shakespeare
发布: 2025-03-07 00:03:10
原创
218 人浏览过

Painless JavaScript Using Prototype

如果您在轨道上,则无需下载原型:它包含在发行版中。您可以通过将其放入页面的中来包括在您的视图中:

>
<%= javascript_include_tag 'prototype' %>
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

现在,让我们开始!

>
>原型的小助手

使用原型的真正好处之一是它为非常常见的脚本任务提供的致命简单辅助功能。 $函数已经引起了人们的关注。给它一个或多个元素ID,它将返回给它们的引用:

>
 <br>
// reference to the element with the ID 'nav' <br>
$("nav") <br>
// an array of element references <br>
$("img1", "img2", "img3")
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

>它就像一个汤具。GetElementById,令人惊讶的是,当您使用它时似乎更方便地编码。

>另一个非常有用的功能是document.getElementsByClassName,它在锡上说的是:它占用CSS类名称,并返回该类别的所有元素列表:

>
// all elements with class 'navlink' <br>
document.getElementsByClassName("navlink") <br>
// all elements with class navlink and inside the element with ID 'nav' <br>
document.getElementByClassName("navlink", $("nav"))
登录后复制
登录后复制
登录后复制
登录后复制

>另外,在编写本文时,原型版本1.5.0_rc0获得了功能强大的$$函数,它允许您使用标准CSS选择器语法选择元素:>

// an array of all input elements inside 'commentform' <br>
$$("#commentform input") <br>
// an array of all links with the class 'external' <br>
$$("a.external")
登录后复制
登录后复制
登录后复制
登录后复制
>请注意,在撰写本文时,除非您从颠覆中下载最新版本的原型,否则此功能将无法提供。

>

$F takes an ID and returns the value of any form field, for instance, a select box like this:

登录后复制
登录后复制
登录后复制
登录后复制
<select name="country" > <br>
  <option selected="selected" value="UK">United Kingdom</option> <br>
  <option value="FR">France</option> <br>
  ... <br>
</select> <br>
 <br>
$F('country') // 'UK'
登录后复制
登录后复制
登录后复制
使JavaScript吸吮
糟糕,我已经偷走了另一个JavaScript库的标签行。 JavaScript库开发人员似乎无法尝试使JavaScript像另一种语言一样。 Mochikit的家伙希望JavaScript成为Python,无数的程序员试图制作JavaScript,例如Java,而原型试图使其像Ruby一样。原型可以扩展到JavaScript的核心,该核心可以(如果选择使用它们)对您的编码JavaScript的方法产生巨大影响。根据您的背景和大脑的工作方式,这可能对您有所帮助。

oo ruby​​(ish)方式:class.create and object.extend

class.greate方法允许您以更类似红宝石的方式定义类,尽管这纯粹是美学的,因为它本质上只是称您将定义为构造函数定义的初始化方法,而不是采用传统的JavaScript方法来创建具有构造函数的对象的传统JavaScript方法。

但是,
var DOMTable = Class.create(); <br>
DOMTable.prototype = { <br>
  initialize : function(el) { <br>
    this.el = el; <br>
  }, <br>
  ... <br>
}
登录后复制
登录后复制
登录后复制
更强大的是愚蠢但有效的对象。extend方法。它所做的只是将一个对象的属性和方法复制到另一个对象,但其用途很多。这是一个快速的品尝者:

// make a (shallow) copy of obj1 <br>
var obj2 = Object.extend({}, obj1); <br>
 <br>
var options = { <br>
  method : "post", <br>
  args : "" <br>
}; <br>
 <br>
// merges in the given options object to the default options object <br>
Object.extend(options, { <br>
  args : "data=454", <br>
  onComplete : function() { alert("done!"); } <br>
}); <br>
 <br>
options.method // "post" <br>
options.args // "ata=454" <br>
options.onComplete // function() { alert("done!"); }
登录后复制
登录后复制
登录后复制
>最常用的用来与另一个对象“混合”方法。例如,您可以创建一组可使某些DOM元素可排序的函数:>

然后,如果我们想从上面的可分配中使我们的滴滴使我们的滴滴混合在一起,则可以将这些方法混合到可滴的对象:>

<%= javascript_include_tag 'prototype' %>
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

现在,我们可以在表上调用这些方法:

 <br>
// reference to the element with the ID 'nav' <br>
$("nav") <br>
// an array of element references <br>
$("img1", "img2", "img3")
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

>函数绑定

>原型还为函数对象添加了两个真正有用的方法:绑定和bindaseVentListener。这些主要用于将函数绑定到特定对象,以便该关键字指向该对象。当您设置事件处理程序功能时,这非常有用。想象一下您尝试这样的事情:

// all elements with class 'navlink' <br>
document.getElementsByClassName("navlink") <br>
// all elements with class navlink and inside the element with ID 'nav' <br>
document.getElementByClassName("navlink", $("nav"))
登录后复制
登录后复制
登录后复制
登录后复制
传统上,您会遇到一个错误,因为当事件触发处理程序功能时,这是指myDiv元素,而不是myObject,因此此Mess.message不确定。您可以使用类似的绑定方法解决此问题:

>

// an array of all input elements inside 'commentform' <br>
$$("#commentform input") <br>
// an array of all links with the class 'external' <br>
$$("a.external")
登录后复制
登录后复制
登录后复制
登录后复制
>现在一切都很好,因为此关键字已绑定到myObject。除此之外,BindaseVentListener执行了同样的事情,尽管它以跨浏览器兼容的方式将事件对象传递到您的函数,因此您不再需要担心window。尝试一下:

$F takes an ID and returns the value of any form field, for instance, a select box like this:

登录后复制
登录后复制
登录后复制
登录后复制
现在,我们的EventHandler函数可以访问事件对象。有关这两种方法的更多详细信息,可以在其创建者的网站上获得。

>

新的字符串和数字方法>

>原型已向内置的字符串对象添加了大量有用的方法。让我们快速看一些最好的。

>

<select name="country" > <br>
  <option selected="selected" value="UK">United Kingdom</option> <br>
  <option value="FR">France</option> <br>
  ... <br>
</select> <br>
 <br>
$F('country') // 'UK'
登录后复制
登录后复制
登录后复制
var DOMTable = Class.create(); <br>
DOMTable.prototype = { <br>
  initialize : function(el) { <br>
    this.el = el; <br>
  }, <br>
  ... <br>
}
登录后复制
登录后复制
登录后复制
// make a (shallow) copy of obj1 <br>
var obj2 = Object.extend({}, obj1); <br>
 <br>
var options = { <br>
  method : "post", <br>
  args : "" <br>
}; <br>
 <br>
// merges in the given options object to the default options object <br>
Object.extend(options, { <br>
  args : "data=454", <br>
  onComplete : function() { alert("done!"); } <br>
}); <br>
 <br>
options.method // "post" <br>
options.args // "ata=454" <br>
options.onComplete // function() { alert("done!"); }
登录后复制
登录后复制
登录后复制
>原型也为数字添加了一个很好的方法。告别您的循环!

var Sortable = { <br>
  sortBy : function(func) { <br>
    ... <br>
  }, <br>
  sortByReversed : function(func) { <br>
    ... <br>
  }, <br>
  reset : function() { <br>
    ... <br>
  } <br>
};
登录后复制
登录后复制
>在这里,Times方法采用的函数将被称为给定的次数,并将当前迭代号作为参数传递。使用枚举时,这种迭代函数的使用很常见,我们将在接下来讨论。

>

迭代红宝石方式: 原型的隐藏宝石之一是枚举的混合物和哈希对象,这些物体直接从红宝石中煮出来。如果您不熟悉Ruby,请不要担心。我将在这里解释这一切。 我们将从枚举开始。简而言之,当我们使用object.extend向对象添加枚举时,它为对象提供了许多真正有用的功能来使用其属性。枚举已添加到数组原型中,因此任何数组都具有这些新方法。以下是一些您可以使用新的“枚举”数组来做的示例:

>

var myTable = new DOMTable("table-id"); <br>
Object.extend(myTable, Sortable);
登录后复制
登录后复制
// sort the table using the given function <br>
myTable.sortBy(function (itemA, itemB) { ... });
登录后复制
var myObject = new Object();  <br>
myObject.message = "Hello!";  <br>
myObject.eventHandler = function() {  <br>
  alert(this.message);  <br>
}  <br>
  <br>
$("mydiv").onmouseover = myObject.eventHandler;
登录后复制
$("mydiv").onmouseover = myObject.eventHandler.bind(myObject);
登录后复制
myObject.eventHandler = function(event) {  <br>
  alert(event.srcElement.nodeName);  <br>
}  <br>
  <br>
$("mydiv").onmouseover = myObject.eventHandler.bindAsEventListener(myObject);
登录后复制
为创建哈希,请在任何对象上调用魔术函数$ h。这将对象的所有属性变成了一组键值对,并混合了枚举。让我们散发哈希:
// "backgroundColor"  <br>
"background-color".camelize()
登录后复制
>:
camelize turns hyphenated strings to camel case strings that you can use to work with CSS properties.

登录后复制
<%= javascript_include_tag 'prototype' %>
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
 <br>
// reference to the element with the ID 'nav' <br>
$("nav") <br>
// an array of element references <br>
$("img1", "img2", "img3")
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
// all elements with class 'navlink' <br>
document.getElementsByClassName("navlink") <br>
// all elements with class navlink and inside the element with ID 'nav' <br>
document.getElementByClassName("navlink", $("nav"))
登录后复制
登录后复制
登录后复制
登录后复制

首先,如果您不是红宝石主义者,枚举和哈希似乎有些麻烦,但是我可以向您保证,一旦您开始使用它们,您会想知道为什么您会愿意让RSI写所有这些循环的RSI!当您将其中一个或多个一起使用时,您将意识到这些新方法的巨大力量。你可以 “>在Encyte Media中更详细地阅读有关枚举和哈希的信息。

>

事件对象有助于提供许多人,这是JavaScript的圣杯:简单,跨浏览器事件处理:

// an array of all input elements inside 'commentform' <br>
$$("#commentform input") <br>
// an array of all links with the class 'external' <br>
$$("a.external")
登录后复制
登录后复制
登录后复制
登录后复制

>以一种相当令人愉悦的方式,原型试图通过在页面卸载时自动删除每个观察者来避免IE中的讨厌记忆泄漏。

不过,在我看来,这是一个相当不发达的事件处理解决方案,因此,可能值得考虑使用像Dean Edwards的Addevent一样暂时使用的东西。

处理表单

表单和字段对象为使用表单和输入字段的工作提供了许多简单但方便的功能,以及支持原型AJAX实现的代码。
>

形式对象

>通常,表单对象的方法以ID或对象引用元素的引用:>

字段对象

$F takes an ID and returns the value of any form field, for instance, a select box like this:

登录后复制
登录后复制
登录后复制
登录后复制

字段对象处理单个元素,其方法通常以与形式对象相似的方式对元素进行ID或对象引用:>

形式序列化

<select name="country" > <br>
  <option selected="selected" value="UK">United Kingdom</option> <br>
  <option value="FR">France</option> <br>
  ... <br>
</select> <br>
 <br>
$F('country') // 'UK'
登录后复制
登录后复制
登录后复制
在原型术语中,序列化表单意味着读取所有表单的元素,并将它们变成与URL编码的字符串(几乎)相同的字符串(几乎),如果您提交了表单,则会发送。例如,考虑以下形式:

请注意,表格巧妙地对访问不同形式元素的方式之间的差异巧妙地平滑,以便正确处理输入,选择,复选框和无线电按钮。 form.Serialize对于多个任务很有用,但是当我们与Ajax合作时,我们会很快就会出现。

var DOMTable = Class.create(); <br>
DOMTable.prototype = { <br>
  initialize : function(el) { <br>
    this.el = el; <br>
  }, <br>
  ... <br>
}
登录后复制
登录后复制
登录后复制

这些观察者每秒检查一下数据是否已更改,如果有的话,将调用mycallbackfunction。

第二种类型的观察者是基于事件的,只有在为元素产生更改或点击事件时才执行检查。您可以这样使用:
// make a (shallow) copy of obj1 <br>
var obj2 = Object.extend({}, obj1); <br>
 <br>
var options = { <br>
  method : "post", <br>
  args : "" <br>
}; <br>
 <br>
// merges in the given options object to the default options object <br>
Object.extend(options, { <br>
  args : "data=454", <br>
  onComplete : function() { alert("done!"); } <br>
}); <br>
 <br>
options.method // "post" <br>
options.args // "ata=454" <br>
options.onComplete // function() { alert("done!"); }
登录后复制
登录后复制
登录后复制
var Sortable = { <br>
  sortBy : function(func) { <br>
    ... <br>
  }, <br>
  sortByReversed : function(func) { <br>
    ... <br>
  }, <br>
  reset : function() { <br>
    ... <br>
  } <br>
};
登录后复制
登录后复制
var myTable = new DOMTable("table-id"); <br>
Object.extend(myTable, Sortable);
登录后复制
登录后复制
>如果您要观察到支持事件处理程序的所有字段,这是一种更有效的观察表格的方法。但是,如果您想注意不支持这些事件的元素的更改,请使用定期观察者。
工作dom

>原型具有4个对象(元素,插入,观察者和位置),可以在许多浏览器差异上进行各种形式的DOM操纵和平滑,从而使dom so屏幕上耗时令人发指。与其将计算机扔出窗口,不如浏览本节。

元素对象

元素对象以您可能期望的那样起作用:大多数元素方法只是将ID或对象引用您要操纵的元素。这是一些最有用的方法:

>
<%= javascript_include_tag 'prototype' %>
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

请参阅Sergio Pereira网站上的完整列表。

插入对象

我知道您在想什么:这听起来有些怪异,对吗?好吧,插入对象在一个元素中和周围添加了HTML块。插入有4种类型:前后,顶部和底部。这是您在带有ID“ mylement”元素之前添加一些html的方法:

>

 <br>
// reference to the element with the ID 'nav' <br>
$("nav") <br>
// an array of element references <br>
$("img1", "img2", "img3")
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
此图显示了每种类型的插入将在何处删除与给定元素有关的HTML内容。

使用原型无痛的JavaScript

位置对象

>位置对象提供多种方法,可以告诉您屏幕上给定的位置,并以跨浏览器兼容的方式提供有关该位置的信息。这应该从编写动画,效果和拖放代码的编写动画,效果和拖放代码中汲取很多麻烦。查看职位参考以获取更多详细信息。

>

上获取您的Web 2.0
“终于!”您在想:“他开始了我们真正想知道的。”是的,我把它留在了最后,以进入原型的Ajax助手,因为它们建在我们一直在经历的所有其他内容之上,并且在谈论Ajax时,它有助于理解原型的形式序列化,观察者和插入。
ajax,如果您在过去几年中被埋葬在一个非常深的孔中,则指的是使用浏览器的XMLHTTPRequest对象(或等效)与服务器进行通信,而无需重新加载页面。原型在大多数细节上都可以平滑,但是在Cameron Adams的本文中,您可以在本文中找到一些背景。

>所以,现在您都在抽一些Web 2.0操作,让我们看一个非常简单的Ajax请求:

ajax.Request构造函数采用URL和选项对象。在这种情况下,我们将一个参数(名称)发送给Hello..php,并提醒其响应(或在错误时提醒错误)。值得花时间熟悉可用的选择;以下是选项的概述,以及它们的默认值:>

使用原型无痛的JavaScript

>原型将自定义的HTTP标头添加到其所有AJAX请求中,以便您的服务器应用程序可以检测到它是AJAX调用,而不是正常调用。标题是:

<%= javascript_include_tag 'prototype' %>
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

这是用于检测AJAX调用的示例PHP函数:>

 <br>
// reference to the element with the ID 'nav' <br>
$("nav") <br>
// an array of element references <br>
$("img1", "img2", "img3")
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
使用这种方法,您可以编写AJAX应用程序,即使用户使用旧浏览器或已禁用JavaScript,也可以使用JJAX应用程序,但这是其他文章……>

>

使用form.serialize将数据传递到ajax.request

> 如上所述,参数选项用于传递URL编码的变量字符串。如果您需要发送的数据是由表单设置的,就像大多数AJAX应用程序一样,您可以简单地使用表单。Serialize从所有表单字段中生成URL编码的字符串,并将其传递到类似的参数选项中:

编写ajax事件处理程序
// all elements with class 'navlink' <br>
document.getElementsByClassName("navlink") <br>
// all elements with class navlink and inside the element with ID 'nav' <br>
document.getElementByClassName("navlink", $("nav"))
登录后复制
登录后复制
登录后复制
登录后复制

> 在上面的示例中,Onsuccess和OnFailure是AJAX事件处理程序的两个示例。 ajax的选项对象中给出的事件处理程序函数给出了一个参数,这是该ajax调用的xmlhttprequest对象。我通常称此论点响应或resp。您可以使用此参数从服务器中获取响应:>

但是,请记住,请记住,resp只是xmlhttprequest对象,因此所有这些属性都可用。

>

>您可以通过将JSON数据添加到X-JSON响应标头中从服务器中发送数据。然后,这将通过原型自动评估,并作为第二个参数发送。>
// an array of all input elements inside 'commentform' <br>
$$("#commentform input") <br>
// an array of all links with the class 'external' <br>
$$("a.external")
登录后复制
登录后复制
登录后复制
登录后复制

>许多AJAX操作只是涉及使用从服务器返回的HTML更新页面上的一些HTML。 ajax.updater对象包裹ajax.request,并简化了这种常见用例。这是一个简单的例子:

>上面的摘要将简单地替换ID为“ myDiv”的元素的内容,并用从服务器返回的任何内容。 ajax.periodicalupdater是相似的,但是以您设置的间隔重复进行Ajax调用:

衰减选项使您可以返回许多相同的响应,使您的服务器有点休息。本质上,每次定期updater提出请求,都将结果与上次返回的服务器进行比较。如果值相同,则将间隔乘以衰减值。因此,在上面的示例中,它将在两秒钟后,然后在四秒钟之后等到下一个请求,依此类推,直到收到服务器的不同结果为止。那时,间隔将重置为一秒钟。 带有响应者的

$F takes an ID and returns the value of any form field, for instance, a select box like this:

登录后复制
登录后复制
登录后复制
登录后复制

如果您正在寻找带有原型的Ajax的一些工作示例,请尝试本文。>
<%= javascript_include_tag 'prototype' %>
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
下一个在哪里?

正如我们在本文中看到的那样,原型不仅本身是有用的,而且为编写其他更专业的库提供了一个绝佳的起点。这正是越来越多的人在做的事情。

>
> script.aculo.us和moo.fx

>托马斯·福克斯(Thomas Fuchs)的脚本。Aculo.us目前,它引起了人们对其Whiz-Bang效果和聪明的UI小部件的关注。它最初是核心原型库的一部分,但很快就会失控并摆脱了父母。 使用原型作为基础,script.aculo.us专门通过动画效果,易于使用拖放功能和功能强大的UI组件来提供丰富的用户体验。该网站上有一个不错的Wiki,并提供了快速增长的质量文档来帮助您入门,并示例页面以使您的创意果汁流动。由于script.aculo.us的文件大小越大,因此已分为几个文件,因此您的用户不必下载整个库,以便您可以使用一些幻灯片效果。但是,即使单个文件也很笨重。

如果您正在追求一些简单的效果,我真的会推荐moo.fx。它的尺寸只有3K,并为您提供一些切换的幻灯片和褪色效果,这些效果通常是简单的Ajax应用程序中所需的一切。如果您想写自己的效果,这也是一个很好的起点。请查看代码,以查看使用Prototype的对象进行编程的一个很好的示例。 Valerio显然非常专注于保持他的脚本文件大小的大小,因此他甚至具有“精简版”的原型版本(切成大约10k左右),并且是Ajax.Request的精益版本,我发现自己比完整的原型库更经常使用。绝对值得一看。

行为

行为是您的DOM脚本工具包的一个很好的补充,它允许您使用CSS选择器将行为添加到文档中。这是它允许您执行的示例:> 在行为网站上,

>在行为网站上阅读有关此信息的更多信息。现在可以使用前面讨论的全新$$函数来实现类似类型的事物,因此最终可能会变得多余。

jquery
 <br>
// reference to the element with the ID 'nav' <br>
$("nav") <br>
// an array of element references <br>
$("img1", "img2", "img3")
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

> jQuery是一个紧凑的小库,可在原型中效果很好,并创建了可以吸收XPath和CSS 3选择器的$函数的超级英雄版本。它将能力与某种极其聪明的方法链方法结合在一起,从而制造了非常简洁的代码。当心这个。

总结
在将某些DOM脚本香料添加到您的Web应用程序中时,

>原型是强大的套件。不幸的是,它的功能和工具的增长速度比文档快得多!我们设法涵盖了本文原型的每个角落,但不是每种方法。不过,我希望您现在知道要去哪里获取所需的额外信息。

如果您想了解更多,请尝试Ronnie Roller的Frototypedoc.com,这是一种与原型文档的不断增长相符的资源。玩得开心!

常见问题(常见问题解答)关于无痛的JavaScript原型>

无痛的JavaScript原型是什么?

无痛的JavaScript原型是JavaScript的独特功能,它允许使用自己的属性和方法创建新对象。这是可以创建其他对象的蓝图。当您要创建具有相同属性和方法的多个对象时,此功能特别有用。它促进了代码可重复性和效率。

>

>无痛的JavaScript原型与其他JavaScript特征有何不同?

>

与其他JavaScript特征不同,无痛的JavaScript原型允许使用自己独特的属性和方法来创建对象。这意味着您可以从相同的原型创建多个对象,每个对象都有其独特的属性和方法。这与其他JavaScript功能不同,后者仅允许创建单个对象。

>

如何创建一个无痛的JavaScript原型?

>创建一个涉及无痛的JavaScript原型涉及定义一个函数,该函数将用作原型,然后使用“新’密钥单词”来创建新的Optife otty protots类型。这是一个简单的示例:


函数汽车(制造,模型,年){
this.make = make; make; this.year = year; y>>} >}
}


var mycar = new Car(' “ Mycar”是一种由“汽车”原型创建的新对象。

我可以在创建它之后添加属性吗?这是使用“原型”属性完成的。这是一个示例:

car.prototype.color ='black';

在此示例中,“颜色”属性被添加到“ car”原型中。

>

>我可以将方法添加到无痛的JavaScript原型吗?这与使用“原型”属性相同的方式与添加属性相同。以下是一个示例:

car.protype.start = function(){
console.log('car start'start');
} } }

在本示例中,在本示例中,'start'方法添加到'car'''''''''''''''''''''''''''proct.

上是什么效果? JavaScript原型是代码可重复性和效率。通过创建原型,您可以创建具有相同属性和方法的多个对象,而无需重新定义每个对象的这些属性和方法。这可以节省大量时间并使您的代码更有效。

>使用无痛的JavaScript原型?

>一个潜在的缺点来使用无痛的JavaScript原型,因为它可以比其他JavaScript功能更复杂地理解和使用。但是,一旦您了解了它的工作原理,它就可以是一个非常强大的工具。

我可以使用其他JavaScript功能使用无痛的JavaScript原型吗?实际上,它经常与其他功能一起使用以创建更复杂和更强大的应用程序。

是所有浏览器中支持的无痛的JavaScript原型吗?

是的,是的,在所有现代浏览器中都支持无痛的Javascript原型。但是,检查您使用的任何JavaScript功能的特定浏览器支持总是一个好主意。

>

我在哪里可以了解有关无痛Javascript原型的更多信息?

>

>在线可用的许多资源可以在线学习更多有关无痛JavaScript原型的信息。一些好的起点包括Mozilla开发人员网络(MDN)以及Codecademy and Udemy等网站上可用的各种JavaScript教程和课程。

>

以上是使用原型无痛的JavaScript的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板