Je ne sais pas dans quelle mesure ou combien de cas vous devez couvrir, mais pour votre exemple, si le texte vient toujours avant les premières balises HTML - pourquoi ne pas simplement diviser le code HTML interne à la première balise et prendre la première:
$('#listItem').html().split('<span')[0];
et si vous en avez besoin plus large peut-être juste
$('#listItem').html().split('<')[0];
et si vous avez besoin du texte entre deux marqueurs, comme après une chose mais avant une autre, vous pouvez faire quelque chose comme (non testé) et utiliser les instructions if pour le rendre suffisamment flexible pour avoir un marqueur de début ou de fin ou les deux, tout en évitant les erreurs de référence nulles :
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...
Je crée généralement des fonctions utilitaires pour des choses utiles comme celle-ci, les rend exemptes d'erreurs, puis je les utilise souvent une fois solides, plutôt que de toujours réécrire ce type de manipulation de chaînes et risquer les références nulles, etc. De cette façon, vous pouvez réutiliser la fonction dans de nombreux projets et ne plus jamais y perdre de temps à déboguer pourquoi une référence de chaîne a une erreur de référence non définie. Ce n'est peut-être pas le code 1 ligne le plus court jamais créé, mais une fois que vous avez la fonction utilitaire, il ne s'agit plus que d'une ligne. Notez que la plupart du code gère simplement les paramètres présents ou non pour éviter les erreurs :)
Par exemple:
/**
* 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)