특정 텍스트를 포함하는 요소에 대한 CSS 선택기가 있습니까?


511

다음 표에 대한 CSS 선택기를 찾고 있습니다.

Peter    | male    | 34
Susanne  | female  | 12

"male"을 포함하는 모든 TD와 일치하는 선택기가 있습니까?


1
문제는 이것이 수행 방식으로 구현하기가 매우 어렵다는 것입니다.
Ms2ger

7
XPath 선택기는 .text () 메소드를 사용하여 수행 할 수 있습니다 (JavaScript 실행 프로그램을 사용하지 않으려는 경우).
djangofan 2019

11
다음은 xpath : // h1 [text () = 'Session']을 사용하여 수행 할 수있는 방법의 예입니다. $ x ( "// h1 [text () = 'Session']"을 입력하여 Chrome에서 xpath를 테스트 할 수 있습니다. ) 콘솔에서
VinnyG

1
이것은 매우 편리합니다. 예를 들어, 확인 표시가 포함 된 표 셀이나 문자열 "Yes", "Pass", "OK"등은 녹색 일 수 있습니다.
Andreas Rejbrand

$x질문에 응답합니다. 원래 질문에 $x("//td[text()='male']")대한 트릭을 수행
Xiao

답변:


393

사양을 올바르게 읽으면 아니요.

요소, 요소의 속성 이름 및 요소의 명명 된 속성 값을 일치시킬 수 있습니다. 그래도 요소 내에서 일치하는 콘텐츠에 대한 내용은 없습니다.


227
한 가지 경우가 있습니다 : :empty.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

34
내 자신의 질문에 대답하기 위해 : 예, 오늘날에도 여전히 그렇습니다! 콘텐츠 선택기가 더 이상 사용되지 않습니다! CSS3 이후 더 이상 컨텐츠 선택기가 없습니다. ( w3.org/TR/css3-selectors/#selectors )
Wlad

158

jQuery 사용하기 :

$('td:contains("male")')

7
jQuery (element) .not ( ": contains ( 'string')")
Jazzy

310
CSS가 아니라면 JavaScript입니다.
Synetech

9
동의-그래서 내 대답은 CSS가 아닌 jQuery를 사용한다고 말했습니다. 그러나 내 대답의 그 부분은 편집되었습니다. =)
moettinger

18
그러나 fe 남성 이라는 단어 자체에도 'male'이라는 단어가 포함되어 있습니까? 그냥 '남성 남성이 먼저 작동합니까? 다시 주문하면 버그가 발생합니까?
Michael Durrant

5
@ Michael Durrant : 당신은 농담이지만, 요소 간 문자열 일치 (동일한 요소 내의 일반 하위 문자열 일치보다 훨씬 큰 문제)는 실제로 가장 큰 이유 중 하나입니다 : contains ()가 삭제되었습니다.
BoltClock

158

CSS3 사양에 대해 생각하고있는 것처럼 보이지만 잘랐습니다 .

:contains()CSS3 선택기 http://www.w3.org/TR/css3-selectors/#content-selectors


9
Looks like they were thinking about it for the CSS3 spec but it didn't make the cut.그리고 정당한 이유 때문에 스타일, 내용, 구조 및 행동을 분리한다는 전제를 위반할 것입니다.
Synetech

56
@Synetech 그것은 스타일링을 컨텐츠에서 분리하는 데 도움이 될 수 있습니다. 이는 컨텐츠가 클라이언트에 대해 알 필요가 없다는 것이 기본 스타일링에 대한 중요성만큼 고려 될 것이라는 의미이기 때문입니다. 현재 html 콘텐츠는 일반적으로 스타일러가 관심을 갖는 클래스를 포함시켜 CSS와 밀접하게 연결되어 있습니다. CSS3의 속성 값 선택기에서 알 수 있듯이 콘텐츠에서 CSS를 허용하는쪽으로 이미 전환하고 있습니다.
DannyMeister

8
@Synetech 그리고 정확히 어떻게 "행동"입니까? 나에게 그것은 프레젠테이션의 문제입니다. 그것은하지 않습니다 것을 - 그것이 제시 특정한 방식으로 특정 유형의 콘텐츠를.
BarbaraKwarc

4
@DannyMeister, 오 당신은 저를 설득 할 필요가 없습니다. 2 년이 지난 지금 나는이 기능을 정확하게 찾으려고 노력하면서 동시에 자신을 발견하고 존재하지 않을뿐만 아니라 거부되었다는 사실을 화나게했습니다. 😒 eBay는 UI를 변경하고 사이트를 사용하기가 매우 어려워졌습니다. 사용자 스타일 시트로 수정하려고하지만 마크 업이 경매와 BIN 목록을 구별하지 않으므로 목록에서 입찰 수를 강조 표시하는 유일한 방법은 텍스트 내용으로 요소를 일치시키는 것입니다. 누군가가 유스 케이스 시나리오를 직접 경험하도록 설득하는 데 필요한 모든 것.
Synetech

8
내용과 스타일을 잘 구분하기 위해 : contains () 선택기가 없습니다. 따라서 내용 (예 : "열기"또는 "해결됨"의 "상태"열)을 기준으로 셀을 스타일링하는 대신 디스플레이와 클래스 속성 모두에서 내용을 복제 한 다음 해당 항목을 선택합니다. . 우수한!
Jon Kloske

122

당신은 호출 된 행에 데이터 속성을 추가해야 할 것 data-gender로모그래퍼 male또는 female값과 속성 선택기를 사용합니다 :

HTML :

<td data-gender="male">...</td>

CSS :

td[data-gender="male"] { ... }

10
Javascript 및 CSS와 함께 사용자 정의 데이터 속성을 사용하는 것이 좋습니다. 데이터 속성을 사용하여 MDN
Michael Benjamin

1
데이터 속성이 처리 방법에 동의하지만 td.male과 같은 CSS 규칙은 특히 <td class = "{{person.gender}}와 같은 각도로 설정하는 것이 훨씬 쉽습니다. ">
DJDaveMark

젠더는 물론 클래스가 작동하는 전형적인 예입니다. 그러나 데이터는 더 단지보다 다양 어떤 경우 malefemale? 사실 class다른 클래스로 가득는, 그 순서는 보장되지 않으므로, 등이 만드는 다른 클래스 이름을 가진 collissions이있을 수 있습니다 class이런 종류의 물건에 대한 나쁜 곳. 전용 data-*속성은 데이터를 모든 것들과 분리하고 속성 선택기를 사용하여 데이터에 대한 부분 매칭 등을 쉽게 만듭니다.
Stijn de Witt

유사한 방식으로 데이터 속성을 사용하는 작동 코드 스 니펫에 대한 또 다른 대답이 있습니다.
Josh Habdas

65

실제로 이것이 구현되지 않은 이유는 매우 개념적입니다. 기본적으로 3 가지 측면의 조합입니다.

  1. 요소의 텍스트 내용은 사실상 해당 요소의 자식입니다.
  2. 텍스트 콘텐츠를 직접 타겟팅 할 수 없습니다
  3. CSS는 선택기로 승천 할 수 없습니다

이 3은 텍스트 내용이있을 때 포함 요소로 다시 올라갈 수 없으며 현재 텍스트의 스타일을 지정할 수 없음을 의미합니다. 내림차순은 컨텍스트 및 SAX 스타일 구문 분석의 단일 추적 만 허용하므로 중요합니다. 다른 축을 포함하는 오름차순 또는 기타 선택기에서는 CSS를 DOM에 적용하는 것을 크게 복잡하게하는보다 복잡한 순회 또는 유사한 솔루션이 필요합니다.


4
사실입니다. 이것이 XPath의 목적입니다. JS / jQuery 또는 파싱 라이브러리 (CSS 전용이 아닌)에서 선택기를 실행할 수 있다면 XPath의 text()기능 을 사용할 수 있습니다 .
Mark Thomas

그것은 content 에 대한 좋은 지적 입니다. 그러나 :contains(<sub-selector>)다른 특정 요소가 포함 된 요소를 선택할 수 있기를 바랍니다 . 등 div:contains(div[id~="bannerAd"])광고 제거하고 그것의 컨테이너하세요.
로렌스 돌

27

다음과 같이 컨텐츠를 데이터 속성으로 설정 한 다음 속성 선택기 를 사용할 수 있습니다.

/* 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());
  });
});

3
노트 .text().textContent꽤 무거운, 가능하면 긴 목록 또는 대형 텍스트에서 그들을 피하려고. .html()그리고 .innerHTML빠르다.
oriadam

@JoshHabdas jsbin / jsfiddle 변경 예를 만들 수 있습니까?
Buksy

1
jQuery를 사용하려면 contains 선택기를 사용하십시오.$("td:contains(male)")
huwiler

사용자가 컨텐츠를 편집 할 수있는 contenteditable='true'경우 ( -필자의 경우) data-content페이지를 렌더링하기 전에 속성 값을 설정하는 것만으로는 충분하지 않습니다 . 지속적으로 업데이트해야합니다. 여기에 내가 사용하는 것 :<td onkeypress="event.target.setAttribute('data-content', event.target.textContent);">
caram

13

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";
}

https://jsfiddle.net/gaby_de_wilde/o7bka7Ls/9/


이것은 자바 스크립트입니다.이 질문과 어떻게 관련이 있습니까?
rubo77

3
CSS의 내용으로 선택할 수 없으므로 js를 사용해야합니다. 이것이 CSS가 아니라고 지적하는 것은 옳지 만 데이터 속성의 사용은 내용별로 선택되지 않습니다. 우리는 독자가 왜 내용으로 셀을 선택하고 싶어하는지, 그녀가 HTML에 어떤 종류의 접근 권한을 가지고 있는지, 얼마나 많은 매치, 테이블이 얼마나 큰지 등을
추측 할 수 있습니다

7

내용이 속성이 아니거나 의사 클래스를 통해 액세스 할 수 없기 때문에 이것이 불가능하다는 것을 두려워합니다. CSS3 선택기의 전체 목록은 CSS3 사양 에서 찾을 수 있습니다 .


4

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];
}

내 경우에는 항상 하나의 요소이므로 둘 이상의 요소가 있으면 첫 번째 요소를 반환합니다.


TD:contains('male')Selenium을 사용하는 경우 사용할 수 있습니다 . imho는 소스를 업데이트하여 클래스를 추가 할 수없는 경우에만 사용합니다. 예를 들어 레거시 코드를 테스트하거나 회사에서 개발자와 대화 할 수없는 경우 테스트가 약하고 누군가가 텍스트를 나중에 masculine변경하거나 언어 를 변경하면 중단 될 수 있기 때문 입니다. SauceLabs 문서는 containshere ( saucelabs.com/resources/articles/selenium-tips-css-selectors )의 사용을 보여줍니다 + cc @matas vaitkevicius 내가 뭔가를 놓쳤습니까?
스노우 코드

3

나는 데이터 속성 (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}}">

템플릿 바인딩은 훌륭한 솔루션입니다. 하지만 (즉, 거의 무엇 불구하고 마크 업 구조를 기반으로 클래스 이름을 생성하는 비트 싫어지기 느낌 BEM은 실제로 수행을).
Josh Habdas

2

data-*속성 사용에 대한 @voyager의 답변 (예 : 2017 년 data-gender="female|male"가장 효과적이고 표준을 준수하는 접근 방식입니다.

[data-gender='male'] {background-color: #000; color: #ccc;}

텍스트를 중심으로 한 제한된 선택기가 있지만 거의 대부분의 목표를 달성 할 수 있습니다. :: 첫 번째 문자는 A는 의사 요소 요소의 첫 글자로 제한 스타일을 적용 할 수 있습니다. 도있다 : 첫째 줄 또한 CSS는 textNode의 스타일의 특정 측면이 기존의 기능을 확장하는 데 사용할 수있는 것은 분명하다 것을 의미한다 분명히 (예 : 단락으로) 요소의 첫 번째 행을 선택 외에 의사 요소는 .

이러한 옹호가 성공 하고 적용 될 때까지 스페이스 델리 미네 이터를 사용하여 explode/ split단어에 적용 할 때 제안 할 수있는 다음 가장 좋은 것은 span요소 내부의 각 개별 단어를 출력 한 다음 단어 / 스타일 목표 를 예측 가능한 경우 : n 번째 선택기 와 함께 사용하는 경우 :

$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>;
}


1

여기에있는 대부분의 답변은 적어도 CSS3까지 부분 내부 텍스트로 요소를 선택할 수 없기 때문에 더 많은 데이터를 포함하도록 HTML 코드를 작성하는 방법에 대한 대안을 제공하려고합니다. 그러나 수행 할 수 있습니다. 바닐라 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>

1

javascript 또는 jquery를 사용하지 않으려는 경우 속성 옵션이 가장 좋은 방법입니다.

예를 들어 ready라는 단어로 모든 표 셀의 스타일을 지정하려면 HTML에서 다음을 수행하십시오.

 <td status*="ready">Ready</td>

그런 다음 CSS에서 :

td[status*="ready"] {
        color: red;
    }

0

당신은 또한 사용할 수 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">&#x0200B;</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">&#x0200B;</td>
    <td data-value="41"></td>
  </tr>
</table>

A ZeroWidthSpace는 색상을 변경하는 데 사용되며 바닐라 JavaScript를 사용하여 추가 할 수 있습니다.

const hombres = document.querySelectorAll('td[data-value="male"]');
hombres.forEach(hombre => hombre.innerHTML = '&#x0200B;');

비록 <td>의 종료 태그가 생략 될 수있다 하고 있으므로이 비어로 처리되게된다.


0

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

-2

다음과 같이 작은 필터 위젯 만들기 :

    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')
            }
        })
    })

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.