我正在尝试向文档中的选定文本添加类。问题是我不希望用户能够选择页面上的所有文本(例如使用命令+ A ......)所以我想从一个范围中删除节点,但我不知道如何要做到这一点。这个页面有很多文本/嵌套div,因此使用添加的类来检查它是否在可选择的元素中将非常耗时/慢。
我做了一个小提琴来解释我想要做得更好的事情。 http://jsfiddle.net/thomasjonas/BhKFt/20/
如果您选择此示例中的所有文本,则该类将添加到所有div中。我希望它只将css应用于带有'yes'类的div。对于这个有一个很好的,非浏览器崩溃的解决方案吗?
提前致谢!
答案 0 :(得分:2)
以下是有点笨拙且低效的,因为它检查每个元素与“yes”类相交的选择。例如,您可以通过提前检查选择是否完全位于具有“是”类的单个元素中来改进它。它使用Rangy专有的intersection()
范围对象方法。
演示:http://jsfiddle.net/timdown/BhKFt/23/
代码:
// getElementsByClassName implementation for browsers without it
// (IE <= 7, for example)
var getElementsByClassName =
(typeof document.documentElement.getElementsByClassName != "undefined") ?
function(el, cssClass) {
return el.getElementsByClassName(cssClass);
} :
function(el, cssClass) {
var allEls = el.getElementsByTagName("*");
var elsWithClass = [];
var classRegex = new RegExp("(?:^|\\s)" + cssClass + "(?:\\s|$)");
for (var i = 0, len = allEls.length, el; i < len; ++i) {
el = allEls[i];
if (el.className && classRegex.test(el.className)) {
elsWithClass.push(el);
}
}
return elsWithClass;
};
$(document).ready(function(){
rangy.init();
$(document).mouseup(function(){
var sel = rangy.getSelection();
var range = sel.getRangeAt(0);
var classApplier = rangy.createCssClassApplier("tmp");
var els = getElementsByClassName(document.body, "yes");
// Create an array of ranges that represent the intersection of
// the selection with each "yes" element
var rangesWithClass = [];
for (var i = 0, len = els.length, elRange; i < len; ++i) {
if (range.intersectsNode(els[i])) {
elRange = rangy.createRange();
elRange.selectNode(els[i]);
rangesWithClass.push(range.intersection(elRange));
elRange.detach();
}
}
// Apply the class to the ranges obtained in the last step
for (i = 0, len = rangesWithClass.length; i < len; ++i) {
classApplier.applyToRange(rangesWithClass[i]);
rangesWithClass[i].detach();
}
sel.removeAllRanges();
});
});
如果传递给rangy.createCssClassApplier()
的选项对象有某种过滤选项,则可能很有用。我会考虑一下。