JavaScript получить идентификатор «CommonAncestorContainer» - PullRequest
0 голосов
/ 01 августа 2011

Так что я чувствую себя немного не в своей лиге.Но вот что я хочу сделать.

По сути, я хочу, чтобы пользователь выделил часть текста внутри абзаца (который может содержать много элементов (т. Е. <span> и <a>), чтобы вернуть значение атрибута id этого абзаца.Вот что я думаю.

function getParaID() //function will be called using a mouseUp event
{
var selObj = window.getSelection();
var selRange = selObj.getRangeAt(0); //btw can anyone explain what this zero means
var paraElement = selRange.commonAncestorContainer;
var paraID = paraElement.getAttribute;

return paraID;
 }

Что ты думаешь? Я рядом?

Ответы [ 2 ]

3 голосов
/ 01 августа 2011

Свойство commonAncestorContainer диапазона выбора может быть ссылкой на текстовый узел, или элементом <span>, или <a>, или элементом <body>, или чем-либо еще, что вы можете иметь на своей странице.В таком случае вам нужно обработать дерево DOM, чтобы найти содержащий <p> элемент, если таковой существует.Вы также должны знать, что IE <9 не поддерживает <code>window.getSelection() или DOM Range, хотя в IE <9 можно довольно легко делать то, что вы хотите. Вот код, который будет работать во всех основных браузерах, включая IE 6: </p>

jsFiddle: http://jsfiddle.net/44Juf/

Код:

function getContainingP(node) {
    while (node) {
        if (node.nodeType == 1 && node.tagName.toLowerCase() == "p") {
            return node;
        }
        node = node.parentNode;
    }
}

function getParaID() {
    var p;
    if (window.getSelection) {
        var selObj = window.getSelection();
        if (selObj.rangeCount > 0) {
            var selRange = selObj.getRangeAt(0);
            p = getContainingP(selRange.commonAncestorContainer);
        }
    } else if (document.selection && document.selection.type != "Control") {
        p = getContainingP(document.selection.createRange().parentElement());
    }
    return p ? p.id : null;
}

Относительно 0, переданного в getRangeAt(), это указывает, какой выбранный диапазон вы хотите.Firefox поддерживает несколько выбранных диапазонов: если вы сделаете выделение, а затем удерживаете Ctrl и сделаете еще один выбор, вы увидите, что теперь у вас выбраны два прерывистых диапазона, к которым можно получить доступ через getRangeAt(0) и getRangeAt(1),Также в Firefox выбор столбца ячеек в таблице создает отдельный диапазон для каждой выбранной ячейки.Количество выбранных диапазонов можно получить с помощью свойства rangeCount выбора.Ни один другой крупный браузер не поддерживает несколько выбранных диапазонов.

2 голосов
/ 01 августа 2011

Ты совсем близко. Если вам нужен только идентификатор родительского элемента, тогда вы должны заменить paraElement.getAttribute на paraElement.id, например:

var paraID = paraElement.id;

Что касается параметра getRangeAt(), он указывает индекс диапазона выбора, который нужно вернуть, и он действительно имеет отношение только к элементам управления, которые допускают прерывистый выбор. Например, поле select, в котором пользователь может использовать ctrl + click для одновременного выбора нескольких произвольных групп строк. В таком случае вы можете использовать параметр для перехода от одного выбранного региона к следующему. Но для выделения текста внутри абзаца у вас никогда не должно быть прерывистого выделения, и поэтому всегда можно пропустить 0. По сути это означает, что вы запрашиваете «первый выбранный регион».

Также обратите внимание, что если ваш интерфейс позволяет выбору пользователя охватывать несколько абзацев, тогда ваш commonAncestorContainer может не быть абзацем, это также может быть любой элемент, содержащий все ваши теги абзаца. Так что вы должны быть готовы разобраться с этим делом.

Edit:

Немного поиграв с этим, вот мое предложение: http://jsfiddle.net/vCsZH/

По сути, вместо того, чтобы полагаться на commonAncestorContainer, этот код применяет mouseDown и mouseUp слушатель к каждому абзацу (в дополнение к тому, который уже применен к контейнеру верхнего уровня). По сути, слушатели будут записывать абзацы, в которых начинается и заканчивается диапазон выбора, что значительно упрощает надежную работу по выбору абзацев.

Если когда-либо был случай в пользу использования динамического связывания событий через фреймворк, такой как jQuery, вот оно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...