javascript - 检查指定元素是否在选择范围内

标签 javascript

我正在为以下问题搜索跨浏览器解决方案(Chrome、FF、Opera > 10、IE >= 8):

有一些html代码:

<div>
    <div id="one">
        <p id="red">red</p>
        <p id="green">green</p>
    </div>
    <div id="two">
        <p id="blue">blue</p>
        <p id="black">black</p>
    </div>
</div>

然后用户使用鼠标文本从“een”(在#green 节点中)到“blu”(在#blue 节点中)进行选择。如何检查#blue 是否在选择范围内(无论是全部还是部分选择都无关紧要)并且#red 和#black 不在选择范围内。 简单的 API 如下所示:

Selection.isElementSelected(document.getElementById('black'));

我已尝试使用 DOMSelection 和范围,但问题是我需要检查嵌套结构中的元素。在 Chrome 中,我可以使用 Range.intersectsNode(),但这是唯一支持此方法的浏览器。

有什么建议吗?

最佳答案

经过一些研究,我根据以下 Material 制定了解决方案: https://developer.mozilla.org/en/DOM/range

http://msdn.microsoft.com/en-us/library/ms535872(v=vs.85).aspx

http://www.quirksmode.org/dom/range_intro.html

在 IE8 的情况下,必须选择整个节点,但这对我来说是可以接受的。

这是 jsfiddle 上的一些 Playground :http://jsfiddle.net/58Uvd/ 这是代码:

(function () {

    function UserRange (win) {
        this.win = win || window;
        this.doc = this.win.document;

        this.userRange = this.createUserRange();
    }

    var NonIEPrototype = {

        constructor: UserRange,

        createUserRange: function () {
            var selection = this.win.getSelection();
            return selection.rangeCount
                ? selection.getRangeAt(0)
                : this.doc.createRange();
        },

        overlapsNode: function (node) {
            return this.intersectsNode(node);
        },


        intersectsNode: function (node) {
            // this method is implemented in Firefox with Gecko before 1.9
            // and other non-IE browsers
            if (this.userRange.intersectsNode) {
                return this.userRange.intersectsNode(node);
            }

            return this.intersectsRange(this.createRangeWithNode(node));
        },

        createRangeWithNode: function (node) {
            var rangeWithNode = node.ownerDocument.createRange();
            try {
                rangeWithNode.selectNode(node);
            }
            catch (ex) {
                rangeWithNode.selectNodeContents(node);
            }
            return rangeWithNode;
        },

        intersectsRange: function (range) {
            return this.userRange.compareBoundaryPoints(Range.END_TO_START, range) === -1 &&
                this.userRange.compareBoundaryPoints(Range.START_TO_END, range) === 1;
        }
    };

    var IEPrototype = {

        constructor: UserRange,

        createUserRange: function () {
            return this.doc.selection.createRange();
        },

        overlapsNode: function (node) {
            var rangeWithNode = this.createRangeWithNode(node);
            return this.containsRange(rangeWithNode);
        },

        createRangeWithNode: function (node) {
            var range = node.ownerDocument.selection.createRange();
            range.moveToElementText(node);
            return range;
        },

        containsRange: function (range) {
            return this.userRange.inRange(range);
        }
    };

    UserRange.prototype = window.getSelection ? NonIEPrototype : IEPrototype;
    window.UserRange = UserRange;

}());

和用法:

var userRange = new UserRange();
userRange.overlapsNode(document.getElementById('node-to-check'));

关于javascript - 检查指定元素是否在选择范围内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9324654/

相关文章:

javascript - 如何使用 jquery 抓取多个元素并将它们包装在一个 div 中?

javascript - AngularJS $http 使用参数中的对象访问 ASP.NET Web Api

javascript - 您可以将 "dumb down"ES6 模板字符串转换为普通字符串吗?

javascript - 从 console.log 调用 webpack 捆绑函数/类

javascript - 向下滚动时如何将 div 的底部粘贴到屏幕顶部?

javascript - 在 AngularJS 中使用 $window 或 $location 重定向

javascript - 如何使用javascript获取和比较图像的边框样式

javascript - 如何根据从 DOM 接收到的键更新状态数组中的某些对象

javascript - 在 jquery 函数中使用 php 中的 javascript 变量

javascript 如果小于,则显示售完