2017-01-22 2 views
0

私は関数を呼び出すクリックハンドラを作ろうとしています。その関数は文字列を取得し、基本的に最後の文字をスライスして前面に追加し、再度クリックするたびに最後の文字を前面に追加します。clickイベントのJavascript on else文または変数を読み取らない

まず、配列メソッドを使用してやることができると思ったのはとても簡単です。

function scrollString() { 

    var defaultString = "Learning to Code Javascript Rocks!"; 
    var clickCount = 0; 

    if (clickCount === 0) { 
     var stringArray = defaultString.split(""); 
     var lastChar = stringArray.pop(); 
     stringArray.unshift(lastChar); 
     var newString = stringArray.join(''); 
     clickCount++; 

    } else { 
     var newArray = newString.split(""); 
     var newLastChar = newArray.pop(); 
     newArray.unshift(newLastChar); 
     var newerString = newArray.join(""); 
     clickCount++; 
    } 

    document.getElementById('Result').innerHTML = (clickCount === 1) ? newString : newerString; 

} 

$('#button').on('click', scrollString); 

今すぐクリックすると動作します。開発ツールでは、newArrayは定義されていません。また、clickCountはインクリメントを停止します。私はそれが範囲の問題であるかどうか、あるいは私が問題に対して全く異なるアプローチをとるべきかどうかはわかりません。

答えて

1

クリックするたびに、実際に文字列がリセットされます。スコープを確認してください!

var str = "Learning to Code Javascript Rocks!"; 
 
var button = document.getElementById("button"); 
 
var output = document.getElementById("output"); 
 

 

 
output.innerHTML = str; 
 

 
button.addEventListener("click", function(e){ 
 
\t str = str.charAt(str.length - 1) + str.substring(0, str.length - 1); 
 
    output.innerHTML = str; 
 
});
button{ 
 
    display: block; 
 
    margin: 25px 0; 
 
}
<button id="button">Click Me!</button> 
 

 
<label id="output"></label>

+0

この答えは私のものよりもはるかに優れています。 upvoteを取る。私は実際にこの部分を行うにはあまりにも怠惰でした。非常に素晴らしい。 – thesublimeobject

+0

ありがとう、私はそれを感謝する! – Gacci

+0

シンプルなおい、おかげさま....私はまだコードを学んでいるので、私はプロセスをoverthoughtと思う:) – giovannihr

0

実際には、スコープの問題です。関数内のカウンターなので、関数が呼び出されるたびに0に設定されます。カウンターがスコープ外にあり、実際に適切なカウントを保持するようにするには、関数からカウンターを抽象化する必要があります。

単純なままにしたい場合は、関数の上にあるclickCountを移動するだけで機能するはずです。

0

それはスコープ

の問題だ場合、私は知りませんはい、それは、実際には複数のスコープの問題です。

どのようにですか?

  1. @thesublimeobjectで指摘したように、カウンタが関数内にあるので、クリックイベントが発生するたびに再初期化されます。
  2. カウンタを関数の外に置いても、別のスコープの問題に直面します。関数の一部であるelseでは、ifスニペット内で初期化した変数(newString)が操作されます。今回はifスニペットが実行されなかったため、エラーundefinedがスローされます。 (再びスコープ号)

細かいアプローチは次のようになります

  1. 機能外側カウンタを取るとdefaultStringdefaultStringが動的ではなく、あなたのコードで示したものよりも値を取得した場合は、ページのロードまたはむしろ関数の中にそれを渡すよりもchange、などのような他のイベントでその値を抽出します。
  2. 操作結果を新しい文字列に代入しないでください。代わりにdefaultStringに割り当てます。この方法では、おそらくif-elseのループとnewLastCharの新しい結果を処理する必要はありません。
  3. それに応じて要素への割り当てを操作します。
+0

それは合計感覚:)ありがとう... – giovannihr

0

あなたはJavascriptを閉鎖機能を使用することができます。

var scrollString = (function() { 
var defaultString = "Learning to Code Javascript Rocks!"; 
return function() { 
    // convert the string into array, so that you can use the splice method 
    defaultString = defaultString.split(''); 

    // get last element 
    var lastElm = defaultString.splice(defaultString.length - 1, defaultString.length)[0]; 

    // insert last element at start 
    defaultString.splice(0, 0, lastElm); 

    // again join the string to make it string 
    defaultString = defaultString.join(''); 
    document.getElementById('Result').innerHTML = defaultString; 
    return defaultString; 
} 
})(); 

これを使用すると、変数をグローバルに宣言する必要はありません。

はJavascriptクロージャを理解するために、これを参照してください。 http://www.w3schools.com/js/js_function_closures.asp

+0

天才....私は閉鎖を使用したいと思いましたがソリューションの実装方法はわかりませんでした。私はあなたの助けに感謝... xD – giovannihr

関連する問題