CSS:: фокус элементов в contenteditable

если у вас есть следующий HTML-код:

<div contenteditable="true">
  <p>The first paragraph</p>
  <p>The second paragraph</p>
</div>

есть ли способ стилизовать абзац, который редактируется иначе, чем все другие абзацы в div что это contenteditable?

div > p:focus { border: 1px solid red }

не будет применяться к редактируемому абзацу.

здесь JSFiddle вы можете играть.

как я могу стиль пункт редактируется (the <p> - tag) по-другому?

Я предпочитаю решение только для CSS, но, возможно, мне придется использовать JavaScript.

EDIT:

так как мы не смогли найти чистое решение CSS (и используя :hover не является реальным решением для меня) теперь я ищу некоторые строки JavaScript, которые устанавливают атрибут class="focus" на редактируемом узле.

3 ответов


Я думаю, что нашел решение.

со следующим фрагментом кода Вы можете получить родительский элемент в текущей позиции курсора при изменении выбора.

var selectedElement = null;
function setFocus(e) {
  if (selectedElement)
    selectedElement.style.outline = 'none';

  selectedElement = window.getSelection().focusNode.parentNode;
  // walk up the DOM tree until the parent node is contentEditable
  while (selectedElement.parentNode.contentEditable != 'true') {
    selectedElement = selectedElement.parentNode;
  }
  selectedElement.style.outline = '1px solid #f00';
};
document.onkeyup = setFocus;
document.onmouseup = setFocus;

здесь я меняю outline свойство вручную, но вы можете, конечно, добавить атрибут класса и установить стиль через CSS.

вы все еще должны вручную проверить, если selectedElement - дитя нашего <div> С . Но я думаю, что вы можете получить основную идея.

здесь обновил JSFiddle.

EDIT: я обновил код, а также JSFiddle, чтобы он работал в Firefox и Internet Explorer 9+. К сожалению, эти браузеры не имеют onselectionchange обработчик событий, поэтому мне пришлось использовать onkeyup и onmouseup.


интересный вопрос. Если он жизнеспособен, я бы предложил переместить атрибут contenteditable в ps сами:http://codepen.io/pageaffairs/pen/FHKAC

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">

<style media="all">

div > p:focus {outline: 1px solid red; }

</style>

</head>
<body>

<div>
    <p contenteditable="true">The first paragraph</p>
    <p contenteditable="true">The second paragraph</p>
</div>

</body>
</html>

EDIT: вот еще одна версия, которая заставляет para returns генерировать paras вместо divs:http://codepen.io/pageaffairs/pen/dbyIa

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">

<style media="all">

div:focus {outline: none;}
div > p:focus, div > p:hover {outline: 1px solid red; }

</style>

</head>
<body>

<div contenteditable="true">
    <p contenteditable="true">The first paragraph</p>
    <p contenteditable="true">The second paragraph</p>
</div>

</body>
</html>

jsFiddle здесь.

следующее несовершенно в том смысле, что ваша мышь должна быть в той же области, что и выбранный абзац (чтобы сохранить :hover аргумент true), но так как это обычно будет так или иначе, это должно быть хорошо - это лучшее, что вы получите, если хотите сохранить свою разметку как есть во всяком случае:

CSS:

div[contenteditable="true"]:focus > p:hover {
   border: 2px solid red;
}

HTML-код:

<div contenteditable="true">
   <p>The first paragraph</p>
   <p>The second paragraph</p>
</div>

jsFiddle здесь.

если вы можете изменить разметку, вы можете использовать следующий упрощенный селектор:

CSS:

p[contenteditable="true"]:focus {
   border: 2px solid red;
}

HTML-код:

<div>
   <p contenteditable="true">The first paragraph</p>
   <p contenteditable="true">The second paragraph</p>
</div>