<div class="title">
I am text node
<a class="edit">Edit</a>
</div>
Desejo obter o "I am text node", não desejo remover a tag "edit" e preciso de uma solução para vários navegadores.
javascript
jquery
Val
fonte
fonte
Respostas:
Isso obtém o
contents
do elemento selecionado e aplica uma função de filtro a ele. A função de filtro retorna apenas nós de texto (ou seja, aqueles nós comnodeType == Node.TEXT_NODE
).fonte
text()
porque afilter
função retorna os próprios nós, não o conteúdo dos nós.jQuery("*").each(function() { console.log(this.nodeType); })
e obtive 1 para todos os tipos de nó.Você pode obter o nodeValue do primeiro childNode usando
http://jsfiddle.net/TU4FB/
fonte
null
um valor de retorno.Se você quiser obter o valor do primeiro nó de texto no elemento, este código funcionará:
Você pode ver isso em ação aqui: http://jsfiddle.net/ZkjZJ/
fonte
curNode.nodeType == 3
vez denodeName
.curNode.nodeType == Node.TEXT_NODE
(a comparação numérica é mais rápida, mas curNode.nodeType == 3 não é legível - qual nó tem o número 3?)curNode.NodeType === Node.TEXT_NODE
. Essa comparação está ocorrendo dentro de um loop de possíveis iterações desconhecidas. Comparar dois números pequenos é melhor do que comparar strings de vários comprimentos (considerações de tempo e espaço). A pergunta correta a fazer nessa situação é "que tipo / tipo de nó eu tenho?", E não "que nome eu tenho?" developer.mozilla.org/en-US/docs/Web/API/Node/nodeTypechildNodes
, saiba que um nó de elemento pode ter mais de um nó de texto. Em uma solução genérica, pode ser necessário especificar qual instância de um nó de texto dentro de um nó de elemento que você deseja atingir (o primeiro, segundo, terceiro, etc ...).Outra solução JS nativa que pode ser útil para elementos "complexos" ou profundamente aninhados é usar NodeIterator . Coloque
NodeFilter.SHOW_TEXT
como o segundo argumento ("whatToShow") e itere apenas sobre os filhos do nó de texto do elemento.Você também pode usar
TreeWalker
. A diferença entre os dois é queNodeIterator
é um iterador linear simples, enquantoTreeWalker
permite que você navegue por meio de irmãos e ancestrais também.fonte
JavaScript puro: minimalista
Em primeiro lugar, sempre tenha isso em mente ao procurar por texto no DOM.
MDN - espaço em branco no DOM
Este problema fará com que você preste atenção na estrutura do seu XML / HTML.
Neste exemplo de JavaScript puro, considero a possibilidade de vários nós de texto que podem ser intercalados com outros tipos de nós . No entanto, inicialmente, não julgo os espaços em branco, deixando essa tarefa de filtragem para outro código.
Nesta versão, passo um
NodeList
do código de chamada / cliente.Obviamente, testando
node.hasChildNodes()
primeiro, não haveria necessidade de usar umfor
loop de pré-teste .JavaScript puro: robusto
Aqui, a função
getTextById()
usa duas funções auxiliares:getStringsFromChildren()
efilterWhitespaceLines()
.getStringsFromChildren ()
filterWhitespaceLines ()
getTextById ()
Em seguida, o valor de retorno (Array ou null) é enviado ao código do cliente onde deve ser tratado. Felizmente, a matriz deve ter elementos de string de texto real, não linhas de espaço em branco.
Strings vazias (
""
) não são retornadas porque você precisa de um nó de texto para indicar corretamente a presença de texto válido. Returning (""
) pode dar a falsa impressão de que existe um nó de texto, levando alguém a supor que pode alterar o texto alterando o valor de.nodeValue
. Isso é falso, porque um nó de texto não existe no caso de uma string vazia.Exemplo 1 :
Exemplo 2 :
O problema surge quando você deseja tornar seu HTML fácil de ler, espaçando-o. Agora, embora não haja texto válido legível por humanos, ainda existem nós de texto com
"\n"
caracteres newline ( ) em suas.nodeValue
propriedades.Os humanos veem os exemplos um e dois como funcionalmente equivalentes - elementos vazios esperando para serem preenchidos. O DOM é diferente do raciocínio humano. É por isso que a
getStringsFromChildren()
função deve determinar se existem nós de texto e reunir os.nodeValue
valores em uma matriz.No exemplo dois, dois nós de texto existem e
getStringFromChildren()
retornarão o.nodeValue
de ambos ("\n"
). No entanto,filterWhitespaceLines()
usa uma expressão regular para filtrar linhas de caracteres de espaço em branco puros.Retornar em
null
vez de"\n"
caracteres newline ( ) é uma forma de mentir para o cliente / código de chamada? Em termos humanos, não. Em termos de DOM, sim. No entanto, o problema aqui é obter texto, não editá-lo. Não há texto humano para retornar ao código de chamada.Nunca se sabe quantos caracteres de nova linha podem aparecer no HTML de alguém. A criação de um contador que procura o caractere de nova linha "segundo" não é confiável. Pode não existir.
Claro, mais abaixo na linha, a questão de editar texto em um
<p></p>
elemento vazio com espaço em branco extra (exemplo 2) pode significar destruir (talvez, pular) todos, exceto um nó de texto entre as tags de um parágrafo para garantir que o elemento contenha precisamente o que é deveria exibir.Independentemente disso, exceto nos casos em que você está fazendo algo extraordinário, você precisará encontrar uma maneira de determinar qual
.nodeValue
propriedade do nó de texto possui o texto legível verdadeiro que deseja editar.filterWhitespaceLines
nos leva a meio caminho.Neste ponto, você pode ter uma saída semelhante a esta:
Não há garantia de que essas duas strings sejam adjacentes uma à outra no DOM, portanto, juntá-las com
.join()
pode formar uma composição não natural. Em vez disso, no código que chamagetTextById()
, você precisa escolher com qual string deseja trabalhar.Teste a saída.
Pode-se adicionar
.trim()
dentro degetStringsFromChildren()
para se livrar dos espaços em branco à esquerda e à direita (ou para transformar um monte de espaços em uma string de comprimento zero (""
), mas como você pode saber a priori o que cada aplicativo pode precisar que aconteça com o texto (string) uma vez que for encontrado? Você não, então deixe isso para uma implementação específica e deixegetStringsFromChildren()
ser genérico.Pode haver momentos em que esse nível de especificidade (o
target
e tal) não seja necessário. Isso é ótimo. Use uma solução simples nesses casos. No entanto, um algoritmo generalizado permite acomodar situações simples e complexas.fonte
Versão ES6 que retorna o primeiro #text node content
fonte
.from()
para fazer uma instância de array copiado superficialmente. (2) O uso de.find()
para fazer comparações de strings usando.nodeName
. Usarnode.NodeType === Node.TEXT_NODE
seria melhor. (3) Retornar uma string vazia quando nenhum valor,,null
é mais verdadeiro se nenhum nó de texto for encontrado. Se nenhum nó de texto for encontrado, pode ser necessário criar um! Se você retornar uma string vazia,,""
poderá dar a falsa impressão de que existe um nó de texto e pode ser manipulado normalmente. Em essência, devolver uma string vazia é uma mentira inocente e é melhor evitar.[...node.childNodes]
para converter HTMLCollection em Arrays.text() - for jquery
fonte
a
elemento também: jsfiddle.net/ekHJH.
no início do seu seletor, o que significa que você realmente obtém o texto dotitle
elemento, não os elementos comclass="title"
.innerText
é uma antiga convenção do IE adotada recentemente. Em termos de script DOM padrão,node.nodeValue
é como se pega o texto de um nó de texto.Isso irá ignorar o espaço em branco também, portanto, você nunca obteve o código textNodes em branco usando o Javascript principal.
Verifique em jsfiddle: - http://jsfiddle.net/webx/ZhLep/
fonte
curNode.nodeType === Node.TEXT_NODE
seria melhor. Usar comparação de string e uma expressão regular em um loop é uma solução de baixo desempenho, especialmente à medida que a magnitude dooDiv.childNodes.length
aumento. Este algoritmo resolve a questão específica do OP, mas, potencialmente, a um custo de desempenho terrível. Se o arranjo, ou número, de nós de texto mudar, então esta solução não pode ser garantida para retornar uma saída precisa. Em outras palavras, você não pode direcionar o nó de texto exato que deseja. Você está à mercê da estrutura HTML e da organização do texto.Você também pode usar o
text()
teste de nó do XPath para obter apenas os nós de texto. Por exemplofonte
Esta é minha solução no ES6 para criar uma string contendo o texto concatenado de todos os childnodes (recursivo) . Observe que também é possível visitar o shdowroot de childnodes.
Esta solução foi inspirada na solução de https://stackoverflow.com/a/41051238./1300775 .
fonte