La solution suivante ne fonctionne pas pour IE, vous devrez appliquer les objets TextRange etc. pour cela. Comme cette solution utilise des sélections, elle ne devrait pas perturber le code HTML dans les cas normaux, par exemple :
<div>abcd<span>efg</span>hij</div>
Con highlight(3,6);
des sorties :
<div>abc<em>d<span>ef</span></em><span>g</span>hij</div>
Notez que le premier caractère à l'extérieur de l'intervalle est enveloppé dans une balise em
et ensuite le reste dans le cadre de la span
dans une nouvelle. Alors que s'il l'ouvrait simplement au caractère 3 et le terminait au caractère 6, il donnerait un balisage invalide comme :
<div>abc<em>d<span>ef</em>g</span>hij</div>
Le code :
~~var r = document.createRange();
var s = window.getSelection()
r.selectNode($('div')[0]);
s.removeAllRanges();
s.addRange(r);
// not quite sure why firefox has problems with this
if ($.browser.webkit) {
s.modify("move", "backward", "documentboundary");
}
function highlight(start,end){
for(var st=0;st<start;st++){
s.modify("move", "forward", "character");
}
for(var st=0;st<(end-start);st++){
s.modify("extend", "forward", "character");
}
}
highlight(2,6);
var ra = s.getRangeAt(0);
var newNode = document.createElement("em");
newNode.appendChild(ra.extractContents());
ra.insertNode(newNode);
Exemple : http://jsfiddle.net/niklasvh/4NDb9/
éditer Il semblerait qu'au moins mon FF4 ait eu des problèmes avec
s.modify("move", "backward", "documentboundary");
mais en même temps, cela semble fonctionner sans, donc je l'ai changé en
if ($.browser.webkit) {
s.modify("move", "backward", "documentboundary");
}~~
éditer comme l'a souligné Tim, modifier n'est disponible qu'à partir de FF4, j'ai donc adopté une approche différente pour obtenir la sélection, qui n'a pas besoin de la méthode modifier, dans l'espoir de la rendre un peu plus compatible avec les navigateurs (IE a toujours besoin de sa propre solution).
Le code :
var r = document.createRange();
var s = window.getSelection()
var pos = 0;
function dig(el){
$(el).contents().each(function(i,e){
if (e.nodeType==1){
// not a textnode
dig(e);
}else{
if (pos<start){
if (pos+e.length>=start){
range.setStart(e, start-pos);
}
}
if (pos<end){
if (pos+e.length>=end){
range.setEnd(e, end-pos);
}
}
pos = pos+e.length;
}
});
}
var start,end, range;
function highlight(element,st,en){
range = document.createRange();
start = st;
end = en;
dig(element);
s.addRange(range);
}
highlight($('div'),3,6);
var ra = s.getRangeAt(0);
var newNode = document.createElement("em");
newNode.appendChild(ra.extractContents());
ra.insertNode(newNode);
exemple : http://jsfiddle.net/niklasvh/4NDb9/
0 votes
Pouvez-vous supprimer les balises dans une chaîne temporaire, puis effectuer une sous-chaîne à partir de cette chaîne ?
0 votes
Vous ne pouvez pas ignorer les balises, sinon vous obtiendrez un code html non valide :
ab<x>cd<em>ef</x>f</em>
. Vous devriez faire quelque chose commeab<x>cd</x><em><x>ef</x>g</em>
1 votes
Bien sûr, je ne peux pas ignorer les balises, mais ce serait bien si le navigateur pouvait résoudre ces problèmes pour moi d'une manière ou d'une autre.