Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript jquery选择器中包含的范围_Javascript_Jquery_Dom_Rangy - Fatal编程技术网

Javascript jquery选择器中包含的范围

Javascript jquery选择器中包含的范围,javascript,jquery,dom,rangy,Javascript,Jquery,Dom,Rangy,我正在开发一个JavaScript包装器。我试图做的是:给定jQuery选择器和一个范围,检测该范围是否包含在选择器中。这是一个用户将阅读文档并能够对特定部分发表评论的空间。因此,我有一个包含文档的div,其中包含id=“viewer”,还有一个按钮区域,在用户选择一些文本后执行操作。以下是(断开的)函数: function selectedRangeInRegion(selector) { var selectionArea = $(selector); var range =

我正在开发一个JavaScript包装器。我试图做的是:给定jQuery选择器和一个范围,检测该范围是否包含在选择器中。这是一个用户将阅读文档并能够对特定部分发表评论的空间。因此,我有一个包含文档的div,其中包含
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;
}