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

Если у вас есть следующий 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.

Как я могу отредактировать отредактированный абзац (<p> -tag) по-другому?

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

EDIT:

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

Ответ 1

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

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

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> с атрибутом contenteditable. Но я думаю, что вы можете получить основную идею.

Здесь обновленный JSFiddle.

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

Ответ 2

Интересный вопрос. Если это жизнеспособно, я бы предложил переместить атрибут contenteditable самому p: 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 возвращает генерировать парас вместо div: 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>

Ответ 3

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>