2011-07-30 5 views
1

Voir cette démo (en fonction de l'événement SelectionChange qui fonctionne dans Chrome seulement à ce moment): http://jsfiddle.net/fyG3H/JavaScript Prévenir window.getSelection() référence circulaire

Sélectionnez un texte lorem ipsum puis concentrer la saisie de texte. Dans le journal de la console, vous verrez qu'il y a un objet DOMSelection. Il a une valeur anchorNode de HTMLBodyElement alors qu'il devrait avoir un de Text.

Je ne savais pas pourquoi ce qui se passait jusqu'à ce que j'ai essayé stringfying l'objet de sélection: http://jsfiddle.net/fyG3H/1/

Cela donne l'erreur suivante:

Uncaught TypeError: Converting circular structure to JSON

Savez-vous comment je peux empêcher cette référence circulaire causé par window.getSelection()?

EDIT

Nouvelle démo qui fonctionne dans d'autres navigateurs, mais aussi donne toujours le mauvais anchorNode: http://jsfiddle.net/fyG3H/5/

Et avec JSON.stringify: http://jsfiddle.net/fyG3H/6/

Firefox semble retourner un vide { } au lieu de lancer une erreur.

+0

votre violon manque bibliothèque de json2. – Mrchief

+1

JSON est un objet natif dans ECMAScript 5. Il n'est pas nécessaire d'inclure une bibliothèque. – DADU

+0

Vraiment? Et nous savons tous combien de navigateurs supportent cela ... n'est-ce pas? – Mrchief

Répondre

2

Vous devez appeler toString() sur getSelection(). J'ai updated your fiddle pour se comporter comme prévu.

var selection; 

$('p').bind('mouseup', function() { 
    selection = window.getSelection().toString(); 
}); 

$('input').bind('focus', function() { 
    this.value = selection; 
    console.log(selection); 
}); 

See demo


EDIT:

La raison pour laquelle vous n'êtes pas obtenir le nœud d'ancrage correct est que l'objet DOMSelection est passé par référence et lorsque vous vous concentrez sur la En entrée, la sélection est effacée, renvoyant ainsi les défauts de sélection correspondant à aucune sélection. Une façon de contourner ce problème est de cloner les propriétés DOMSelection vers un objet et de s'y référer. Vous n'aurez plus les méthodes prototypiques DOMSelection, mais cela dépendra peut-être de ce que vous voulez faire.

var selection, clone; 

$('p').bind('mouseup', function() { 
    selection = window.getSelection(); 
    clone = {}; 
    for (var p in selection) { 
     if (selection.hasOwnProperty(p)) { 
      clone[p] = selection[p]; 
     } 
    } 
}); 

$('input').bind('focus', function() { 
    console.dir(clone); 
}); 

See demo

+0

Merci pour votre réponse. En créant une chaîne à partir de l'objet de sélection, l'objet est perdu et n'est donc pas une solution adéquate. – DADU

+0

Ensuite, stockez 'getSelection()' et appelez 'toString()' à chaque fois que vous voulez le contenu. – mVChr

+0

Le stockage de getSelection() est exactement ce que je fais dans la démo (http://jsfiddle.net/fyG3H/5/). – DADU