您应该拥有什么:
- 基本的Java语言理解
- 符合标准的浏览器
- 装有Firebug插件的Firefox
在Web编码的早期,动态功能是使用onEvent属性添加到网站的。
<span onclick="doSomething()">click me</span>
因此,对于每个事件,您都有一个单独的功能,该功能在脚本标签中定义(最好位于<head>中 )
<script type="text/javascript">
function doSomething()
{
// sample code
alert("you have successfully clicked me");
}
</script>
2.再次播放,Sam或传统模型
随着时间的流逝,人们开始将他们的代码放在一个外部javascript文件中,以使标记和行为分开,因为这样您可以更好地维护代码。
仍然通过onEvent属性维护功能。
<script type="text/javascript">
function doSomething()
{
// sample code
alert("page finished loading");
}
// attach the function to an event attribute
window.onload = doSomething;
</script>
尽管通过这种方式可以更好地组织脚本,但是您仍然可以悬吊函数,此外,您还必须应对新问题。
内联方法直接应用功能时,外部脚本必须先查找需要更改的元素。
这就是文档对象模型(DOM)发挥作用的地方。 乍一看,这可能看起来很乏味,但是当您使用Javascript前进时,您会看到它带来的好处(无需在HTML代码中调用Javascript,包含Javascript就足够了)。
// HTML
<span id="submit">click me</span>
// Javascript
function doSomething()
{
// sample code
alert("you have successfully clicked me");
}
// this will only work, if the element is already loaded into the browser
document.getElementById("submit").onclick = doSomething;
// to delay any function call after the page load, you have to use the onload event
window.onload = function()
{
document.getElementById("submit").onclick = doSomething;
}
注意:Firebug插件可让您查看当前文档树(DOM树)。
所有这些代码都有一个真正的缺点:每个事件(和元素)只能应用一个函数调用,即,如果您包含多个脚本,则只有最后一个window.onload调用才起作用(原因是,每个元素仅具有onEvent属性) )。
3. Javascript,下一代或DOM生活方式当W3C释放DOM Level 2时,所有这些都改变了。现在,您可以通过函数处理事件:addEventListener和removeEventListener,它们为选定事件绑定一个函数到一个元素。
function doSomething()
{
// sample code
alert("you have successfully clicked me");
}
function doSomethingElse()
{
// code comes here...
}
function init()
{
document.getElementById("submit").addEventListener("click", doSomething, false);
document.getElementById("submit").addEventListener("click", doSomethingElse, false);
}
window.addEventListener("load", init, false);
现在,您可以根据需要向一个元素(从任何脚本中)添加尽可能多的事件。
注意:我只在这里刮过Event主题,因为虽然事件处理是Javascript的核心(也是一个很好的例子),但在短篇文章中几乎没有对它进行解释。
进一步的注意:我不能在这里介绍IE的错误和解决方法,因为那将需要自己的一篇文章。
4.清理代码已经有好的文章了,如何编写好的代码:
简洁的Javascript, 从DHTML到DOM脚本-如何替换过时JavaScript技术的示例。 维生素功能»可维护JavaScript的重要性到目前为止,我们已经使用函数来组织脚本,只要没有太多的代码就可以了。 假设您有3个脚本文件,并且每个文件都有自己的init()函数! 这肯定会导致问题。 所以现在怎么办? 如果您有3rd party脚本,则无法真正重写它们的代码...
由于Javascript具有OOP功能(诚然与Java不匹配),因此我们可以使用它来阻止我们的功能相互干扰。
要了解其工作原理,我们必须了解范围(例如,此处:
Digital Web Magazine-JavaScript的范围 )。 Javascript中的每个变量都有一个范围(定义它的上下文)。 重要的是全局作用域 (变量在脚本中的任何位置均可访问)和局部作用域 (变量仅可在其定义的函数内部访问)。 因此,我们定义的任何函数(如我们所做的那样)都将具有全局范围。 在每个脚本文件中。因此,如果定义了两个函数,则最后一个将获胜,因为它将覆盖前一个函数(无论是否在不同文件中定义了它们)。
function init()
{
alert(1);
}
// somewhere else but later
function init()
{
alert(2);
}
// alerts '2'
init();
注意:在讨论范围时,还有一种非常有用的技术称为Closures,您可能会发现它很方便(
假人JavaScript封闭| 发展中的思想-莫里斯·约翰( )现在我们知道范围了,这将给我们带来什么好处? 上面的两个函数具有相同的名称(“ init”)和相同的范围(全局)。 为了使它们与众不同,我们需要至少更改其中之一。 当然,您可以发明出无数个名称,包括“ init”,但是我们首先选择了该名称,因为它最能说明(并且至今)功能。
这样就可以选择更改范围,但是我们该怎么做呢? 这就是面向对象编程(OOP)发挥作用的地方。 OOP意味着处理对象。
简而言之,对象是一种构造,具有(可以具有)仅属于该对象的值(称为属性)和函数(称为方法)。
对象的用法如下:
// define a new value for the property
object.property = x;
// assign the property value to a variable
var y = object.property;
// call a method
object.method();
// call a method with arguments
object.method(arg1, arg2);
// doesn't work
property = x;
var y = property;
method();
如果您睁开眼睛,睁开大脑,您可能会发现这如何解决我们的示波器问题。
对于剩下的内容,我会告诉您: 对象定义了其方法(函数)和属性(值)的范围。
因此:obj1.init()和obj2.init()是两个不同的函数。 得到它了?
为了解决我们的范围问题,我们仅将函数定义为不同对象的方法。
注意:这不是OOP的初衷,但我在这里不解释OOP(这可能会花费很长时间,超出了本文的讨论范围)。
让我们继续。 我们如何定义这些对象? 有一种书写方式(称为对象文字(
等我来! »博客存档»对对象文字表示爱 ))我们可以在这里使用。var object_name = {
property_1 : "value_1",
property_2 : "value_2",
method_1 : function()
{
alert("method 1 executing");
},
method_2 : function(x)
{
if (this.x)
{
alert(this.x);
}
}
}
// alerts “method 1 executing”
object_name.method_1();
// does nothing (value_1 is not the name of a valid property)
object_name.method_2("value_1");
// alerts “value_2”
object_name.method_2('property_2');
在知道如何定义对象之后,我们可以从上面重写'init'示例。
// since we define the objects (not its methods) in global scope,
// we can omit the var keyword
NS1 = {
init : function()
{
alert(1);
}
}
NS2 = {
init : function()
{
alert(2);
}
}
// alerts “1”
NS1.init();
// alerts “2”
NS2.init();
现在,我们已经成功地为每个init()函数应用了不同的作用域!
5.构建脚本
在编写脚本时,(在大多数情况下)您只需要执行少量任务(例如事件处理(某些单击事件,可能是鼠标悬停事件),动态内容加载(AJAX,子菜单)或表单验证)。 要开始使用它们,每个任务一个init()函数就足够了。 周围的所有其他功能仅帮助那些启动器功能完成工作。 因此,您可以轻松地将启动程序功能周围的帮助程序功能分组。 每个组都可以分配到自己的范围。
当然,您也可以构造范围…(但是仅对于大型库才需要)
例:
myName.menu // function group for menu creation
myName.forms // function group for form validation
myName.commons // functions used in many groups
// e.g. event handling, loop functions, …
如果您已阅读有关OOP的文章,则可能听说过某个对象可能具有私有属性和方法(此处的关键字是“(数据)封装”),这些属性和方法只能在对象内部调用,而不能从外部访问(无论它是什么范围)。
将组的所有帮助程序功能设为私有不是有用的(如果仅在组中使用该功能,为什么要授予全局访问权限)?
我们也可以做到。 在代码中稍作更改,我们就可以设置公共和私有属性和方法!
// our scope (let's call it namespace …)
bytes = {
// subclasses
// technically not necessary, but providing an overview
// esp. if you have many subclasses
josah : new Object,
msquared : new Object
// you can define metadata here (dublincore.org)
}
// object with only public members
bytes.msquared = {
favouriteColour : "purple",
hateColour : "gray",
state : function()
{
alert("I like " + this.favouriteColour);
},
stateNot : function()
{
alert("I hate " + this.hateColour);
}
}
// alerts "I hate gray"
bytes.msquared.stateNot();
// alerts "I like blue"
bytes.msquared.favouriteColour = "blue";
bytes.msquared.state();
// an object with private and public members
// I didn't go for real functions here……… ;-)
bytes.josah = function() {
// this is a private property
var hateColour = "purple";
// this is a private function
// the 'this' keyword does not necessarily
// point to bytes.josah!
function throw()
{
this.lift();
this.move();
this.drop();
}
return {
// this is a public function
defenestrate : function(num)
{
var OP = thread[num].firstChild;
OP.addEventListener("unlike", throw, true);
// you can call members from different scopes
bytes.msquared.hateColour = hateColour;
bytes.msquared.stateNot();
}
};
}();
// doesn't work
bytes.josah.throw();
// works (but I wouldn't try it)
// defenestrates #666 and alerts "I hate purple"
bytes.josah.defenestrate(666);
现在,您可以将所有函数分组在类中,并且组织起来非常完美。
最后是一个真实的例子
描述:单击注册的元素时弹出一个图像(或在window.open()中可以执行的其他任何操作)。 只要将元素的id属性注册为弹出窗口,元素就可以不受限制。 您甚至可以打开一个以上的弹出窗口,尽管不要太多(用户可能会因此而烦恼)。
/*
#########################################################
# Popup script by Dormilich, bytes.com #
# http://bytes.com, If you use this script on your site #
# Please keep this comment at the top of the javascript #
#########################################################
*/
Dormilich.Popup = function() {
/**
* [private] array to store the objects holding the necessary information for window.open()
*/
var IMG = new Array;
/**
* [private] calling window.open() on event
* since the image info object is not part of the element, the correct image object
* is identified by ID comparison
*
* @return (void)
*/
function pop()
{
var l = IMG.length;
for (var j=0; j<l; j++)
{
// because pop() is used by addEvent() 'this' points to the object
// having the event attached to
if (IMG[j].id == this.id)
{
window.open(IMG[j].src, IMG[j].titel, IMG[j].props);
}
}
}
return {
/**
* [public] create an image info object that hold the parameters for window.open() and put
* it in the private storage array. src, titel & props are the parameters for window.open()
*
* @param (string) ID id of the element to apply the onclick event to
* @param (string) LOC the location of the image to popup
* @param (string) TTL title of the popup window
* @param (int) HGT image height
* @param (int) WDT image width
* @return (void)
*/
create : function(ID, LOC, TTL, HGT, WDT)
{
var obj = {
id : ID,
src : LOC,
titel : TTL,
props : "height=" + HGT + ",width=" + WDT + ",menubar=no,resizable=yes,scrollbars=yes"
}
IMG.push(obj);
},
/**
* [public] loop through all element in the private storage array and attach the private pop() method
* with the onclick event handler. (interestingly, even though the addEvent() method comes from a
* different class it's executed in the local scope)
*
* @return (void)
*/
register : function()
{
var l = IMG.length;
for (var i=0; i<l; i++)
{
var z = document.getElementById(IMG[i].id);
if (z)
{
z.style.cursor = "pointer";
// currently Tino Zijdel's addEvent() function namespaced
Events.addEvent(z, "click", pop);
}
}
}
};
}();
Events = {
addEvent : function(obj, evType, fn, useCapture)
{
// full code see http://therealcrisp.xs4all.nl/upload/addEvent2
// of course you can use any other addEvent() function you like
}
};
样本用法:
/* Javascript */
// add image
// assigning the image "test.png" to the element with the id "test"
// a new 500x700 popup (inner size) will appear onclick Dormilich.Popup.create('test', 'test.png', 'TST', 500, 700);
// open a PDF in a new window (just used a random size) Dormilich.Popup.create('oath', 'slayers_try_prophecy.pdf', 'TRY', 387, 632);
// register elements/images Events.addEvent(window, "load", Dormilich.Popup.register);
/* HTML */
// show a full size image when clicking on a thumbnail <img src="test_thumb.jpg" width="50" height="70" alt="test image for popup" title="click for full image" id="test" class="thumbnails" />
// show the full text of an essay <div id="oath" class="shortdesc" title="click for full text">There shall come a controller of a dark star who shall call forth the light. (…)</div>
终(末)
多米利奇
From: https://bytes.com/topic/javascript/insights/858838-organizing-javascripts