如何应用圆角边框突出显示/选择 [英] How to apply rounded borders to highlight/selection
问题描述
对于一个项目,我已经使用 Visual Studio Online 一段时间了,并且他们将圆角边框应用于所选内容的方式在线代码查看器非常有趣:
I have used Visual Studio Online for a while for a project, and the way they apply rounded borders to selections in their online code viewer is very interesting:
我尝试检查元素并寻找某种自定义CSS,但是没有运气.
I've tried inspecting the element and looking for some kind of custom CSS, but had no luck.
我感觉这需要一些复杂的技巧"才能使其起作用,但它似乎非常有趣,因为我从未见过如此.
I have a feeling this requires some complex "hacks" to make it work, but it seems very interesting as I've never seen it done before.
他们如何将圆角边框应用于选区?
注意:普通选择在选择时完全隐藏,而四舍五入的选择就像常规选择一样跟随您的光标.选择完之后,才可以.
Note: The normal selection is completely hidden WHILE selecting, and the rounded selection follows your cursor just like a regular selection. Not AFTER you have selected something.
编辑:我已经创建了@Coma答案的叉子,应该可以在Firefox中工作,并且如果使用以下命令进行移动,请选择鼠标的另一端:
I have created a fork of @Coma's answer that should work in Firefox and select while the mouse if moving using:
$(document).on('mousemove', function () {
(在某些情况下边界仍然可以使用.)
(The borders in certain cases could still use work.)
推荐答案
不完美,但可以正常工作:
Not perfect but it's working:
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;
}
包装节点元素中的每个字符
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());
});