`
zy8643954
  • 浏览: 23777 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

prototype里Form.Element.focus(element) 方法是否实现错误?

阅读更多
今天上午没事做,在公司拿着买到的 <<prototype与script.aculo.us终极揭秘>>一书看,无意中发现了一个比较有趣的问题,不知道是不是 prototype.js自己的bug,拿上来让各位鉴定一下。
   参照prototype.js的官方的api文档,Form.Element.focus(element) -> HTMLElement,他的意思应该是调用这个focus()方法之后返回的是应该是一个被prototye扩张的 HTMLElement,然后可以拿着返回的对象可以继续进行链式调用。可事实上并非如此。我自己测试了一把。下面的代码给的不全。要测试的话需要自己补全。

 <script type="text/javascript">
        	function test_focus()
	{
	    $("clickme").observe("click",function(){
		alert(Object.isString(Form.Element.focus('username')))
		Form.Element.focus('username').disable().setValue("hahahaha");
	      });	
	}
        	document.observe("dom:loaded",test_focus)
  </script>
  <body>
    <form id="login">
    	username : <input type="text" id="username" value="hehehehe"><br>
	password : <input type="text" id="password"><br>
	<input type="button" value="click me" id="clickme"><br>
    </form>
   </body>


上面的代码运行到alert()部分的时候,会提示true,也就是说他返回的是一个String,然后会报出一个Form.Element.focus("username").disable is not a function的错误。

查看prototype.js的源代码,我们看到这个方法的定义,他其实就是直接返回了传进去的element,根本就没做扩展,所以所谓的链式编程到这里就不能继续下去了。
  Form.Element = {
      focus: function(element) {
      $(element).focus();
      return element;
   },

  select: function(element) {
    $(element).select();
    return element;
  }
 };


我直接把它hack掉之后上面的代码就可以正常运行了
  Form.Element = {
      focus: function(element) {
      $(element).focus();
      return $(element);
   },

  select: function(element) {
    $(element).select();
    return $(element);
  }
 };


我不知道这是不是prototype.js的bug,我这样的修改也只能说能测试通过我写的demo,所以拿出来供大家谈论一下。

分享到:
评论
13 楼 waitingmyself 2009-01-05  
API:The activate method is a nifty way to both focus a form field and select its current text, all in one portable JavaScript call.

源码:1.6.0.2
activate: function(element) {
    element = $(element);
    try {
      element.focus();
      if (element.select && (element.tagName.toLowerCase() != 'input' ||
          !['button', 'reset', 'submit'].include(element.type)))
        element.select();
    } catch (e) { }
    return element;
  }

12 楼 zy8643954 2009-01-04  
downpour  说的是正确的,谢谢你让我明白了这个。
11 楼 downpour 2009-01-04  
hanjs 写道
zy8643954 写道
ls的好像没有完全理解我说的意思啊。


我看了一下,确实是和文档说的有出入。LS的也看看文档吧,首先要明确到底什么是HTMLElement


我都把文档的说明打上红色标记了,为啥不稍微看一下呢?

什么是HTMLElement?看看《JavaScript权威指南》:

引用
Availability

DOM Level 1 HTML

Inherits from/Overrides

Node->Element->HTMLElement


哪里说了HTMLElement就一定要被prototype加强过?


10 楼 hanjs 2009-01-03  
zy8643954 写道
ls的好像没有完全理解我说的意思啊。


我看了一下,确实是和文档说的有出入。LS的也看看文档吧,首先要明确到底什么是HTMLElement
9 楼 downpour 2009-01-03  
zy8643954 写道
downpour 写道
prototype并没有告诉你Form.Element.focus(element)返回的对象是被prototype加强过的,只是你个人的猜测而已

事实上,类似像focus这样的函数,只是为了做焦点定位,继续使用其返回值的场景很少。所以返回值也不应该变成一个加强过的对象。

不要动不动就说是框架的bug,我认为还是先动动脑筋别人为什么要这样实现为好。


我参考的是prototype-160-api.pdf官方文档,文档里写的是focus(element) -> HTMLElement。我没有说是它的错误。但是文档和实现确实不一致。

focus(element) -> HTMLElement
Gives keyboard focus to an element.
Form.Element.focus('searchbox')
// Almost equivalent, but does NOT return the form element
// (uses the native focus() method):
$('searchbox').focus()


focus(element) -> HTMLElement就代表返回的对象就必须要被prototype加强嘛?这纯粹是你的理解。

我们来看看另外一个Element的方法,prototype的文档是怎么说的:

引用


down(element[, cssRule][, index = 0]) -> HTMLElement | undefined


The Element.down method is part of Prototype’s ultimate DOM traversal toolkit (check out Element.up, Element.next and Element.previous for some more Prototypish niceness). It allows precise index-based and/or CSS rule-based selection of any of the element’s descendants.

As it totally ignores text nodes (it only returns elements), you don’t have to worry about whitespace nodes.

And as an added bonus, all elements returned are already extended allowing chaining



如果返回的HTMLElement支持chaining,并被prototype加强,在文档中自会详细说明。

对于focus这种方法,文档中本身就没有提到支持chaining。从这个方法的语义本身来说,也不需要支持chaining,因为在调用focus这个函数之后,几乎没有场景需要让其进行后续操作。
8 楼 zy8643954 2009-01-02  
downpour 写道
prototype并没有告诉你Form.Element.focus(element)返回的对象是被prototype加强过的,只是你个人的猜测而已

事实上,类似像focus这样的函数,只是为了做焦点定位,继续使用其返回值的场景很少。所以返回值也不应该变成一个加强过的对象。

不要动不动就说是框架的bug,我认为还是先动动脑筋别人为什么要这样实现为好。


我参考的是prototype-160-api.pdf官方文档,文档里写的是focus(element) -> HTMLElement。我没有说是它的错误。但是文档和实现确实不一致。

focus(element) -> HTMLElement
Gives keyboard focus to an element.
Form.Element.focus('searchbox')
// Almost equivalent, but does NOT return the form element
// (uses the native focus() method):
$('searchbox').focus()
7 楼 downpour 2009-01-02  
prototype并没有告诉你Form.Element.focus(element)返回的对象是被prototype加强过的,只是你个人的猜测而已。

事实上,类似像focus这样的函数,只是为了做焦点定位,继续使用其返回值的场景很少。所以返回值也不应该变成一个加强过的对象。

不要动不动就说是框架的bug,我认为还是先动动脑筋别人为什么要这样实现为好。
6 楼 zy8643954 2009-01-02  
ls的好像没有完全理解我说的意思啊。
5 楼 hanjs 2009-01-02  
不知道lz看的是哪个版本的?

好像不是你这样用的吧

setValue: function(element, value) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    Form.Element.Serializers[method](element, value);
    return element;
  },



<script src="prototype-1.6.0.3.js" type="text/javascript"> </script>

<script type="text/javascript">   
        function test_focus()   
{   
    $("clickme").observe("click",function(){   
    //alert(Object.isString(Form.Element.focus('username')))   
    Form.Element.disable('username');
    Form.Element.setValue('username',"hahahaha");   
      });      
}  
        document.observe("dom:loaded",test_focus)   
 </script>   
 <body>   
   <form id="login">   
    username : <input type="text" id="username" value="hehehehe"><br>   
password : <input type="text" id="password"><br>   
<input type="button" value="click me" id="clickme"><br>   
   </form>   
  </body> 
4 楼 vipmail 2008-12-30  
element = $(element);  支持
3 楼 long_biti 2008-12-14  

$('username').focus().disable();
prototype1.5开始更建议直接使用上述形式来调用。
而focus方法的问题应该是因为在从老的版本过度过来的时候没有改完善吧。参考disable方法,在方法开始的地方直接使用:
element = $(element);

像lz写的:
$(element).focus();  
    return $(element); 
在prototype好像是不建议多次对一个element使用$(),可能存在一些无谓的性能损耗。
2 楼 zy8643954 2008-12-09  
xuyao 写道
会不会你看的prototype版本和API不对

我一开始也是这么认为,后来在官方网站下了最新的1.6.0.3都是一样的。
1 楼 xuyao 2008-12-09  
会不会你看的prototype版本和API不对

相关推荐

    用prototype实现页面自动提交

    例如,我们可以使用`Form.Element.focus`来自动聚焦某个输入字段,或者使用`Form.Element.serialize`序列化表单数据,这对于自动提交时获取用户输入的数据非常有用。 2. **表单提交**:Prototype的`Form.Methods`...

    prototype手册1.6.0.2版本

    - **`serialize(formElement[, getHash=false])`**和**`serializeElements(elements[, getHash=false])`**:将表单或一组元素序列化为URL参数字符串。 #### Form.Element模块:更细粒度的表单元素控制 `Form....

    prototype.js常用函数:

    24. **Form.Element.serialize**:序列化表单元素的内容,`Form.Element.serialize('text1')`将`text1`的值转化为字符串。 25. **$F**:这是`Form.Element.getValue()`的别名,如`$F('text1')`获取ID为`text1`的...

    Prototype使用学习手册指南

    Prototype.js作为一个成熟的JavaScript库,简化了许多常见的DOM操作、事件处理及AJAX请求,使得开发者能够更加专注于业务逻辑而非底层实现细节。本手册旨在详细介绍Prototype.js中的常用函数及其应用场景,帮助...

    基础的prototype.js常用函数及其用法

    `Prototype.js`是一个JavaScript库,它提供了一系列便捷的DOM操作方法和效果函数,极大地简化了JavaScript编程。在本文中,我们将深入探讨`Prototype.js`中的一些基础且常用的函数及其用法。 1. **Element Methods:...

    Prototype Cheat Sheet

    - **`focusFirstElement(formElement)`**: Sets focus on the first interactive element in a form. - **`getElements(formElement)`**: Retrieves all child elements of a form element. - **`getInputs(form...

    prototype.js常用函数详解

    《prototype.js常用函数详解》 在JavaScript开发中,Prototype.js库提供了一系列强大的工具,使得DOM操作、事件处理以及Ajax交互变得更加便捷。以下是对Prototype.js中一些常见函数的详细解析: 1. **Element....

    div失去焦点事件实现思路

    3. 在`focus`事件中,调用`focus()`方法使`div`获得焦点。 4. 在`blur`事件中,执行相应的操作,例如隐藏`div`。 通过这种方法,我们可以扩展`div`的功能,使其在交互式应用中发挥更大的作用,提供更加丰富的用户...

    js使用小技巧

    访问窗体元素 document.all("txt").focus(); document.all("txt").select(); 窗体命令 document.execCommand 窗体COOKIE document.cookie 菜单事件 document.oncontextmenu 创建元素 document....

    jQuery详细教程

    $(selector).focus(function) 触发或将函数绑定到被选元素的获得焦点事件 $(selector).mouseover(function) 触发或将函数绑定到被选元素的鼠标悬停事件 四. jQuery实例 jQuery hide() 演示简单的 jQuery hide() ...

    JavaScript保留关键字汇总

    alert、assign、blur、anchor、anchors、button、checkbox、clearInterval、clearTimeout、close、closed、confirm、constructor、decodeURI、decodeURIComponent、defaultStatus、document、element、elements、...

Global site tag (gtag.js) - Google Analytics