新手javascript问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了新手javascript问题相关的知识,希望对你有一定的参考价值。

<html>
<head>
<script language = "javascript">
function Ok_OnClick(event)

if(document.getElementsByName("textName")[0].value == "")

alert("请输入内容");
return;
//getElementById
var table;
var tableList = document.getElementsByTagName("TABLE");
for(var i = 0 ; i < tableList.length ; i++)

if(tableList[i].name == "tableName")

table = tableList[i];
break;

//第一个问题,这个循环体有什么用?
var value = document.getElementsByName("textName")[0].value;
var index = table.rows.length;
table.insertRow(index); //在表格中插入一个新的行
table.rows(index).insertCell(0); //在表格的一行中插入一个单元格。第二个问题,这里的rows()是指插入的那个行?为什么这么写,语法规定?
table.rows(index).cells(0).innerText = value;//将文本输出。//问题同上。
document.getElementsByName("textName")[0].value = "";//将texaarea清空。

</script>
<title>启航留言版!</title>
</head>
<body>
<table name="tableName" align="center" border = "0">
<tr>
<th colspan="4"><h1>留言版</h1></th>
</tr>
<tr>
<td align = "center" width="283" style="font-family:'楷体_GB2312'"><div style="font-size:20px; color: #000F;">欢迎光临启航留言板</div></td>
</tr>
</table>
<hr>
<br>
<center><textarea rows="2" name="textName" id="textId" cols="20">
</textarea><br><br>
<input type="button" value="提交" onClick="return Ok_OnClick(window.event);" ></center>
</body>
</html>

你这个代码最大的一个问题..:就是..这段代码放在世界上任何一台电脑里都不会运行成功的....

我长这么大..从来么听说过JS里有一个叫...getElementByName("")这个方法...而且这段代码中居然出现了2次这个方法....

get开头的只有2个方法...getElementsByTagName() getElementById()

希望下面的能够帮到你..:

1.循环体的作用是找到name="tableName" 的table..因为上面是getElementsByTagName("table") 意思是获取页面中所有的tagname(节点名)为table的element...

节点名还有另一个表示方法就是nodename...但是没有这个方法..只有这个属性..

2.语法是规定这么写的...这个是为了解决ie和firefox的兼容问题的..table这个元素比较特殊...因为我们平时用JS动态插入节点元素的时候..都会用var table=document.createElement("table");
var tr=document.createElement("tr");
var td=document.createElement("td");
tr.appendChild(td); table.appendChild(tr);

这样常理确实能够完成任务..但是.....事实上..是实现不了的在2个浏览器..具体的我忘记了(可能只在其中一个浏览器中实现不了..你可以试下..)

所以..如果你不想采用这种DOM的插入方法..就可以利用..这种insertrow的方法.

table.rows[index].insertCell(0);

其实..有另一种完美的dom方法来完成表格的插入..

table分为tbody..thead..和tfoot...如果你想实现表格的DOM插入方法.就必须创建其中的一个..比如..

var table=document.createElement("table");
var tbody=document.createElement("tbody");
var thead=document.createElement("thead");
var thead_tr=document.createElement("tr");
for(var i=0;i<3;i++)
var th=document.createElement("th");
thead_tr.appendChild(th);

thead.appendChild(thead_tr);//这样就实现了thead部分

for(var i=0;i<3;i++)
var tr=document.createElement("tr");
for(var j=0;j<3;j++)
var td=document.createElement("td");
tr.appendChild(td);

tbody.appendChild(tr);

table.appendChild(thead);
table.appendChild(tbody);
document.body.appendChild(table);//实现..包括一行th..3行3列的表格..

但是象你这个程序.确实可以利用insertrow的方法..因为表格本身就已经存在了.如果你想重新创建..可以利用dom的方法..那样更完美..

3.至于这一句
table.rows[index].cells(0).innerText = value;
在IE中确实可以实现. 但是在FF中.这段代码不起任何作用...因为..FF不支持innerText......你可以把它换成innerHTML..这个IE和FF都支持..而且..它还支持写入HTML代码..
参考技术A 尽管这个程序错误很多,
我还是试图按照作者本来的意思来给你解释一下。

//第一个问题,这个循环体有什么用?

document.getElementsByTagName("TABLE")
得到本页面中所有的 <table>...</table> 对象,
循环一遍,找到名字是 "tableName"的对象,就把对象赋值给 table 变量。

实际上,如果你给 table 指定一个 id,比如 id="table1",就可以这样
var table = document.getElementById('table1');

不必用循环,还不容易出错。

//在表格的一行中插入一个单元格。第二个问题,这里的rows()是指插入的那个行?为什么这么写,语法规定?

var index = table.rows.length;

这个 index 应该是表格的行数,增加一行之后,index 所对应的应该是最后一行。

table.rows(index).insertCell(0);

这样写不对,应该是

table.rows[index].insertCell(0);

因为 rows 是个数组。

费力气学这个程序,不如了解一下原理,自己重新写吧。
这个程序不值得学习。本回答被提问者采纳
参考技术B //第一个问题,这个循环体有什么用?

document.getElementsByTagName("TABLE")
得到本页面中所有的 <table>...</table> 对象,
循环一遍,找到名字是 "tableName"的对象,就把对象赋值给 table 变量。

实际上,如果你给 table 指定一个 id,比如 id="table1",就可以这样
var table = document.getElementById('table1');

不必用循环,还不容易出错。

//在表格的一行中插入一个单元格。第二个问题,这里的rows()是指插入的那个行?为什么这么写,语法规定?

var index = table.rows.length;

这个 index 应该是表格的行数,增加一行之后,index 所对应的应该是最后一行。

table.rows(index).insertCell(0);

这样写不对,应该是

table.rows[index].insertCell(0);

因为 rows 是个数组。

javascript 角新手容易碰到的坑

Angular新手容易碰到的坑
12/18/2014 STIYES
在Angular群里回答新手问题一段时间了,有一些Angular方面的坑留在这里备查,希望能对各位有所帮助。这个文章将来会随时更新,不会单独开新章,欢迎各位订阅。

Q1.<div ng-include="views/user/show.html"></div> 错在哪里?

如果你这么写过,会发现这个位置啥也没有加载出来,那么,错在哪里呢?错在ng-include需要的是一个变量,如果你在$scope中有这样一个变量 $scope.userShowTemplateUrl = "views/users/show.html",并且把上面这句变为<div ng-include="userShowTemplateUrl"></div>就能正常工作了。或者这样写也行:<div ng-include=" 'views/user/show.html' "></div>

原因何在?

因为在ng-include中,是把它的参数当做变量来解释的,它会通过$eval对传入的值进行计算,然后作为模板地址去加载。

不过,更好的方法是把这些界面片段(partical)写成指令,那样你就不用在多处重复写路径了,更重要的是,将来你可以直接在这里扩展它的交互逻辑,从界面原型平滑的演化到线上系统。

Q2. 我的指令怎么无效?

A2. 如果你排除了代码错误等问题,那么最可能的原因是restrict。restrict参数是用来规定你可以通过哪种方式来使用指令,而这个问题之所以容易成为坑,是因为restrict的默认值是A,也就是说,默认情况下,指令只能通过属性的形式使用,比如我写了一个指令叫做appHeader,那么默认情况下我只能用这样的形式使用它:<div app-header></div>,而<app-header></app-header>的形式则是无效的。

所以,如果你用返回函数的形式使用指令,那么你就只能使用属性的方式调用它,比如:

yourModule.directive('appHeader', function() { return function(scope, element, attrs) { element.text('hello'); } });
如果要使用元素的方式使用指令,那么你就要这样写:

yourModule.directive('appHeader', function() { return { restrict: 'E', // 或'EA'等都可以,几种形式可以任意组合 link: function(scope, element, attrs) { element.text('hello'); } } });
Q3. 修改了变量怎么界面没反应?

A3. 首先你当然要检查有没有错误以及是否确实是scope变量,如果这些都没问题,那么多半儿是$apply导致的。对于大多数操作,$apply都会自动执行,所以你不用担心,但是如果你使用了angular之外的功能,比如直接调用了setTimeout函数、挂接了jquery的事件、使用了jquery的ajax操作等等,那么系统就没有机会帮你调用$apply,界面也就没有机会刷新了,但是你如果之后又做了其他会导致$apply的操作,你会发现以前“欠下”的那次界面刷新被正常执行了了 …… 迟到的刷新仍然是bug。

典型代码如下:

setTimeout(function() { $scope.time = new Date() }, 1000);
这种情况下你在页面中绑定的time变量将不会被自动刷新,无论是通过{{}}表达式,还是通过ng-*属性或者其他任何形式。怎么改呢?这样:

setTimeout(function() { $scope.$apply(function() { $scope.time = new Date(); }); }, 1000);
不过,这不是最好的形式,最好的形式是什么呢?当然是使用angular内置的$timeout服务,它就是干这个的:

$timeout(function() { $scope.time = new Date(); });
没有$apply,却正常工作,没bug,而且漂亮多了吧?不过这里别忘了你得把$timeout服务进行依赖注入,不然它是undefined。

Q4. ng-click 写成 ng-class 导致的界面停止响应

A4. 这是我自己犯过的一个低级错误,属于深度依赖ide导致的问题。ide的自动代码提示功能,ng-cl的第一个候选项是ng-class,如果偷懒少打了一个字,那么本来想写ng-click的代码就会写成ng-class,结果就是,无休止的重新计算ng-class中的表达式,其中的原因还没来得及看源码研究。

如果遇到界面停止响应的问题,而且你也同样深度依赖ide,那么,从这个角度查查看吧。

Q5. 我知道你不拜金,但别忘了$

A5. 在angular中有一个通用的约定:angular的内部服务、方法、属性通常都会以$开头,而相应的,它也要求你自己的命名不要用$开头。比较容易忘记用$开头的主要是一些方法,特别是$apply, $watch, $on, $broardcast, $emit这些,而这些如果你写错了,在chrome中你将得到一个莫名其妙的提示 TypeError: undefined is not a function! 可恶的是,连函数名字都没有!所以,虽然我知道你不拜金,但是千万不要忘了写$!

Q6. 注意作用域的原型继承问题!

A6. 在Angular中,作用域是通过原型链进行继承的。而这种继承有一个问题,那就是在子类中对变量进行赋值时,不会去修改父级的。

假设scopeA继承自scopeB,而在scopeB中定义了一个变量value: 1,这时候,读取scopeA.value可以正确取到值,但是如果赋值,就有问题了 scopeA.value = 2,这时候,scopeB.value的值是多少呢?你可能以为是2,但它是1!原因就在于原型继承时对变量的赋值不会修改原型中的值,而是直接在当前scope中创建一个同名的属性。

这个现象导致了一个容易让新手困惑的问题:

下面的代码工作正常:

<label><input type="radio" ng-model="color" value="red"> Red </label><br/> <label><input type="radio" ng-model="color" value="green"> Green</label><br/> <label><input type="radio" ng-model="color" value="blue"> Blue </label><br/> {{color}}
而下面的代码工作不正常,color值将不会随着选择而变化:

<div ng-repeat="value in ['red', 'green', 'blue']"> <label><input type="radio" ng-model="color" ng-value="value"> {{value}} </label> </div> {{color}}
它的原因就在于color值定义在当前scope中,而ng-repeat创建了一个子scope,它使用原型继承的方式从父级继承下来。对color值的修改,会去修改子级的变量,而父级的同名变量不会被修改。

要想让它正常工作,就改成这样:

<div ng-repeat="value in ['red', 'green', 'blue']"> <label><input type="radio" ng-model="vm.color" ng-value="value"> {{value}} </label> </div> {{vm.color}}
这里,把color定义成了一个vm对象的属性,这时候,因为只需要对vm的成员进行赋值,而不存在对vm进行赋值的情况,所以赋值会正确的作用于父级scope上。这里的vm只是$scope上的一个对象,叫别的名字也可以,只是因为它的实际作用是ViewModel,所以我习惯于把它命名为vm。

在Angular 1.2以后的版本中引入了controllerAs语法,可以一劳永逸的解决这个问题。具体的用法请参见 http://www.cnblogs.com/whitewolf/p/3493362.html

如果使用1.2以下的版本,可以在controller的第一句加上这样的语法来模拟:

var vm = $scope.vm = {};
所有的$scope变量都改为赋值给vm变量就可以了,view中也要相应的引用vm变量。

Q7. angular.module的两种写法:含义大不同

angular.module('name', [])和angular.module('name') 虽然看起来很相似,但是!它们的含义却是截然不同的!

angular.module('name', [])是创建一个新的module,[]表示它没有依赖任何其他模块,如果已经有了一个同名模块,则会覆盖现有的。

而angular.module('name')是查找一个现有module,如果这个module不存在,则返回空值。

如果把带方括号的形式(创建)误用为不带方括号的形式(引用),那么在它的返回值上调用controller等函数会出现空指针错误。

而如果把引用形式误用为创建形式,则会导致难以理解的“对象不存在”错误,但是你却明明定义过那个service或者controller等对象!这种问题就是因为后面的模块定义覆盖了以前的模块定义,你定义过的那些对象都被随着以前的module而丢掉了!

Q8. 第三方指令不起作用

最可能的原因是你没有加入模块依赖。第三方指令通常会定义在自己的模块中,所以这个模块必须被你的app模块所依赖,其中包含的指令才能在view中使用。比如你要使用ui-select2指令,就必须在自己的模块定义中加入这个依赖:

angular.module('app', [ 'ngCookies', 'ngResource', 'ngSanitize', 'ui.select2' ]).....
如果仍然没有解决问题,请看看控制台中有没有错误信息,以及是否存在Q2所提的情况。

Q9. 我要用这个directive来绑定html代码怎么办?ng-bind-html无法解析的html

随便一测试,它是不支持把html直接传给它的:

//html <p ng-bind-html="m"></p> //js $scope.m="<b>text</b>"; //error: [$sce:unsafe] Attempting to use an unsafe value in a safe context. 
我选择的是直接做一个过滤器:

//js  app.filter('toTrusted', ['$sce', function ($sce) { return function (text) { return $sce.trustAsHtml(text); }; }]); app.controller...{ $scope.m="<b>text</b>" } //html:  <p ng-bind-html="m | to_trusted"></p>

以上是关于新手javascript问题的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 新手,我认为我需要一个循环来解决这个问题.....?

javascript新手入门必读书籍推荐

译理解JavaScript闭包——新手指南

深入理解JavaScript系列(23):JavaScript与DOM(上)——也适用于新手

新手到javascript - 鼠标事件

JS是新手,请帮忙关于JavaScript循环的问题