2017-01-30 7 views
4

を作る私は別に、各文字を押すたびにボタンを選択し、文字セレクタを作るしようとしています。しかし、そのあなたはspanタグにすべての文字を入れて、スパンの背景色を変更するために必要なすべてのJavaScriptの文字セレクタ

<!DOCTYPE html> 
 
<html lang="en"> 
 

 
    <head> 
 
    <title>HELLO WORLD</title> 
 
    </head> 
 

 
    <body> 
 
    <center> 
 
     <br /> 
 
     <p id="temp">ABCDEFGHIJKLMNOPQRSTUVWXYZ</p> 
 
     <br /> 
 
     <input type="button" onclick="selector()" value="SELECT" /> 
 

 
     <script> 
 

 
     var x = document.getElementById("temp").innerHTML; 
 
     var i = 0; 
 

 
     function selector() { 
 
      x.charAt(i).style.backgroundColor = "red"; 
 
      i++; 
 
     } 
 

 
     </script> 
 
    </center> 
 
    </body> 
 

 
</html>

+0

あなたは、単一の文字のスタイルを設定することはできません。私は、それぞれの文字をそれぞれ「スパン」でラップし、それをスタイリングすることをお勧めします。 – evolutionxbox

+0

チャレンジは@evolutionxboxになり、ネストされたタグの各文字をラップしないようにします。示されているinnerHTMLを考えると、それは問題ではありません。しかし、この同じコードが子孫タグで再利用される場合、このアプローチで完全に壊れてしまいます。 – Snowmonkey

+0

@Armin 'selector()'関数は 'i'をインクリメントします。 –

答えて

3

ここに1つの可能な実装だ

  • string#splitを使用してHTML要素内の文字のリストを作成します。
  • spanタグ内のこれらの文字のそれぞれを包みます。これは、map機能を使用すると簡単です。これらが英字であるかどうかを確認したいので、test関数を使用します。
  • 我々は、元の文字列の文字数を見つける必要があります。それを行うには、すべてのspanタグの新しい文字列を取り除くことができます。最初の文字をJavaScriptにゼロに設定します。
  • イベントリスナーを呼び出します。これは、たとえば、キーの押下を待ち受ける​​です。
  • 私たちの文字のすべてが今char型のクラスでラップされています。特定の文字を見つけるには、document.querySelectorAllを使用してください。[index]
  • 文字列を循環する場合は、リストの最後の文字のスタイルを削除します。さもなければ、直前の文字は自然に元に戻されます。

var chars = document.getElementById("par").innerHTML.split(''); 
 

 
var wrapped = chars.map(c => /[a-z]/i.test(c) ? "<span class='char'>" + c + "</span>" : "").join(''); 
 
var numLetters = wrapped.replace(/<span class='char'>/g, '').replace(/<\/span>/g, '').length; 
 

 
document.getElementById("par").innerHTML = wrapped; 
 

 
var index = 0; 
 
document.addEventListener("keydown", function() { 
 
    document.querySelectorAll(".char")[index].style.color = "red"; 
 
    if (index == 0) { 
 
     document.querySelectorAll(".char")[numLetters - 1].style.color = "black"; 
 
    } 
 
    if (index > 0) { 
 
     document.querySelectorAll(".char")[index - 1].style.color = "black"; 
 
    } 
 
    index = index == numLetters - 1 ? 0 : index + 1 
 
});
<p id="par">This is a paragraph</p>

+0

ありがとう;):) –

+0

ハッピーに助けました –

2

で働いていません。

var i = 0; 
 

 
function selector() { 
 
    if (document.getElementById("temp_" + i)) 
 
    document.getElementById("temp_" + i).style.backgroundColor = "red"; 
 
    i++; 
 
}
<p id="temp"> 
 
    <span id='temp_0'>A</span> 
 
    <span id='temp_1'>B</span> 
 
    <span id='temp_2'>C</span> 
 
    <span id='temp_3'>D</span> 
 
</p> 
 

 
<button onclick='selector();'>Test</button>

+0

このアプローチの私の問題は、化粧用のHTMLにプログラム的な変更を強制することです。これらのタグは、ページの実際のレンダリングには必要ありません。デザイナーから取得した場合、それらのタグは表示されません。だから、Scott Marcusのアプローチでは、彼はそのままHTMLを使って作業し、プログラム的な変更を必要としています。 – Snowmonkey

+0

これは質問への返信で、行う方法を説明しています。 Scottは私のようなスパンタグを作成します。しかし彼はJSでスパンを作りました。これは別の方法です。私は最良のアプローチを掲示するのではなく、問題を解決する方法を説明するためにここにはいません。 – R3tep

+0

ありがとう;):) –

5

主な問題は、あなただけのHTML要素ではなく、要素のテキストコンテンツを構成する個々の文字にスタイルを適用することができるということです。

は、これは、あなたがしている「未定義」エラーを取得している理由... backgroundColorは、個々の文字の上に存在していないstyleプロパティの戻り値を指し、undefinedに設定することはできませんです。

最初に、強調表示する文字を別の要素にラップする必要があります(ここでは<span>が最適です)。<span>の内容を強調表示することができます。

あなたは、ボタンの各クリックだけ次の文字やハイライトは次の文字を含むように拡張されなければならないので、私は下記の者の両方のためのソリューションを持っている場合を強調すべきかどうかについて、正確には明らかでありませんでした。詳細な説明については、インラインコメントを参照してください:

溶液#1(一度に単一の文字を強調表示)

// Get DOM reference to paragraph (not contents of paragraph) 
 
var x = document.getElementById("temp"); 
 

 
// Get DOM reference to button so we can wire it up to 
 
// an event handler in JS (not via inline event handling attributes). 
 
var btn = document.getElementById("btn"); 
 

 
// Set up event handler: 
 
btn.addEventListener("click", selector); 
 

 
var i = 0; 
 

 
function selector() { 
 
    
 
    // Get the character to be highlighted 
 
    var char = x.textContent.charAt(i); 
 
    
 
    // Set the contents of the paragraph to a new string that has the particular character 
 
    // wrapped with a <span> that is set to use a predetermined class that does the actual 
 
    // highlighting. 
 
    x.innerHTML = x.textContent.replace(char, "<span class='highlight'>" + char + "</span>"); 
 
    
 
    // Increment i until we've hit the 26th value, then reset to 0 
 
    i < 25 ? i++ : i = 0; 
 
}
.highlight { background-color:red; }
<p id="temp">ABCDEFGHIJKLMNOPQRSTUVWXYZ</p> 
 
<br> 
 

 
<!-- There is no closing tag for input elements! --> 
 
<input type="button" id="btn" value="SELECT">

溶液#2(次の文字を含めるように強調表示拡張)

// Get DOM reference to paragraph (not contents of paragraph) 
 
var x = document.getElementById("temp"); 
 

 
// Get DOM reference to button so we can wire it up to an event handler in JS (not via inline event 
 
// handling attributes). 
 
var btn = document.getElementById("btn"); 
 

 
// Set up event handler: 
 
btn.addEventListener("click", selector); 
 

 
var i = 0; 
 

 
function selector() { 
 
    
 
    // Get the character to be highlighted 
 
    var char = x.textContent.charAt(i); 
 
    
 
    // Set the contents of the paragraph to a new string that encloses all the characters 
 
    // up to and including the current one in a <span> that is set to use a predetermined 
 
    // class that does the actual highlighting. 
 
    x.innerHTML = "<span class='highlight'>" + x.textContent.replace(char, char + "</span>"); 
 
    
 
    // Increment i until we've hit the 26th value, then reset to 0 
 
    i < 25 ? i++ : i = 0; 
 
}
.highlight { background-color:red; }
<p id="temp">ABCDEFGHIJKLMNOPQRSTUVWXYZ</p> 
 
<br> 
 

 
<!-- There is no closing tag for input elements! --> 
 
<input type="button" id="btn" value="SELECT">

+0

エレガントで拡張可能です。うまくコード化! – Snowmonkey

+0

ありがとうございました:) –