Подтвердить что ты не робот

Как применять закругленные границы для выделения/выбора

Я использовал Visual Studio Online какое-то время для проекта и способ применения округленных границ к выборам в своем онлайн-браузере очень интересно:

http://i.imgur.com/V9dlwSr.png

Я пробовал проверять элемент и искать какой-то пользовательский CSS, но не повезло.

У меня такое чувство, что для его работы требуются некоторые сложные "хаки", но это кажется очень интересным, как я никогда раньше не видел.

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

Примечание.. Обычный выбор полностью скрыт. WHILE выбирает, а округленный выбор следует за вашим курсором, как обычный выбор. Не ПОСЛЕ того, что вы что-то выбрали.

Изменить: У меня создан вилка ответа @Coma, которая должна работать в Firefox и выбирать, пока мышь при перемещении с помощью:

$(document).on('mousemove', function () {

(Границы в некоторых случаях могут по-прежнему использовать работу.)

4b9b3361

Ответ 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, он делает то, что делает после отпускания мыши