Редактор YUI (RTE): Как обернуть выделение <span>и НЕ потерять форматирование? - PullRequest
0 голосов
/ 02 ноября 2010

Хорошо, у меня возникла проблема, над которой я работал последнюю неделю или около того и перепробовал все, что я знаю или смог найти. Я использую YUI 2.x редактор, где пользователи будут выполнять тяжелое форматирование. У меня есть внешняя кнопка на странице, которая должна обернуть выделенный текст в <span>, когда пользователь щелкает по нему, но он должен сделать это без без потери форматирования. По какой-то причине делать следующее любит стереть все форматирование в выделении:

var sel = myEditor._getSelection();
var newEl = '<span>' + sel + '</span>';
myEditor.execCommand('inserthtml', newEl);

Поэтому, чтобы решить эту проблему, я думаю, что лучше всего использовать _getSelectedElement() вместе с _createCurrentElement('span') для добавления элементов стиля. Вот что у меня так далеко:

function createSpan() {
  var el = myEditor._getSelectedElement();
  var sel = myEditor._getSelection();

  // IE support
  if (document.selection) {
    sel = myEditor._getDoc().selection.createRange();
    newText = sel.text;
  }
  else {
    newText = sel;
  }

  // Create the new element with the old styles
  myEditor._createCurrentElement('span', {color: el.style.color, fontSize: el.style.fontSize, fontFamily: el.style.fontFamily});
  myEditor._selectNode(myEditor.currentElement[0]);
  myEditor.currentElement[0].innerHTML = newText;
  return myEditor.currentElement[0];
}

Это прекрасно работает, если _getSelectedElement() правильно возвращает элемент с правильными стилями, но я обнаружил, что если пользователь выберет целый абзац, он вернет BODY. И поскольку у BODY нет стилей, они снова теряются.

По сути, мне нужно, чтобы он вел себя как кнопка Bold на панели инструментов, но использовал <span>, а не <b>. Почему это так сложно?

Есть идеи или предложения? Спасибо!

Ответы [ 2 ]

1 голос
/ 02 ноября 2010

Оказывается, все, что вам нужно сделать, это:

myEditor._createCurrentElement('span');
newEl = myEditor.currentElement[0];

_createCurrentElement внутренне создает новый элемент с текущим выбором в качестве innerHTML и сохраняет форматирование для вас. Так просто ... спасибо Дэв Гласс за помощь. Проверьте его пост здесь: http://yuilibrary.com/forum/viewtopic.php?f=89&t=5436&p=18659#p18659

0 голосов
/ 11 сентября 2012

Попробуйте это:

function toHTML(docFragment) {
    var d = this._getDoc().createElement('div');
    d.appendChild(docFragment);
    return d.innerHTML;
}

var ie = false;
if (this._getWindow().getSelection) { 
    var selectedText = this._getWindow().getSelection(); 
} else if ( this._getDoc().getSelection ) { 
    var selectedText = this._getDoc().getSelection(); 
} else if ( this._getDoc().selection ) { 
    ie = true;
    var selectedText = this._getDoc().selection.createRange();
} 
if (!ie) {
    var theParent = selectedText.getRangeAt(0).cloneContents(); 
    var selection = toHTML(theParent);
} else {
    var selection = selectedText.htmlText;
}

var span = this._getDoc().createElement('span');

span.innerHTML = selection;

if (!ie) {
    var rang = selectedText.getRangeAt(0);
    if ($.browser.mozilla) {
        var rangeObj = this._getDoc().createRange();
        var documentFragment = rangeObj.createContextualFragment(span.outerHTML);
    } else {
        var d = this._getDoc().createElement('div');
        d.innerHTML = span.outerHTML;
        var docFrag = this._getDoc().createDocumentFragment();
        while (d.firstChild) {
            docFrag.appendChild(d.firstChild);
        };
        var documentFragment = docFrag;
    }
    rang.collapse(false);
    rang.deleteContents();
    rang.insertNode(documentFragment);
} else {
    this._getDoc().selection.createRange().pasteHTML(span.outerHTML);
}
...