Как применять закругленные границы для выделения/выбора
Я использовал Visual Studio Online какое-то время для проекта и способ применения округленных границ к выборам в своем онлайн-браузере очень интересно:
![http://i.imgur.com/V9dlwSr.png]()
Я пробовал проверять элемент и искать какой-то пользовательский CSS, но не повезло.
У меня такое чувство, что для его работы требуются некоторые сложные "хаки", но это кажется очень интересным, как я никогда раньше не видел.
Как они могут применять закругленные границы к выделенной области?
Примечание.. Обычный выбор полностью скрыт. WHILE выбирает, а округленный выбор следует за вашим курсором, как обычный выбор. Не ПОСЛЕ того, что вы что-то выбрали.
Изменить: У меня создан вилка ответа @Coma, которая должна работать в Firefox и выбирать, пока мышь при перемещении с помощью:
$(document).on('mousemove', function () {
(Границы в некоторых случаях могут по-прежнему использовать работу.)
Ответы
Ответ 1
Не идеально, но он работает:
http://jsfiddle.net/coma/9p2CT/
Удалить реальный выбор
::selection {
background-color: transparent;
}
Добавить несколько стилей
span.highlight {
background: #ADD6FF;
}
span.begin {
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
span.end {
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
pre.merge-end > span:last-child {
border-bottom-right-radius: 0;
}
pre.merge-end + pre > span:last-child {
border-top-right-radius: 0;
}
pre.merge-begin > span:first-child {
border-bottom-left-radius: 0;
}
pre.merge-begin + pre > span:first-child {
border-top-left-radius: 0;
}
Оберните каждый символ в элементе node
var format = function () {
var before = -1;
var html = $.trim(editor.text())
.split("\n")
.reverse()
.map(function (line) {
var a = line.length === before ? 'merge-end' : '';
before = line.length;
return '<pre class="' + a + '"><span>' + line.split('').join('</span><span>') + '</span></pre>';
})
.reverse()
.join('');
editor.html(html);
};
Получить выбранные узлы и выделить их, позаботиться о своих родителях
var getSelectedNodes = function () {
var i;
var nodes = [];
var selection = rangy.getSelection();
for (i = 0; i < selection.rangeCount; ++i) {
selection
.getRangeAt(i)
.getNodes()
.forEach(function (node) {
if ($(node).is('span')) {
nodes.push(node);
}
});
}
return nodes;
};
var highlight = function (nodes, beforeNode) {
var currentNode = $(nodes.shift()).addClass('highlight');
var currentParent = currentNode.parent();
if (beforeNode) {
var beforeParent = beforeNode.parent();
if (currentParent.get(0) !== beforeParent.get(0)) {
currentNode.addClass('begin');
beforeNode.addClass('end');
beforeParent.addClass('merge-begin');
}
} else {
currentNode.addClass('begin');
}
if (nodes.length) {
highlight(nodes, currentNode);
} else {
currentNode.addClass('end');
}
};
format();
$(document).on('mouseup', function () {
$('.highlight').removeClass('highlight begin end');
highlight(getSelectedNodes());
});
Благодаря Tim Down для Rangy!
Ответ 2
Я могу заверить вас, что это не имеет ничего общего с html, css border radius или highlighting. Доказательство?
- Весь выбор отображается как единый блок с несколькими ребрами и верификациями и не является симметричным. Невозможно иметь несколько обрамленных фигур непосредственно в html, без использования SVG или Canvas. (хорошо, что возможность открыта для обсуждения)
- Если это не один блок, а действительно несколько строк, выделенных или помеченных каким-либо HTML или CSS или JS, тогда не может быть кривой внешнего вида:
![enter image description here]()
(всегда есть возможности. Например, вы можете покрыть выделение, используя белый прямоугольник с радиусом границы, но это кажется крайне неэффективным и маловероятным... Итак...)
Сводка, они должны использовать свойство Canvas и множество кодов для "подкладки" интерактивной процедуры выбора. В редакторе есть множество различных типов выделения, таких как "выделение того же слова", "выделение выделения", "исключение из фокуса" и т.д.... Для того, чтобы все это произошло эффективно, я не могу найти лучшую альтернативу чем холст.
Не злитесь на меня, чтобы опубликовать это. Но я не хотел, чтобы мои 4 часа исследований были отходами. По крайней мере, я получил наблюдение и это.
ОБНОВЛЕНИЕ:
Хотя я думал, что закрытие выделения с использованием белого прямоугольника с граничным радиусом в конце, является довольно неэффективным и ненужным. Microsoft так не думает.
Они используют изогнутые прямоугольники с закругленными углами, чтобы скрыть конец бликов, чтобы дать эффект. Они используют абсолютно позиционированный, округлый <div>
, чтобы дать эффект выделения. И в конце этого <div>
они накладывают изображение закругленного прямоугольника.
И с удовольствием к ним они отлично справились с этим.
Ответ 3
CSS '::selection
поддерживает только объявление цвета, фона, курсора и контура (См. W3C). Поэтому нет возможности определить border-radius
для выбора с помощью чистого CSS.
Поэтому я считаю, что они сделали это, как Никлас упоминал в комментариях:
- Подождите, пока пользователь ничего не выберет (selectstart, комбинация mousedown и mouseup)
- Получить выделенный текст
- Получить позицию выбранного текста (количество символов от начала), так как если вы просто дважды щелкните одно слово, вы не сможете создать из него правило
- Оберните выделение с помощью div или span
- Применить стили к обертке
- Слушайте, чтобы пользователь щелкнул что-то еще и т.д. (снимает с себя текст) → удалить обертку
Я начал пытаться самостоятельно создать решение, но я потерял свою мотивацию, так как потребовалось слишком много времени.
Возможно, кому-то могут понадобиться мои предложения (я использовал jQuery):
Для точки 2:
var selection = (window.getSelection() // > IE 9
|| document.selection.createRange() //< IE 9
).toString();
Для пункта 4 используйте replace()
Для точки 6:
$(".selection").replaceWith($(".selection")[0].childNodes);
Fiddle
Ответ 4
Они на самом деле используют круглые прямоугольники, чтобы покрыть конец бликов в предложениях, которые меньше, чем предыдущие или последующие строки (как я уже сказал в пункте 2). Проверьте это самостоятельно:
- Вы не можете проверять элемент непосредственно из iframe. Поэтому щелкните в другом месте и перейдите к iframe. Я сделал это, используя встроенный встроенный инспектор исходного кода.
- Затем используйте это изображение, чтобы узнать положение линии, выделенной на изображении.
- Это
<div>
содержит все основные выделения. Они просто накладывают вокруг текста прямоугольные прямоугольники с фоновым цветом, используя
абсолютный, верхний и левый!!! **
- Следующий
<div>
содержит похожие фоновые цвета <div>
s, только они предназначены для выделения целенаправленного слова, похожих слов и т.д.
![enter image description here]()
На самом деле это содержимое iframe. Посмотрите #document
вверху?
См. расширенный вид. Небольшое пространство над кодом имеет фактически выделенный раздел.
![enter image description here]()
Это не очень хорошая идея для простого веб-сайта. Им действительно нужно было разбираться и писать словами и буквами, поскольку он должен быть редактором кода высокого класса, поэтому не могу обвинять их в том, что они проводят сравнительно мало времени, чтобы немного закруглить края.
Ответ 5
проблема, когда вы делаете это с помощью JavaScript, он делает то, что делает после отпускания мыши