次の表のCSSセレクターを探しています。
Peter | male | 34
Susanne | female | 12
「男性」を含むすべてのTDに一致するセレクターはありますか?
$x
質問に答えます。元の質問のために、$x("//td[text()='male']")
トリックん
次の表のCSSセレクターを探しています。
Peter | male | 34
Susanne | female | 12
「男性」を含むすべてのTDに一致するセレクターはありますか?
$x
質問に答えます。元の質問のために、$x("//td[text()='male']")
トリックん
回答:
仕様を正しく読んだ場合、違います。
要素、要素内の属性の名前、および要素内の名前付き属性の値を照合できます。しかし、要素内のコンテンツに一致するものは何も表示されません。
:empty
。
jQueryの使用:
$('td:contains("male")')
彼らはCSS3仕様についてそれについて考えていたように見えますが、それはうまくいきませんでした。
:contains()
CSS3セレクターhttp://www.w3.org/TR/css3-selectors/#content-selectors
Looks like they were thinking about it for the CSS3 spec but it didn't make the cut.
そして、それは正当な理由で、スタイル、コンテンツ、構造、および動作を分離するという前提全体に違反します。
あなたはと呼ばれる行にデータ属性を追加する必要があるだろうdata-gender
とmale
か、female
値と属性セレクタを使用します。
HTML:
<td data-gender="male">...</td>
CSS:
td[data-gender="male"] { ... }
male
またはそれ以上に変化している場合はどうなりますかfemale
?class
他のクラスで満たされているという事実、それらの順序は保証されていません、他のクラス名との衝突があるかもしれませんなどはclass
、この種のものにとってより悪い場所になります。専用のdata-*
属性は、データをそのすべてのものから分離し、属性セレクターを使用して部分的なマッチングなどを簡単に実行できるようにします。
これが実装されていない理由には、実際には非常に概念的な根拠があります。これは基本的に3つの側面の組み合わせです。
これら3つを合わせて、テキストコンテンツを取得するまでに、上位の要素に戻ることはできず、現在のテキストのスタイルを設定することはできません。降順ではコンテキストとSAXスタイルの解析の単一追跡のみが可能であるため、これはおそらく重要です。他の軸を含む昇順または他のセレクターは、CSSのDOMへの適用を非常に複雑にする、より複雑なトラバーサルまたは同様のソリューションの必要性をもたらします。
text()
関数を使用することができます。
:contains(<sub-selector>)
、他の特定の要素を含む要素を選択する方法を教えてください。div:contains(div[id~="bannerAd"])
広告とそのコンテナを取り除くのが好きです。
次に示すように、コンテンツをデータ属性として設定し、属性セレクターを使用できます。
/* Select every cell containing word "male" */
td[data-content="male"] {
color: red;
}
/* Select every cell starting on "p" case insensitive */
td[data-content^="p" i] {
color: blue;
}
/* Select every cell containing "4" */
td[data-content*="4"] {
color: green;
}
<table>
<tr>
<td data-content="Peter">Peter</td>
<td data-content="male">male</td>
<td data-content="34">34</td>
</tr>
<tr>
<td data-conten="Susanne">Susanne</td>
<td data-content="female">female</td>
<td data-content="14">14</td>
</tr>
</table>
jQueryを使用して、データコンテンツの属性を簡単に設定することもできます。
$(function(){
$("td").each(function(){
var $this = $(this);
$this.attr("data-content", $this.text());
});
});
.text()
と.textContent
かなり重いので、可能な場合は長いリストや大きなテキストにそれらを避けるようにしてください。.html()
と.innerHTML
高速です。
$("td:contains(male)")
contenteditable='true'
私の場合)、data-content
ページがレンダリングされる前に属性の値を設定するだけでは不十分です。継続的に更新する必要があります。ここで私が使用するもの:<td onkeypress="event.target.setAttribute('data-content', event.target.textContent);">
CSSにはこの機能がないため、JavaScriptを使用してコンテンツによってセルのスタイルを設定する必要があります。たとえばXPathの場合contains
:
var elms = document.evaluate( "//td[contains(., 'male')]", node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null )
次に、結果を次のように使用します。
for ( var i=0 ; i < elms.snapshotLength; i++ ){
elms.snapshotItem(i).style.background = "pink";
}
コンテンツは属性ではなく、疑似クラスを介してアクセスできないため、これは不可能だと思います。CSS3セレクタの完全なリストは、CSS3仕様にあります。
Selenium CSSテキスト選択を行うことを検討している人にとって、このスクリプトはある程度役立つかもしれません。
秘訣は、探している要素の親を選択し、テキストを持つ子を検索することです。
public static IWebElement FindByText(this IWebDriver driver, string text)
{
var list = driver.FindElement(By.CssSelector("#RiskAddressList"));
var element = ((IJavaScriptExecutor)driver).ExecuteScript(string.Format(" var x = $(arguments[0]).find(\":contains('{0}')\"); return x;", text), list);
return ((System.Collections.ObjectModel.ReadOnlyCollection<IWebElement>)element)[0];
}
これは、私の場合は常に1つの要素であるため、複数ある場合は最初の要素を返します。
TD:contains('male')
ますが、セレンを使用している場合:あなたがクラスを追加するには、ソースを更新できない場合私見は、それを使用しています。たとえば、レガシーコードをテストしている場合、または会社が開発者に話しかけることを許可しない場合(eurgh!)は、テストが脆弱であり、誰かが後でテキストをmasculine
変更したり言語を変更したりすると壊れます。SauceLabs docsはcontains
ここの使用法を示しています(saucelabs.com/resources/articles/selenium-tips-css-selectors)+ cc @matas vaitkevicius何かを見逃しましたか?
data属性(voyagerの答え)は、それがどのように処理されるべきか、CSSルールが次のようであることに同意します。
td.male { color: blue; }
td.female { color: pink; }
多くの場合、特に設定がはるかに簡単です。特に次のように単純なangularjsのようなクライアント側のライブラリを使用すると、
<td class="{{person.gender}}">
内容が一語であることを確認してください!または、次のようにして別のCSSクラス名にマップすることもできます。
<td ng-class="{'masculine': person.isMale(), 'feminine': person.isFemale()}">
完全を期すために、データ属性アプローチは次のとおりです。
<td data-gender="{{person.gender}}">
data-*
属性の使用に関する@voyagerの回答(例:2017年の時点でdata-gender="female|male"
最も効果的で標準に準拠したアプローチ:
[data-gender='male'] {background-color: #000; color: #ccc;}
テキストを中心とした限られたセレクターもありますが、ほとんどの目的は達成できます。::最初の文字である擬似要素要素の最初の文字に限定スタイルを適用することができます。あります::最初の行の擬似要素は、(例えば、段落など)は明らかに要素の最初の行を選択する以外にも、CSSがtextNodeのスタイルの特定の側面には、この既存の機能を拡張するために使用することができることが明らかであることを意味し。
そのようなアドボカシーが成功して実装されるまで、私が提案できる次の最高のものは、スペースデリミネーターを使用したexplode
/ split
ワードです。span
要素内の個々のワードを出力し、ワード/スタイリングの目標が:nthセレクターと組み合わせて予測可能な使用かどうかを示します。:
$p = explode(' ',$words);
foreach ($p as $key1 => $value1)
{
echo '<span>'.$value1.'</span>;
}
それ以外の場合は、予測できない場合は、data-*
属性の使用に関するボイジャーの回答を使用します。PHPの使用例:
$p = explode(' ',$words);
foreach ($p as $key1 => $value1)
{
echo '<span data-word="'.$value1.'">'.$value1.'</span>;
}
Chimp / Webdriver.ioを使用している場合、CSS仕様よりもはるかに多くのCSSセレクターをサポートしています。
これは、たとえば、「Bad bear」という単語を含む最初のアンカーをクリックします。
browser.click("a*=Bad Bear");
ここでの回答のほとんどは、HTMLコードを記述してより多くのデータを含める方法に代わるものを提供しようとしています。これは、少なくともCSS3までは、部分的な内部テキストで要素を選択できないためです。しかし、それは可能です。ちょっとしたバニラJavaScriptを追加する必要があります。女性には男性も含まれているため、選択されます。
cells = document.querySelectorAll('td');
console.log(cells);
[].forEach.call(cells, function (el) {
if(el.innerText.indexOf("male") !== -1){
//el.click(); click or any other option
console.log(el)
}
});
<table>
<tr>
<td>Peter</td>
<td>male</td>
<td>34</td>
</tr>
<tr>
<td>Susanne</td>
<td>female</td>
<td>14</td>
</tr>
</table>
<table>
<tr>
<td data-content="Peter">Peter</td>
<td data-content="male">male</td>
<td data-content="34">34</td>
</tr>
<tr>
<td data-conten="Susanne">Susanne</td>
<td data-content="female">female</td>
<td data-content="14">14</td>
</tr>
</table>
また、使用することができcontent
てattr()
いるスタイルテーブルのセルと::not
:empty
th::after { content: attr(data-value) }
td::after { content: attr(data-value) }
td[data-value]:not(:empty) {
color: fuchsia;
}
<table>
<tr>
<th data-value="Peter"></th>
<td data-value="male">​</td>
<td data-value="34"></td>
</tr>
<tr>
<th data-value="Susanne"></th>
<td data-value="female"></td>
<td data-value="12"></td>
</tr>
<tr>
<th data-value="Lucas"></th>
<td data-value="male">​</td>
<td data-value="41"></td>
</tr>
</table>
A ZeroWidthSpace
は色を変更するために使用され、バニラJavaScriptを使用して追加できます。
const hombres = document.querySelectorAll('td[data-value="male"]');
hombres.forEach(hombre => hombre.innerHTML = '​');
けれども<td>
sの終了タグを省略することができるようにすること、それが空でないものとして扱われる可能性があります。
自分でDOMを作成しない場合(たとえば、ユーザースクリプトで)、純粋なJSを使用して以下を実行できます。
for ( td of document.querySelectorAll('td') ) {
console.debug("text:", td, td.innerText)
td.setAttribute('text', td.innerText)
}
for ( td of document.querySelectorAll('td[text="male"]') )
console.debug("male:", td, td.innerText)
<table>
<tr>
<td>Peter</td>
<td>male</td>
<td>34</td>
</tr>
<tr>
<td>Susanne</td>
<td>female</td>
<td>12</td>
</tr>
</table>
コンソール出力
text: <td> Peter
text: <td> male
text: <td> 34
text: <td> Susanne
text: <td> female
text: <td> 12
male: <td text="male"> male
次のような小さなフィルターウィジェットを実行します。
var searchField = document.querySelector('HOWEVER_YOU_MAY_FIND_IT')
var faqEntries = document.querySelectorAll('WRAPPING_ELEMENT .entry')
searchField.addEventListener('keyup', function (evt) {
var testValue = evt.target.value.toLocaleLowerCase();
var regExp = RegExp(testValue);
faqEntries.forEach(function (entry) {
var text = entry.textContent.toLocaleLowerCase();
entry.classList.remove('show', 'hide');
if (regExp.test(text)) {
entry.classList.add('show')
} else {
entry.classList.add('hide')
}
})
})
この質問の構文は、ロボットフレームワークの構文に似ています。この場合、containsに使用できるcssセレクターはありませんが、代わりに使用できるSeleniumLibraryキーワードがあります。要素まで待つが含まれてい。
例:
Wait Until Element Contains | ${element} | ${contains}
Wait Until Element Contains | td | male