Vraag Hoe u afgeronde randen toepast om te markeren / selecteren


ik heb gebruikt Visual Studio Online voor een tijdje voor een project, en de manier waarop ze grenzen toepassen op selecties in hun online codeweergave is erg interessant:

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

Ik heb geprobeerd het element te inspecteren en op zoek te gaan naar een soort aangepaste CSS, maar had geen geluk.

Ik heb het gevoel dat dit een aantal complexe "hacks" vereist om het te laten werken, maar het lijkt erg interessant omdat ik het nog nooit eerder heb gezien.

Hoe kunnen ze afgeronde randen toepassen op een selectie?

Notitie: De normale selectie is volledig verborgen TERWIJL het selecteren en de afgeronde selectie volgt uw cursor net als een normale selectie. Niet NA je hebt iets geselecteerd.

Bewerk: ik heb creëerde een vork van @ Coma's antwoord dat zou moeten werken in Firefox en selecteer terwijl de muis beweegt met behulp van:

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

(De randen kunnen in bepaalde gevallen nog steeds werk gebruiken.)


17
2017-07-27 20:48


oorsprong


antwoorden:


Niet perfect maar het werkt:

http://jsfiddle.net/coma/9p2CT/

Verwijder de echte selectie

::selection {
   background-color: transparent;
}

Voeg enkele stijlen toe

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;
}

Wikkel elk teken in een knoopelement

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);
};

Pak de geselecteerde knooppunten en markeer ze, zorg voor hun ouders

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());
});

Dankzij Tim Down voor slanke!


7
2017-08-03 23:30



Ik kan je verzekeren dat dit niets te maken heeft met html, css border radius of highlighting. Het bewijs?

  1. De hele selectie wordt weergegeven als een enkel blok met meerdere randen en veritices en is niet symmetrisch. Het is niet mogelijk om direct in HTML een vorm met meerdere randen te gebruiken, zonder SVG of Canvas te gebruiken. (nou ja, dat is een mogelijkheid die open staat voor discussie)
  2. Als het geen enkel blok is, maar inderdaad meerdere regels gemarkeerd of gemarkeerd met een soort HTML of CSS of JS, kan er geen sprake zijn van een naar buiten gerichte curve zoals deze:
    enter image description here
    (er zijn altijd mogelijkheden, je zou bijvoorbeeld de selectie kunnen bedekken met een witte rechthoek met een grensradius, maar dit lijkt zeer inefficiënt en onwaarschijnlijk ... Dus ...)

Samenvatting, ze moeten de eigenschap Canvas en de hele partij codes gebruiken om een ​​interactieve selectieprocedure te 'onderbouwen'. Er zijn tal van verschillende soorten markeringen in de editor, zoals 'hetzelfde woord markeren', 'geselecteerde markering', 'onscherpe markering', enz ... Om dit allemaal efficiënt te laten gebeuren, kan ik geen beter alternatief vinden dan canvas.

Wees niet boos op me omdat ik dit heb gepost. Maar ik wilde mijn 4 uur onderzoek niet als een verspilling zien. Ik heb tenminste een observatie gekregen en dat is dat.

BIJWERKEN :

Hoewel ik dacht dat het bedekken van de selectie met een witte rechthoek met een randradius aan het einde, een nogal inefficiënte en onnodige manier is. Microsoft denkt van niet.

Ze gebruiken de rechthoekige rechthoeken om het einde van de hooglichten te verbergen om dat effect te bereiken. Ze gebruiken absoluut gepositioneerde, ronde randen <div>s om het effect van markeren te geven. En aan het einde daarvan <div>, ze overlappen een afbeelding van een afgeronde rechthoek.

En een pluim voor hen, ze hebben er uitstekend werk mee gedaan.


5
2017-08-03 14:10



CSS' ::selection ondersteunt alleen het declareren van kleur, achtergrond, cursor en omtrek (Zie W3C). Er is dus geen mogelijkheid om te definiëren border-radius voor de selectie met pure CSS.

Dus ik geloof dat ze het deden zoals Niklas in reacties zei:

  1. Wacht tot de gebruiker iets selecteert (select start, combinatie van muisaanwijzer en mouse-up)
  2. Ontvang de geselecteerde tekst
  3. Selecteer de positie van de geselecteerde tekst (aantal tekens vanaf het begin), want als u alleen op een enkel woord dubbelklikt, kunt u er geen regel van maken
  4. Wikkel de selectie met een div of span
  5. Pas stijlen toe op de verpakking
  6. Luister of de gebruiker op iets anders enz. Klikt (de selectie van de tekst ongedaan maken) -> wrapper verwijderen

Ik begon zelf een oplossing te proberen te maken, maar ik verloor mijn motivatie omdat het teveel tijd kostte. Misschien had iemand mijn suggesties nodig (ik gebruikte jQuery):

Voor punt 2:

var selection = (window.getSelection() // > IE 9 
                 || document.selection.createRange() //< IE 9
                ).toString();

Gebruik voor punt 4 replace ()

Voor punt 6:

$(".selection").replaceWith($(".selection")[0].childNodes);

Viool


2
2017-07-27 22:38



Ze gebruiken eigenlijk rechthoekige rechthoeken om het einde van hooglichten in zinnen te bedekken die kleiner zijn dan de voorgaande of volgende regels (precies zoals ik in punt 2 heb gezegd). Bekijk dit zelf:

  1. U kunt het element niet rechtstreeks vanuit het iframe inspecteren. Dus klik ergens anders en navigeer naar het iframe. Ik deed het met behulp van de ingebouwde broncode-inspecteur van chromes.
  2. Gebruik vervolgens deze afbeelding om de positie te bepalen van de lijn die in de afbeelding is gemarkeerd.
  3. Dat <div> bevat alle "selectie" hoogtepunten. Ze gebruiken alleen afgeronde, achtergrondgekleurde rechthoeken onder de tekst met absoluut, linksboven !!! **
  4. De volgende <div> heeft een vergelijkbare achtergrondkleur <div>s, alleen voor het benadrukken van gericht woord, soortgelijke woorden, enz.

enter image description here

Dit is eigenlijk de inhoud van het iframe. Zie de #document op de top?

Bekijk de uitgevouwen weergave. De kleine ruimte boven het hebben van de code is eigenlijk het gemarkeerde gedeelte.

enter image description here

Dit is echter geen goed idee voor een eenvoudige website. Ze moesten de woorden en letters echt ontleden en verwerken, omdat het een high-end code-editor moet zijn, dus kan het hen niet kwalijk nemen dat ze relatief weinig tijd hebben besteed om de randen een beetje 'rond te draaien'.


1
2017-08-03 16:58