2017-06-08 9 views
0

このコードは、prototype.jsの1.6のために働いたが、1.7にアップグレードするので、私はエラーを取得:uncaught exception: Syntax error, unrecognized expression: [object HTMLInputElement]prototype.jsの1.7キャッチされない例外:構文エラー、認識できない表現:[オブジェクト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() {

助けをお待ちしています。

答えて

2

コレクションをループする列挙子の中にあるインスタンス変数(elem)は、コレクションではなく特異なオブジェクトです。したがって、elem.observe('keyup', function() { ... });を使用してオブザーバをインスタンス化します。

"double-dollar"関数は、最初の引数として渡されたCSSセレクタに一致するDOM要素のコレクションを検索します。しかし、あなたはすでにスクリプトの最上部でそれを行っています。だから、そのコレクションの各メンバーはすでに "発見"されています(Prototypeのメソッドのすべてで拡張されています)。

これにはいくつかの最適化が用意されています。カウントダウンを行うための関数を1つ作成する必要があります。おそらくaddMethodsファクトリを使用して入力のプロトタイプにチェーンする必要があります。したがって、各テキストエリアに対して新しい匿名関数を作成する必要はありません。次に、各ページにこれらの入力が非常に少ない場合は、「遅延オブザーバ」パターンを見て、入力ごとに別々のオブザーバを作成するのではなく、ページ全体に対して1人のオブザーバを書くことができます。要求されたよう

例、:あなたの助けのための

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(); 
}); 
+0

感謝。時間があれば、 'addMethods'ファクトリと'遅延オブザーバ 'パターンのコードを投稿してください。私はJSで頻繁には動作しませんが、何か新しいことを学ぶのはいいです:) – sv3n

+1

私はいくつかの例で元の答えを更新しました。 – Walter

+0

ありがとう!これは、他の小さなスクリプトを改善するのに役立ちます。 – sv3n

関連する問題