【问题标题】:Prototype.js 1.7 uncaught exception: Syntax error, unrecognized expression: [object HTMLInputElement]Prototype.js 1.7 未捕获的异常:语法错误,无法识别的表达式:[object HTMLInputElement]
【发布时间】:2017-11-09 22:13:44
【问题描述】:

此代码适用于 Prototype.js 1.6,但自从升级到 1.7 后出现错误:uncaught exception: Syntax error, unrecognized expression: [object HTMLInputElement]

document.observe('dom:loaded', function() {
    $$('.validate-length').each(function(elem) {
        var note = elem.next('.note');
        var counter = new Element('span');
        note.insert(counter);

        var curLen = $(elem).getValue().length;
        var maxLen = elem.className.match(/maximum-length-(\d+)/)[1];
        var count  = maxLen - curLen;

        if (curLen >= maxLen) {
            counter.update(' (-' + count + ')').setStyle({'color': 'red'});
        } else {
            counter.update(' (+' + count + ')').setStyle({'color': 'green'});
        }

        $$(elem).invoke('observe', 'keyup', function() {
            var curLen = $(elem).getValue().length;
            var count  = maxLen - curLen;
            if (curLen >= maxLen) {
                counter.update(' (-' + count + ')').setStyle({'color': 'red'});
            } else {
                counter.update(' (+' + count + ')').setStyle({'color': 'green'});
            }
        });
    });
});

这里似乎有问题:$$(elem).invoke('observe', 'keyup', function() {

感谢任何帮助。

【问题讨论】:

    标签: javascript prototypejs


    【解决方案1】:

    当你在一个枚举器中循环一个集合时,你的实例变量 (elem) 是一个单一的对象,而不是一个集合。所以你想使用elem.observe('keyup', function() { ... }); 来实例化你的观察者。

    “double-dollar”函数查找与作为其第一个参数传递的 CSS 选择器匹配的 DOM 元素集合。但是您已经在脚本的顶部完成了该操作,因此现在该集合的每个成员都已经“找到”(并使用 Prototype 的所有方法进行了扩展),并且不需要任何进一步的包装即可执行操作。

    您也可以在这方面进行一些优化。您应该创建一个函数来进行倒计时,也许使用addMethods 工厂将其链接到输入的原型,因此您不需要为每个文本区域创建一个新的匿名函数。接下来,如果您在每个页面上都有多个这样的输入,您可能希望查看“延迟观察者”模式,以允许您为整个页面编写一个观察者,而不是为每个输入创建一个单独的观察者.

    示例,根据要求:

    Element.addMethods({
      // setup once, memoize the counter element and maxLen
      prepare_for_countdown: function(element){
        var elm = $(element);
        // even if you call it multiple times, it only works once
        if(!elm.retrieve('counter')){
          var counter = new Element('span');
          elm.next('.note').insert(counter);
          elm.store('counter', counter);
          var maxLen = elm.readAttribute('data-max-length');
          elm.store('maxLen', maxLen);
        }
        return elm; // so you can chain
      },
      // display the value, run once at load and on each observed keyup
      countdown: function(element){
        var elm = $(element);
        var curLen = elm.getValue().length;
        var maxLen = elm.retrieve('maxLen');
        var count  = maxLen - curLen;
        var counter = elm.retrieve('counter');
        if (curLen >= maxLen) {
          counter.update(' (' + count + ')').setStyle({'color': 'red'});
        } else {
          counter.update(' (+' + count + ')').setStyle({'color': 'green'});
        }
        return elm;
      }
    });
    
    // run setup and call countdown once outside of listener to initialize
    $$('.validate-length').invoke('prepare_for_countdown').invoke('countdown');
    
    // deferred listener, only responds to keyups that issue from a matching element
    document.on('keyup', '.validate-length', function(evt, elm){
      elm.countdown();
    });
    

    【讨论】:

    • 感谢您的帮助。如果您有时间,请您发布一些addMethods 工厂和deferred observer 模式的代码。我不经常使用 JS,但学习新东西总是很高兴:)
    • 我已经用一些例子更新了原始答案。
    • 非常感谢!这将有助于改进其他一些小脚本。
    猜你喜欢
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 2011-12-03
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-10
    相关资源
    最近更新 更多