<textarea class="large required maxlength=300"></textarea>
这样做不光把表现层和行为层混合在了一起,而且用于读出这个值的脚本也会变得比较怪异:
var max = this.className.substring( this.className.indexOf('maxlength')+10);if (this.value.length > max) // 提醒用户出错了。
很容易就注意到这段脚本只有当我们把maxlength=x放在最后一个的时候才能工作。如果我们想让这个脚本可以处理不是放在最后一个的maxlength=x(这种情况是常有的,比如我们想再加一个传值的触发器),它会变得更加复杂。
面临的问题
这就是我们现在面临的问题。如何才能添加完美的JavaScript触发器,让我们可以方便地把一般声明(“在这里部署行为”)和针对元素的值一起传给脚本?
从技术上来说,把这些信息一起加到class属性上是可能的,但问题是class是被设计出来做这件事的吗?
自定义属性
我转向另一种解决方案。再来看一下前面提到的textarea长度限制的例子。我们需要两部分信息:
这个文本输入框有长度上限吗?
上限是什么?
用自然、有语义的方式来表达这些信息需要添加一个自定义属性给textarea:
<textarea class="large" maxlength="300"></textarea>
maxlength属性通知脚本检查用户输入,并通过属性的值把长度上限传给脚本。同理,我们可以把“required”触发器也改为一个自定义属性。比如:required="true",无论给它赋什么值都可以,因为它只是起一个通知的作用,无须附带任何额外的信息。
<textarea class="large" maxlength="300" required="true"></textarea>
从技术上说,这么做没有任何问题。W3C DOM的 getAttribute()方法可以从任何一个标签中读取任意属性的值。只有7.54版以前的Opera不允许从标签(如 <h2>)中读取一个错误的属性(如src)。幸运的是之后的版本对 getAttribute()提供了完全的支持。
下面就是我的解决方案:
function validateForm(){ var x = document.forms[0].elements; for (var i=0;i<x.length;i++) { if (x[i].getAttribute('required') && !x[i].value) // notify user of error }}var x = document.getElementsByTagName('textarea');for (var i=0;i<x.length;i++){ if (x[i].getAttribute('maxlength')) x[i].onkeypress = checkLength;}function checkLength(){ var max = this.getAttribute('maxlength'); if (this.value.length > max) // notify user of error}










