J'ai essayé de demander ceci auparavant, sans aucune chance d'expliquer/prouver un exemple de travail où le bogue se produit. Voici donc un autre essai:
J'essaie de reproduire un effet d'espace réservé sur une DIV modifiable. Le concept de base est simple:
<div contenteditable><em>Edit me</em></div>
<script>
$('div').focus(function() {
$(this).empty();
});
</script>
Cela peut parfois fonctionner, mais si l'espace réservé contient du HTML, ou si un autre traitement est effectué, le signe d'insertion de texte du DIV modifiable est supprimé, et l'utilisateur doit re-cliquer sur le DIV modifiable pour pouvoir commencer à taper (même s'il est toujours au point):
Exemple: http://jsfiddle.net/hHLXr/6/
Je ne peux pas utiliser de déclencheur de focus dans le gestionnaire, car cela créera une boucle d'événements. J'ai donc besoin d'un moyen de réinitialiser le curseur d'insertion dans le DIV modifiable, ou d'une autre manière de recentrer.
Vous devrez peut-être mettre à jour manuellement la sélection. Dans IE, l'événement focus est trop tard, donc je suggère d'utiliser à la place l'événement activate
. Voici du code qui fait le travail dans tous les principaux navigateurs, y compris IE <= 8 (ce qui ne sera pas le cas avec une alternative CSS uniquement):
Démo en direct: http://jsfiddle.net/hHLXr/12/
Code:
$('div').on('activate', function() {
$(this).empty();
var range, sel;
if ( (sel = document.selection) && document.body.createTextRange) {
range = document.body.createTextRange();
range.moveToElementText(this);
range.select();
}
});
$('div').focus(function() {
if (this.hasChildNodes() && document.createRange && window.getSelection) {
$(this).empty();
var range = document.createRange();
range.selectNodeContents(this);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
});
Voici une solution CSS uniquement augmentant certaines des autres réponses: -
<div contentEditable=true data-ph="My Placeholder String"></div>
<style>
[contentEditable=true]:empty:not(:focus)::before{
content:attr(data-ph)
}
</style>
EDIT: Voici mon extrait sur codepen -> http://codepen.io/mrmoje/pen/lkLez
EDIT2: Soyez avisé, cette méthode ne fonctionne pas à 100% pour les applications multi-lignes en raison de <br>
éléments présents dans le div après avoir effectué un select-all-cut
ou select-all-delete
sur toutes les lignes. Crédits: - @vsync
Le retour arrière semble fonctionner correctement (au moins sur webkit/blink)
Je viens de publié un plugin pour cela .
Il utilise une combinaison de CSS3 et JavaScript pour afficher l'espace réservé sans ajouter au contenu du div
:
HTML:
<div contenteditable='true' data-placeholder='Enter some text'></div>
CSS:
div[data-placeholder]:not(:focus):not([data-div-placeholder-content]):before {
content: attr(data-placeholder);
float: left;
margin-left: 5px;
color: gray;
}
JS:
(function ($) {
$('div[data-placeholder]').on('keydown keypress input', function() {
if (this.textContent) {
this.dataset.divPlaceholderContent = 'true';
}
else {
delete(this.dataset.divPlaceholderContent);
}
});
})(jQuery);
Et c'est tout.
utilisez simplement les pseudo-classes css.
span.spanclass:empty:before {content:"placeholder";}
J'ai trouvé que la meilleure façon de le faire est d'utiliser l'attribut placeholder
comme d'habitude et d'ajouter quelques lignes de CSS.
[~ # ~] html [~ # ~]
<div contenteditable placeholder="I am a placeholder"></div>
[~ # ~] css [~ # ~]
[contenteditable][placeholder]:empty:before {
content: attr(placeholder);
color: #bababa;
}
Remarque: le CSS :empty
selector ne fonctionne que s'il n'y a littéralement rien entre les balises d'ouverture et de fermeture. Cela inclut les nouvelles lignes, les tabulations, les espaces vides, etc.
Tout ce dont vous avez besoin est cette petite solution
[contenteditable=true]:empty:before{
content: attr(placeholder);
display: block; /* For Firefox */
}
Voici ma façon:
Il utilise une combinaison de jQuery et CSS3. Fonctionne exactement comme l'attribut d'espace réservé html5! .
HTML:
<div class="placeholder" contenteditable="true"></div>
CSS3:
.placeholder:after {
content: "Your placeholder"; /* this is where you assign the place holder */
position: absolute;
top: 10px;
color: #a9a9a9;
}
jQuery:
$('.placeholder').on('input', function(){
if ($(this).text().length > 0) {
$(this).removeClass('placeholder');
} else {
$(this).addClass('placeholder');
}
});
Voici le correctif que j'ai utilisé.
<div contenteditable><em>Edit me</em></div>
<script>
$('div').focus(function() {
var target = $(this);
window.setTimeout(function() { target.empty(); }, 10);
});
</script>
J'ai développé un plug-in jQuery pour cela. Jetez un oeil https://github.com/phitha/editableDiv
Ce n'est pas une solution exacte à votre problème.
dans le jeu d'options summernote
airMode: true
l'espace réservé fonctionne de cette façon.
var curText = 'Edit me';
$('div').focusin(function() {
if ($(this).text().toLowerCase() == curText.toLowerCase() || !$(this).text().length) {
$(this).empty();
}
}).focusout(function() {
if ($(this).text().toLowerCase() == curText.toLowerCase() || !$(this).text().length) {
$(this).html('<em>' + curText + '</em>');
}
});