J'ai observé un comportement indésirable dans Chrome qui se produit lorsque l'on rejoint deux <p>
en supprimant la séparation entre eux. Bien que les balises <p>
soient jointes correctement, Chrome enveloppe le contenu de la balise <p>
plus à droite avec un <span>
.
Edit : cela se produit pour tous les éléments de blocs, pas seulement p
tags.
Exemple :
Par exemple, lorsque la séparation </p><p>
est supprimée du bloc suivant:
<div contenteditable="true"><p>p one.</p><p>p two.</p></div>
Il devient:
<div contenteditable="true"><p>p one.<span style="font-size: 16px; line-height: 1.44;">p two.</span></p>
Exemple dans un violon: le contenu de l'emballage Chrome est joint <p>
avec un <span>
.
Question :
Existe-t-il un moyen simple d'empêcher Chrome de faire cela? Il en résulte un marquage horrible dont j'aimerais beaucoup me débarrasser.
Il y a un moyen, mais vous devez définir activement quelques styles. L'idée est de dire à Chrome que les styles sont déjà pris en charge, donc il n'a pas besoin d'ajouter SPAN pour répondre aux exigences de styles. En principe, vous devez ajouter les styles ajoutés au chrome à une classe étendue sous votre div contentative (voir l'exemple ci-dessous).
Violon édité
Pour vous, exemple:
.edit p, span
class dans le style Cela devient:
.edit { border: 1px solid gray; padding: 10px; } .edit p, span { line-height: 1.44; font-size: 16px; }
Et le DIV:
<div contenteditable="true" class="edit">...</div>
Notez que vous n'avez normalement pas besoin de la font-size: 16px;
la font-size: 16px;
. J'avais besoin d'ajouter celui-ci parce que le violon définit une certaine taille de police en contentement. Sur une page indépendante, je n'en ai pas besoin.
Vous devez appliquer ce «patch» de Chrome à tous les éléments où cela se produit (alors, si vous avez besoin de UL, OL …, ajoutez ce qui est nécessaire à la suite de ma logique d'exemple ci-dessus)
Je sais que ce n'est pas vraiment une réponse pour le résoudre, mais un indice de la façon dont il pourrait être corrigé (mais il est long d'être un commentaire à Petah question de savoir comment je le résoudrais)
En général, vous vérifiez que de tels bogues pourraient se produire. Pour le cas de la création de l' span
vous keydown
tous keydown
événements de keydown
et de keypress
et vérifiez si la clé est la touche de recul ou de suppression ou pour chaque touche qui insère des caractères s'il s'agit d'une sélection réelle.
Si tel est le cas, vous devez vérifier la sélection actuelle (soit la position de la marque d'insertion, soit la sélection réelle), alors vous savez quel est l'élément de texte ou le noeud suivant. Alors vous devez vérifier la suivante dans la suivante, keyup
keypress
et la keyup
si une span
créée directement après votre marque d'insertion. Selon le bug du navigateur, vous avez besoin d'une vérification supplémentaire. S'il y en a une, créez un nouveau contenu. Mutation
événements de Mutation
supplémentaires et les attributs d' assistance pourraient être utilisés.
Mais je dois dire que j'ai renoncé à faire cela moi-même et a changé pour ckeditor 4. la plupart des fonctionnalités dont je n'ai pas besoin et c'est une très grande bibliothèque. Mais à cause du grand nombre de ces bugs, je n'ai pas vu une autre solution pour moi.
EDIT Voici une mise à jour du js violon qui montre l'idée avec un événement Mutable: http://jsfiddle.net/THPmr/6/
Mais ce n'est pas à l'épreuve des balles, il suffit de montrer comment cela pourrait être obtenu (testé uniquement dans chrome 27.0.1422.0, et probablement ne fonctionnerait pas si plus d'un élément de texte est contenu dans la seconde p
)
Le CSS influence la façon dont le balisage est effectué à l'intérieur contentable:
Div, pré {border: 1px solid grey; Rembourrage: 10px; Hauteur de ligne: 1,44; }
Supprimez la ligne ligne-hauteur et le problème ne se produit plus.
Il existe en général plusieurs bugs avec contentement liés au style par défaut: comment éviter le contenu WebKitEditable copier-coller en résultant CSS indésirable?
EDIT JsFiddle influence indirectement cela (la tinkerbin se comporte différemment) en raison de son 'CSS (normalize.css). Essaye ça:
<p>
font-size
déclarations de font-size
dans la pile CSS – y compris votre hauteur de ligne Solution 1 : utilisez les classes et les identifiants.
Ne déclarez pas la taille de la police pour p
ou div
mais pour p.main-content
, ou plus simplement, .main-content
. Si la taille de police de vos éléments à l'intérieur de contentement provient du CSS par défaut interne du navigateur, Chrome n'ajoute pas de marquage supplémentaire / style inline.
Solution 2 : Utiliser un Sanitizer.
J'allais personnellement avec le n ° 1 car il n'est jamais recommandé de spécifier les tailles de police et les erreurs de frappe dans des étiquettes si génériques.
La meilleure façon de trouver jusqu'à présent est d'écouter DOMNodeInserted et de vérifier le tagName. Si c'est une portée, vous pouvez supprimer la balise et laisser le contenu. Cela maintient également le curseur à l'endroit correct.
function unwrap(el, target) { if ( !target ) { target = el.parentNode; } while (el.firstChild) { target.appendChild(el.firstChild); } el.parentNode.removeChild(el); } var AutoFix = true; document.getElementById('editable') .addEventListener('DOMNodeInserted', function(ev) { if ( !AutoFix ) { return; } if ( ev.target.tagName=='SPAN' ) { unwrap(ev.target); } });
J'ai ajouté un «AutoFix» booléen afin que vous puissiez désactiver les changements de dom automatiques lorsque vous devez insérer un intervalle, car cet événement déclenche un changement de dom. Par exemple, si vous avez une barre d'outils qui permet à l'utilisateur d'insérer quelque chose comme <span class = "highlight"> … </ span>.
Le code n'a pas d'effets secondaires dans IE ou FireFox pour autant que je voie.
Voici ma façon de supprimer les limites supplémentaires
document.querySelector('[contenteditable=true]') .addEventListener('DOMNodeInserted', function(event) { if (event.target.tagName == 'SPAN') { event.target.outerHTML = event.target.innerHTML; } });
Cela m'a irrité aussi, mais j'ai trouvé une solution qui fonctionne bien pour l'instant.
$('#container span').filter(function() { $(this).removeAttr("style"); return $(this).html().trim().length == 0; }).remove();
Je retire simplement la balise de style de l'élément de portée et supprimez-le complètement s'il est vide. Vous pourriez probablement filtrer en fonction du style de l'attribut, mais comme je fais déjà une boucle pour vérifier les vides, je pensais qu'il était préférable de faire les deux en même temps.
Il crée un scintillement pour une microseconde lorsque chrome tente d'abord d'insérer le style hérité pour la portée, mais vous ne le voyez qu'une fois immédiatement après la suppression.
Ce n'est pas parfait, mais c'est rapide et concis.
Trouvé ce lien à partir d'un commentaire publié sur le blog de quelqu'un:
(Correction d'un bug où les dernières versions de WebKit produiraient l'élément span …) https://github.com/tinymce/tinymce/commit/8e6422aefa9b6cc526a218559eaf036f1d2868cf
Consultez les réponses ici: https://stackoverflow.com/a/24494280/2615633 Pour corriger le problème, vous pouvez simplement utiliser ce plugin: jquery.chromeinsertfix