Não tenho certeza de quão flexível ou quantos casos você precisa cobrir, mas, por exemplo, se o texto sempre vem antes das primeiras tags HTML - por que não dividir o html interno na primeira tag e pegar o primeiro:
$('#listItem').html().split('<span')[0];
e se você precisar mais amplo talvez apenas
$('#listItem').html().split('<')[0];
e se você precisar do texto entre dois marcadores, como após uma coisa, mas antes de outra, poderá fazer algo como (não testado) e usar as instruções if para torná-la flexível o suficiente para ter um marcador de início ou fim ou ambos, evitando erros nulos de ref :
var startMarker = '';// put any starting marker here
var endMarker = '<';// put the end marker here
var myText = String( $('#listItem').html() );
// if the start marker is found, take the string after it
myText = myText.split(startMarker)[1];
// if the end marker is found, take the string before it
myText = myText.split(endMarker)[0];
console.log(myText); // output text between the first occurrence of the markers, assuming both markers exist. If they don't this will throw an error, so some if statements to check params is probably in order...
Geralmente, faço funções utilitárias para coisas úteis como essa, as deixo livres de erros e depois confio nelas frequentemente uma vez sólidas, em vez de sempre reescrever esse tipo de manipulação de string e arriscar referências nulas, etc. Dessa forma, você pode reutilizar a função em muitos projetos e nunca mais perca tempo depurando por que uma referência de string tem um erro de referência indefinido. Pode não ser o código de 1 linha mais curto de todos os tempos, mas depois que você tiver a função de utilitário, será uma linha a partir de então. Observe que a maior parte do código é apenas manipular parâmetros que estão lá ou não para evitar erros :)
Por exemplo:
/**
* Get the text between two string markers.
**/
function textBetween(__string,__startMark,__endMark){
var hasText = typeof __string !== 'undefined' && __string.length > 0;
if(!hasText) return __string;
var myText = String( __string );
var hasStartMarker = typeof __startMark !== 'undefined' && __startMark.length > 0 && __string.indexOf(__startMark)>=0;
var hasEndMarker = typeof __endMark !== 'undefined' && __endMark.length > 0 && __string.indexOf(__endMark) > 0;
if( hasStartMarker ) myText = myText.split(__startMark)[1];
if( hasEndMarker ) myText = myText.split(__endMark)[0];
return myText;
}
// now with 1 line from now on, and no jquery needed really, but to use your example:
var textWithNoHTML = textBetween( $('#listItem').html(), '', '<'); // should return text before first child HTML tag if the text is on page (use document ready etc)