Sélection par programme du texte dans UIWebView

Je pose cette question après 2 jours de recherche. J'ai lu toutes les questions et réponses connexes dans stackoverflow et google (y compris cette question, qui est très similaire mais sans réponse) et ne peut toujours pas trouver une solution. Espérons que quelqu'un ici pourra vous aider.

J'ai un UIWebView avec du texte chargé. Je souhaite sélectionner une partie du texte par programme, comme si l'utilisateur l'avait appuyé longuement.

J'ai essayé d'exécuter ce code javascript en réponse à un clic:

function selectEl(x,y) { document.designMode = "on"; var el = document.elementFromPoint(x, y); var range = document.createRange(); range.selectNodeContents(el); var sel = document.getSelection(); sel.removeAllRanges(); sel.addRange(range); document.designMode = "off"; } 

Je l'ai essayé avec et sans changer designMode à "off" à la fin de la fonction. Je sais que ce code "sélectionne" l'élément correct, car si je réalise cette commande

 document.execCommand("BackColor", false, "#ffffcc"); 

Il met en évidence l'élément sur lequel j'ai cliqué, mais cela ne provoque pas une sélection du texte. Des idées sur la façon d'y parvenir?

Cela semble être un bug dans Mobile Safari. Lorsque je bascule le contentEditable sur true en touchstart et que touchstart configure comme faux en touchend cela fonctionne. Si je supprime ces lignes et je les rafraîchis, ça marche toujours . Si je ferme Mobile Safari, effacez le cache, puis relancez le document avec les lignes supprimées, il cesse de fonctionner à nouveau.

J'ai mis à jour le code ci-dessous avec une version de travail (bien que j'ai supprimé la pression longue pour simplifier).

 <!DOCTYPE html> <html> <head> <script type="text/javascript"> (function() { var node, range, offset, clientX, clientY; document.addEventListener("DOMContentLoaded", function() { document.body.addEventListener("touchstart", function(event) { var selection = window.getSelection(); selection.removeAllRanges(); clientX = event.touches[0].clientX; clientY = event.touches[0].clientY; range = document.caretRangeFromPoint(clientX, clientY); node = range.startContainer; offset = range.startOffset; document.body.contentEditable = "true"; event.preventDefault(); }); document.body.addEventListener("touchmove", function(event) { var selection = window.getSelection(), range = document.caretRangeFromPoint(event.touches[0].clientX, event.touches[0].clientY), newRange = document.createRange(); if(clientY < event.touches[0].clientY) { newRange.setStart(node, offset); newRange.setEnd(range.startContainer, range.startOffset); } else { newRange.setStart(range.startContainer, range.startOffset); newRange.setEnd(node, offset); } selection.removeAllRanges(); selection.addRange(newRange); event.preventDefault(); }); document.body.addEventListener("touchend", function(event) { document.body.contentEditable = "false"; event.preventDefault(); }); }); })(); </script> <body> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam tempus volutpat mauris sed porta. Phasellus euismod malesuada eleifend. Donec mattis, orci quis scelerisque mattis, turpis sem pulvinar nisi, et sagittis nunc nisi sed nulla. Pellentesque pharetra consequat neque, ultrices mattis mauris auctor id. Aenean tincidunt turpis non odio gravida semper. Praesent feugiat, lorem at lacinia tristique, orci eros tincidunt leo, at adipiscing sapien felis at tellus. Phasellus ac est nec nibh posuere euismod vel vitae neque. Vestibulum mollis adipiscing urna ut tristique. Vivamus purus tortor, venenatis id aliquam nec, elementum et lacus. Praesent elementum purus eget sapien ornare laoreet. Vestibulum ac odio enim. </body> </head> </html> 

Juste une pensée: Assurez-vous que vous n'utilisez PAS rien de tel dans votre css:

 * { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; } 

Cela empêche toute sélection de texte.

Je suis tombé sur ce sujet:

 hitElem.style.backgroundColor = "highlight"; hitElem.style.color = "highlighttext"; 

Ou, CE SITE a écrit des scripts HORRIBLES mais cela peut vous aider 🙂 Il fonctionne avec les gammes.