Javascript jquery选择器中包含的范围
我正在开发一个JavaScript包装器。我试图做的是:给定jQuery选择器和一个范围,检测该范围是否包含在选择器中。这是一个用户将阅读文档并能够对特定部分发表评论的空间。因此,我有一个包含文档的div,其中包含Javascript jquery选择器中包含的范围,javascript,jquery,dom,rangy,Javascript,Jquery,Dom,Rangy,我正在开发一个JavaScript包装器。我试图做的是:给定jQuery选择器和一个范围,检测该范围是否包含在选择器中。这是一个用户将阅读文档并能够对特定部分发表评论的空间。因此,我有一个包含文档的div,其中包含id=“viewer”,还有一个按钮区域,在用户选择一些文本后执行操作。以下是(断开的)函数: function selectedRangeInRegion(selector) { var selectionArea = $(selector); var range =
id=“viewer”
,还有一个按钮区域,在用户选择一些文本后执行操作。以下是(断开的)函数:
function selectedRangeInRegion(selector) {
var selectionArea = $(selector);
var range = rangy.getSelection().getRangeAt(0);
var inArea = (selectionArea.has(range.startContainer).length > 0);
if (inArea) {
return range;
} else {
return null;
}
}
似乎selectionArea.has(range.startContainer)
返回一个大小为0的数组。我尝试过像这样包装:$(range.startContainer)
。有什么建议吗
我为这个问题找到了解决办法。这假设您有一个div选择器,并且您的内容没有任何div:
function containsLegalRange(selector, range) {
var foundContainingNode = false;
var container = range.commonAncestorContainer
var nearestDiv = $(container).closest("div");
if (nearestDiv.attr("id") == selector) {
return true
}
else {
return false
}
}
.has()有时可能会很奇怪,并在不应该的情况下生成.length==0
。请尝试以下方法:
function selectedRangeInRegion(selector) {
var range = rangy.getSelection().getRangeAt(0);
var selectionArea = selector + ':has(\'' + range.startContainer + '\')';
var inArea = $(selectionArea).length > 0);
if (inArea) {
return range;
}
else {
return null;
}
}
has()
不是这样工作的:传递给它的参数是选择器字符串或DOM元素,而range.startContainer
是DOM节点,实际上可能是文本节点或元素
我不认为会有一种方法像你希望的那样简单。下面是我能想到的最简单的事情
jsFiddle:
代码:
如果这对您有帮助,请单击我答案旁边的复选标记!这不太可能在所有情况下都起作用:
range.startContainer
实际上可能是文本节点或元素,因此在后一种情况下,将其转换为字符串肯定没有帮助。这种解决方案对我不起作用。我在调用$(selectionArea)时遇到错误“Uncaught Syntax error,unrecogned expression:[对象文本]”。原始代码中有一个拼写错误(缺少大括号)。我想这不是故意的?是的,不是故意的。我从粘贴的代码中删除了调试代码,而不是事先删除。感谢这看起来几乎可以工作,但是如果我在所选div中选择一些文本,在该div之外选择一些文本,containsRange将返回true。将“allowPartiallySelected”更改为false,containsRange似乎总是返回false。有没有办法将jquery选择器转换为一个范围并调用containsNode?@Jordan:通常没有办法创建一个包含jquery对象内容的范围,因为jquery对象包含一组可能不相交的节点。您可以创建一个包含jQUery对象中每个节点的范围,但这没有帮助,因为它可能还包含不属于jQUery对象的节点。关于<代码>允许部分选择< /代码>设置为<代码> false <代码>,我同情:因为<代码>包容节点< /代码>在它所考虑的“包含”中是迂腐的,这是一个问题,因为单个视觉位置可以是DOM中几个不同点中的任何一个。@约旦:例如,如果光标位于主div的开头,则视为位于div中文本节点的开头,但主div的范围在div之前立即开始。containsNode()
是非标准的Rangy扩展,但与其他标准范围方法一致,但是对于大多数用例来说都不是那么容易处理的,所以我正在考虑在Rangy ranges中添加一个containsNodeText()
或类似的方法。Tim,非常感谢你的帮助(我使用的插件的开发人员回答了我的问题,非常酷)。我想出了一个不同的解决方案,并编辑了我原来的问题。@Jordan:很公平。我试图回答最一般的情况,但如果你的需求更简单,那就太好了。
function containsRange(selector, range, allowPartiallySelected) {
var foundContainingNode = false;
$(selector).each(function() {
if (range.containsNode(this, allowPartiallySelected)) {
foundContainingNode = true;
return false;
}
});
return foundContainingNode;
}