특정 텍스트로 DIV를 어떻게 찾을 수 있습니까? 예를 들면 :
<div>
SomeText, text continues.
</div>
다음과 같이 사용하려고합니다.
var text = document.querySelector('div[SomeText*]').innerTEXT;
alert(text);
그러나 물론 작동하지 않습니다. 내가 어떻게 해?
특정 텍스트로 DIV를 어떻게 찾을 수 있습니까? 예를 들면 :
<div>
SomeText, text continues.
</div>
다음과 같이 사용하려고합니다.
var text = document.querySelector('div[SomeText*]').innerTEXT;
alert(text);
그러나 물론 작동하지 않습니다. 내가 어떻게 해?
답변:
OP의 질문은 jQuery가 아닌 일반 JavaScript 에 관한 것 입니다. 많은 답변이 있고 @Pawan Nogariya 답변을 좋아하지만 이 대안을 확인하십시오.
JavaScript에서 XPATH 를 사용할 수 있습니다 . MDN 기사에 대한 자세한 정보는 여기 .
이 document.evaluate()
메서드는 XPATH 쿼리 / 표현식을 평가합니다. 따라서 거기에 XPATH 표현식을 전달하고 HTML 문서로 이동하여 원하는 요소를 찾을 수 있습니다.
XPATH에서 다음과 같은 텍스트 노드로 요소를 선택할 수 있습니다. whch는 다음 텍스트 노드가있는 요소를 가져옵니다 div
.
//div[text()="Hello World"]
일부 텍스트를 포함하는 요소를 얻으려면 다음을 사용하십시오.
//div[contains(., 'Hello')]
contains()
XPATH 의 메소드는 노드를 첫 번째 매개 변수로 사용하고 텍스트를 두 번째 매개 변수로 검색합니다.
여기 에서이 plunk를 확인하십시오. 이것은 JavaScript에서 XPATH를 사용한 예제입니다.
다음은 코드 스 니펫입니다.
var headings = document.evaluate("//h1[contains(., 'Hello')]", document, null, XPathResult.ANY_TYPE, null );
var thisHeading = headings.iterateNext();
console.log(thisHeading); // Prints the html element in console
console.log(thisHeading.textContent); // prints the text content in console
thisHeading.innerHTML += "<br />Modified contents";
보시다시피 HTML 요소를 가져 와서 원하는대로 수정할 수 있습니다.
alert(thisHeading.textContent.replace(/.*You have login (.*) times.*/,'$1')) ;
.evaluate()
사용합니다. 제가 틀렸다면 누군가 정정 해주십시오). 첫째로, 정규식과 일치하는 것을 검색 할 수 없습니다. 둘째, .textContent
속성은 요소의 텍스트 노드를 반환합니다. 이 텍스트에서 값을 가져 오려면 정규식과 일치하는 일종의 함수를 만들고 그룹에서 일치하는 값을 반환하여 명시 적으로 처리해야합니다.이를 위해 별도의 스레드에서 새 질문을 만드십시오.
이 매우 간단한 솔루션을 사용할 수 있습니다.
Array.from(document.querySelectorAll('div'))
.find(el => el.textContent === 'SomeText, text continues.');
은 Array.from
(확산 연산자 또는 슬라이스와 같은 이렇게 여러 방법이있다) 배열로 노드 목록을 변환 할
결과는 이제 배열이되어 Array.find
메소드 를 사용할 수있게되며 , 그런 다음 모든 술어를 넣을 수 있습니다. 정규식 또는 원하는대로 textContent를 확인할 수도 있습니다.
참고 Array.from
및 Array.find
ES2015 기능은 다음과 같습니다. 트랜스 파일러없이 IE10과 같은 이전 브라우저와 호환됩니다.
Array.prototype.slice.call(document.querySelectorAll('div'))
.filter(function (el) {
return el.textContent === 'SomeText, text continues.'
})[0];
find
와 함께 filter
.
당신이 자바 스크립트에서 요청했기 때문에 다음과 같은 것을 가질 수 있습니다.
function contains(selector, text) {
var elements = document.querySelectorAll(selector);
return Array.prototype.filter.call(elements, function(element){
return RegExp(text).test(element.textContent);
});
}
그리고 이렇게 부르세요
contains('div', 'sometext'); // find "div" that contain "sometext"
contains('div', /^sometext/); // find "div" that start with "sometext"
contains('div', /sometext$/i); // find "div" that end with "sometext", case-insensitive
[object HTMLDivElement],[object HTMLDivElement]
foundDivs[0].innerText
간단합니다
이 솔루션은 다음을 수행합니다.
ES6 확산 연산자를 사용하여 모든 div
의 NodeList를 배열 로 변환합니다 .
(가) 경우 출력을 제공 div
포함 쿼리 문자열을 정확히 아닌 경우, 동일 (다른 답변의 일부 발생하는) 쿼리 문자열을. 예 : 'SomeText'뿐만 아니라 'SomeText, text continue'에 대한 출력도 제공해야합니다.
div
쿼리 문자열뿐만 아니라 전체 내용을 출력합니다 . 예를 들어 'SomeText, text continue'의 경우 'SomeText'뿐만 아니라 전체 문자열을 출력해야합니다.
여러 개의 div
에 단일 div
.
[...document.querySelectorAll('div')] // get all the divs in an array
.map(div => div.innerHTML) // get their contents
.filter(txt => txt.includes('SomeText')) // keep only those containing the query
.forEach(txt => console.log(txt)); // output the entire contents of those
<div>SomeText, text continues.</div>
<div>Not in this div.</div>
<div>Here is more SomeText.</div>
innerHTML
최상위 <div>
s의 크기를 생각하십시오 . div
먼저 자식을 포함하는를 필터링해야합니다 . 또한 의심 document.getElementsByTagName('div')
이 더 빠를 수 있지만 확실하게 벤치마킹 할 것입니다.
쿼리하는 div의 상위 요소가 있는지 확인하는 것이 가장 좋습니다. 그렇다면 부모 요소를 가져 와서 element.querySelectorAll("div")
. 일단 속성 nodeList
에 필터를 적용하십시오 innerText
. 우리가 쿼리되는 사업부의 부모 요소가 있다고 가정 id
의 container
. 일반적으로 ID에서 직접 컨테이너에 액세스 할 수 있지만 적절한 방법으로합시다.
var conty = document.getElementById("container"),
divs = conty.querySelectorAll("div"),
myDiv = [...divs].filter(e => e.innerText == "SomeText");
그게 다입니다.
jquery 또는 이와 비슷한 것을 사용하지 않으려면 다음을 시도해 볼 수 있습니다.
function findByText(rootElement, text){
var filter = {
acceptNode: function(node){
// look for nodes that are text_nodes and include the following string.
if(node.nodeType === document.TEXT_NODE && node.nodeValue.includes(text)){
return NodeFilter.FILTER_ACCEPT;
}
return NodeFilter.FILTER_REJECT;
}
}
var nodes = [];
var walker = document.createTreeWalker(rootElement, NodeFilter.SHOW_TEXT, filter, false);
while(walker.nextNode()){
//give me the element containing the node
nodes.push(walker.currentNode.parentNode);
}
return nodes;
}
//call it like
var nodes = findByText(document.body,'SomeText');
//then do what you will with nodes[];
for(var i = 0; i < nodes.length; i++){
//do something with nodes[i]
}
텍스트를 포함하는 배열에 노드가 있으면 작업을 수행 할 수 있습니다. 각각 경고하거나 콘솔에 인쇄하십시오. 한 가지주의 할 점은 이것이 반드시 div 자체를 가져 오지 않을 수도 있다는 것입니다. 그러면 찾고있는 텍스트가있는 텍스트 노드의 부모를 가져옵니다.
데이터 속성의 텍스트 길이에는 제한이 없으므로 데이터 속성을 사용하십시오! 그런 다음 일반 CSS 선택기를 사용하여 OP가 원하는 요소를 선택할 수 있습니다.
for (const element of document.querySelectorAll("*")) {
element.dataset.myInnerText = element.innerText;
}
document.querySelector("*[data-my-inner-text='Different text.']").style.color="blue";
<div>SomeText, text continues.</div>
<div>Different text.</div>
이상적으로는 문서로드시 데이터 속성 설정 부분을 수행하고 성능을 위해 querySelectorAll 선택기의 범위를 좁 힙니다.
Google은 특정 텍스트가있는 노드를 찾아야하는 사람들을위한 최고의 결과로 이것을 가지고 있습니다. 업데이트를 통해 이제 노드 목록을 배열로 변환하지 않고도 최신 브라우저에서 반복 할 수 있습니다.
솔루션은 forEach를 그렇게 사용할 수 있습니다.
var elList = document.querySelectorAll(".some .selector");
elList.forEach(function(el) {
if (el.innerHTML.indexOf("needle") !== -1) {
// Do what you like with el
// The needle is case sensitive
}
});
이것은 일반 선택기가 하나의 노드 만 선택할 수 없을 때 노드 목록 내에서 텍스트를 찾고 / 바꾸는 데 도움이되었으므로 바늘을 확인하기 위해 각 노드를 하나씩 필터링해야했습니다.
XPath 및 document.evaluate ()를 사용하고. contains () 인수에 대해 그렇지 않으면 전체 HTML 또는 가장 바깥 쪽 div 요소가 일치합니다.
var headings = document.evaluate("//h1[contains(text(), 'Hello')]", document, null, XPathResult.ANY_TYPE, null );
또는 선행 및 후행 공백 무시
var headings = document.evaluate("//h1[contains(normalize-space(text()), 'Hello')]", document, null, XPathResult.ANY_TYPE, null );
또는 모든 태그 유형 (div, h1, p 등)과 일치
var headings = document.evaluate("//*[contains(text(), 'Hello')]", document, null, XPathResult.ANY_TYPE, null );
그런 다음 반복
let thisHeading;
while(thisHeading = headings.iterateNext()){
// thisHeading contains matched node
}
thisheading.setAttribute('class', "esubject")
다음은 XPath 접근 방식이지만 최소한의 XPath 전문 용어를 사용합니다.
요소 속성 값을 기반으로 한 일반 선택 (비교 용) :
// for matching <element class="foo bar baz">...</element> by 'bar'
var things = document.querySelectorAll('[class*="bar"]');
for (var i = 0; i < things.length; i++) {
things[i].style.outline = '1px solid red';
}
요소 내의 텍스트를 기반으로하는 XPath 선택.
// for matching <element>foo bar baz</element> by 'bar'
var things = document.evaluate('//*[contains(text(),"bar")]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
for (var i = 0; i < things.snapshotLength; i++) {
things.snapshotItem(i).style.outline = '1px solid red';
}
그리고 여기에는 텍스트가 더 휘발성이기 때문에 대소 문자를 구분하지 않습니다.
// for matching <element>foo bar baz</element> by 'bar' case-insensitively
var things = document.evaluate('//*[contains(translate(text(),"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz"),"bar")]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
for (var i = 0; i < things.snapshotLength; i++) {
things.snapshotItem(i).style.outline = '1px solid red';
}
비슷한 문제가있었습니다.
arg의 텍스트를 포함하는 모든 요소를 반환하는 함수입니다.
이것은 나를 위해 작동합니다.
function getElementsByText(document, str, tag = '*') {
return [...document.querySelectorAll(tag)]
.filter(
el => (el.text && el.text.includes(str))
|| (el.children.length === 0 && el.outerText && el.outerText.includes(str)))
}
여기에는 이미 많은 훌륭한 솔루션이 있습니다. 그러나보다 능률적 인 솔루션을 제공하고 querySelector 동작 및 구문에 대한 아이디어를 유지하기 위해 Object 를 확장하는 솔루션을 선택했습니다. 몇 가지 프로토 타입 함수로 . 이 두 함수는 모두 텍스트 일치를 위해 정규식을 사용하지만 문자열은 느슨한 검색 매개 변수로 제공 될 수 있습니다.
다음 기능을 구현하기 만하면됩니다.
// find all elements with inner text matching a given regular expression
// args:
// selector: string query selector to use for identifying elements on which we
// should check innerText
// regex: A regular expression for matching innerText; if a string is provided,
// a case-insensitive search is performed for any element containing the string.
Object.prototype.queryInnerTextAll = function(selector, regex) {
if (typeof(regex) === 'string') regex = new RegExp(regex, 'i');
const elements = [...this.querySelectorAll(selector)];
const rtn = elements.filter((e)=>{
return e.innerText.match(regex);
});
return rtn.length === 0 ? null : rtn
}
// find the first element with inner text matching a given regular expression
// args:
// selector: string query selector to use for identifying elements on which we
// should check innerText
// regex: A regular expression for matching innerText; if a string is provided,
// a case-insensitive search is performed for any element containing the string.
Object.prototype.queryInnerText = function(selector, text){
return this.queryInnerTextAll(selector, text)[0];
}
이러한 함수를 구현하면 이제 다음과 같이 호출 할 수 있습니다.
document.queryInnerTextAll('div.link', 'go');
document.queryInnerText('div.link', 'go');
document.queryInnerTextAll('a', /^Next$/);
document.queryInnerText('a', /next/i);
e = document.querySelector('#page');
e.queryInnerText('button', /Continue/);