Aşağıdaki tablo için bir CSS seçici arıyorum:
Peter | male | 34
Susanne | female | 12
"Erkek" içeren tüm tank avcılarına uyan herhangi bir seçici var mı?
$x
soruya cevap verir. orijinal soru için, $x("//td[text()='male']")
hile yapar
Aşağıdaki tablo için bir CSS seçici arıyorum:
Peter | male | 34
Susanne | female | 12
"Erkek" içeren tüm tank avcılarına uyan herhangi bir seçici var mı?
$x
soruya cevap verir. orijinal soru için, $x("//td[text()='male']")
hile yapar
Yanıtlar:
Ben okursanız şartname hayır, doğru.
Bir öğeyle, öğedeki özniteliğin adıyla ve öğedeki adlandırılmış özniteliğin değeriyle eşleşebilirsiniz. Yine de, bir öğedeki içeriği eşleştirmek için hiçbir şey göremiyorum.
:empty
.
JQuery kullanma:
$('td:contains("male")')
Görünüşe göre CSS3 spec için düşünüyorlardı ama kesmedi .
:contains()
CSS3 seçici 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.
Ve iyi bir nedenden dolayı, stil, içerik, yapı ve davranışı ayırma öncülünü ihlal edecektir.
data-gender
Bir male
veya female
değerle çağrılan satırlara bir veri özelliği eklemeniz ve özellik seçiciyi kullanmanız gerekir:
HTML:
<td data-gender="male">...</td>
CSS:
td[data-gender="male"] { ... }
male
ya da female
? Aslında class
diğer sınıfları ile doludur, bunların sıralaması garanti edilmez, vb yapar diğer sınıf adları ile collissions olabilir class
Bu tür görevler için daha kötü bir yer. Özel bir data-*
özellik, verilerinizi tüm bu öğelerden yalıtır ve özellik seçicileri kullanarak kısmi eşleme vb.
Aslında bunun neden uygulanmadığının çok kavramsal bir temeli vardır. Temel olarak 3 yönün bir kombinasyonudur:
Bu 3 birlikte metin içeriğine sahip olduğunuzda, içeren öğeye geri yükselemeyeceğiniz ve mevcut metni biçimlendiremeyeceğiniz anlamına gelir. Bu, büyük olasılıkla önemlidir, çünkü azalan içerik ve SAX stili ayrıştırmasının tekil olarak izlenmesine izin verir. Yükselen veya diğer eksenleri içeren diğer seçiciler, CSS'nin DOM'a uygulanmasını büyük ölçüde karmaşıklaştıracak daha karmaşık çaprazlama veya benzer çözümlere olan ihtiyacı ortaya çıkarır.
text()
işlevini kullanmak mümkün olacaktır .
:contains(<sub-selector>)
, başka belirli elementler içeren bir element seçmek için. Gibi div:contains(div[id~="bannerAd"])
reklamdan kurtulmak ve 's konteyner almak.
İçeriği veri özelliği olarak ayarlayabilir ve ardından burada gösterildiği gibi özellik seçicileri kullanabilirsiniz :
/* 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>
Veri içeriği özniteliklerini kolayca ayarlamak için jQuery'yi de kullanabilirsiniz:
$(function(){
$("td").each(function(){
var $this = $(this);
$this.attr("data-content", $this.text());
});
});
.text()
ve .textContent
oldukça ağır olan mümkün olduğunda uzun listeleri veya büyük metinlerde bunları önlemek için deneyin. .html()
ve .innerHTML
hızlı.
$("td:contains(male)")
contenteditable='true'
- benim durumum), data-content
sayfa oluşturulmadan önce özelliğin değerini ayarlamak yeterli değildir . Sürekli güncellenmesi gerekir. İşte ne kullanıyorum:<td onkeypress="event.target.setAttribute('data-content', event.target.textContent);">
CSS'de bu özellik bulunmadığından, hücreleri içeriğe göre biçimlendirmek için JavaScript kullanmanız gerekir. Örneğin XPath'larda contains
:
var elms = document.evaluate( "//td[contains(., 'male')]", node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null )
Sonra sonucu şöyle kullanın:
for ( var i=0 ; i < elms.snapshotLength; i++ ){
elms.snapshotItem(i).style.background = "pink";
}
Korkarım ki bu mümkün değil, çünkü içerik bir özellik değildir veya sahte bir sınıf aracılığıyla erişilebilir değildir. CSS3 seçicilerinin tam listesi CSS3 teknik özelliklerinde bulunabilir .
Selenium CSS metin seçimleri yapmak isteyenler için, bu komut dosyasının bir kısmı yararlı olabilir.
Hile, aradığınız öğenin üst öğesini seçmek ve ardından metni içeren alt öğeyi aramaktır:
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];
}
Bu benim durumumda her zaman bir öğe olduğundan birden fazla varsa ilk öğeyi döndürür.
TD:contains('male')
sen selenyum kullanıyorsanız: Eğer sınıfları eklemek kaynağını güncelleştirmek olamaz imho sadece kullanın. Örneğin, eski kodu test ediyorsanız veya şirketiniz geliştiricilerle konuşmanıza izin vermiyorsa (eurgh!) çünkü testleriniz kırılgan olacak ve birisi metni daha sonra değiştirirse masculine
veya dili değiştirirse kırılacaktır . SauceLabs dokümanları contains
burada kullanımını gösterir ( saucelabs.com/resources/articles/selenium-tips-css-selectors ) + cc @matas vaitkevicius bir şey kaçırdım mı?
Veri özniteliğinin (voyager'ın cevabı) nasıl ele alınması gerektiğine katılıyorum , AMA, CSS kuralları gibi:
td.male { color: blue; }
td.female { color: pink; }
kurulumu genellikle çok daha kolay olabilir, özellikle de angularjs gibi müşteri tarafındaki kütüphaneler kadar basit olabilir:
<td class="{{person.gender}}">
İçeriğin yalnızca bir kelime olduğundan emin olun! Veya aşağıdakilerle farklı CSS sınıfı adlarıyla eşleştirebilirsiniz:
<td ng-class="{'masculine': person.isMale(), 'feminine': person.isFemale()}">
Tamlık için veri özniteliği yaklaşımı:
<td data-gender="{{person.gender}}">
@ voyager'ın data-*
özelliği kullanma konusundaki cevabı (örn . 2017 itibariyle data-gender="female|male"
en etkili ve standartlara uygun yaklaşımdır:
[data-gender='male'] {background-color: #000; color: #ccc;}
Hemen hemen çoğu gol olabilir sınırlı seçicileri de olsa bazı metnin etrafında odaklı olduğu gibi elde edilebilir. :: İlk harfli bir olan sözde öğesi bir öğenin ilk harfine sınırlı stil uygulayabilirsiniz. Ayrıca bir :: first-line pseudo-element öğenin ilk satırını (paragraf gibi) seçmenin yanı sıra, CSS'nin bu mevcut yeteneği bir textNode'un belirli yönlerini şekillendirmek için kullanılabileceği de açıktır. .
Böyle bir savunuculuk başarılı oluncaya ve uygulanıncaya kadar önerebileceğim bir sonraki en iyi şey explode
/ split
bir boşluk sınırlayıcı kullanarak / kelimeler olduğunda , her bir span
öğeyi bir öğenin içine çıkarın ve ardından kelime / stil hedefi öngörülebilir kullanımla birleştiğinde : n. Seçiciler :
$p = explode(' ',$words);
foreach ($p as $key1 => $value1)
{
echo '<span>'.$value1.'</span>;
}
Else , öngörülemezse , voyager'ın data-*
özniteliği kullanma hakkındaki cevabını tekrar kullanın . PHP kullanan bir örnek:
$p = explode(' ',$words);
foreach ($p as $key1 => $value1)
{
echo '<span data-word="'.$value1.'">'.$value1.'</span>;
}
Chimp / Webdriver.io kullanıyorsanız , çok daha fazla CSS seçiciyi destekliyorlar CSS spec daha.
Bu, örneğin, "Kötü ayı" kelimelerini içeren ilk bağlantıya tıklayacaktır:
browser.click("a*=Bad Bear");
Buradaki cevapların çoğu, daha fazla veri eklemek için HTML kodunun nasıl yazılacağına alternatif sunmaya çalışıyor çünkü en azından CSS3'e kadar bir öğeyi kısmi iç metne göre seçemezsiniz. Ama yapılabilir, sadece biraz vanilya JavaScript eklemeniz gerekir, çünkü kadın da erkek içerdiğinden haberdar olun:
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>
Ayrıca kullanabilirsiniz content
ile attr()
olan stil tablo hücreleri ve ::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
rengi değiştirmek için kullanılır ve vanilya JavaScript kullanılarak eklenebilir:
const hombres = document.querySelectorAll('td[data-value="male"]');
hombres.forEach(hombre => hombre.innerHTML = '​');
Her ne kadar <td>
s uç etiketi atlanmış olsa da, boş olarak kabul edilmesine neden olabilir.
DOM'yi kendiniz oluşturmazsanız (örneğin, bir kullanıcı metninde) salt JS ile aşağıdakileri yapabilirsiniz:
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>
Konsol çıkışı
text: <td> Peter
text: <td> male
text: <td> 34
text: <td> Susanne
text: <td> female
text: <td> 12
male: <td text="male"> male
Bunun gibi küçük Filtre Widget'ları yapmak:
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')
}
})
})
Bu sorunun sözdizimi Robot Framework sözdizimine benziyor. Bu durumda, içerenler için kullanabileceğiniz bir css seçici olmasa da, bunun yerine kullanabileceğiniz bir SeleniumLibrary anahtar sözcüğü vardır. Eleman kadar bekleyin içerir .
Misal:
Wait Until Element Contains | ${element} | ${contains}
Wait Until Element Contains | td | male