转跳到内容

同時打開多個修改編輯框時,圖片插入的位置不正確


推荐贴

光看標題可能會有點抽象。先說起因,最近看到了這個帖子,https://sstm.moe/topic/358822-不用打开检查界面就通过外链插入音视频控件的脚本直接获取全民k歌电脑网页音频源文件的脚本(基于tampermonkey插件)/,所以去找了下可以準確地將元素插入到相應的編輯框的方法,然後就發現了這個


首先看下圖,隨便找個回覆點修改,可以看到在 CKEDITOR.instances 中有兩個object,帶有id的是最底下新回覆的,先不用管它。comment_value 則是修改回覆用的編輯框。

TPi2AJFT_o.png


這時候在"其他媒體" >> "插入外部圖片"中輸入鏈接可以正常插入圖片,到這裡都沒有問題。
7CNbu8Rt_o.png 


但假如在保持之前的修改編輯器存在的情況下再打開另一個,可以看到CKEDITOR.instances 中仍然只有兩個object
tb2dCccV_o.png


這時在任意的修改框裡插入圖片,圖都會出現在最後打開的那一個裡面
f2cHHJL2_o.png aBeySPXP_o.png


問題講完了,再說說原因,首先可以看到這個編輯框是基於CKEditor的,在創建的時候會調用CKEDITOR.add,在CKEDITOR.instances[b.name] = b; 這裡用name 作為key把editor寫入到CKEDITOR.instances裡面(也就是一開始展示的那個)。
但是所有的修改框都叫comment_value,所以在CKEDITOR.instances中只能找到最後創建的那一個。

CKEDITOR.add = function(b) {
    function h() {
        CKEDITOR.currentInstance == b && (CKEDITOR.currentInstance = null,
        CKEDITOR.fire("currentInstance"))
    }
    CKEDITOR.instances[b.name] = b;
    b.on("focus", function() {
        CKEDITOR.currentInstance != b && (CKEDITOR.currentInstance = b,
        CKEDITOR.fire("currentInstance"))
    });
    b.on("blur", h);
    b.on("destroy", h);
    CKEDITOR.fire("instance", null, b)
}

其二就是在插入圖片時也是在CKEDITOR.instances裡面去找的,可以看var editor = CKEDITOR.instances[$(this.scope).data('editorid')]; 這一句,最終導致在同時存在多個修改框時,只會找到最後創建的那一個

insertLink: function(e) {
  var url = this.scope.find('[data-role="linkURL"]').val().replace(/'/g, '%27').replace(/"/g, '%22').replace(/</g, '%3C').replace(/>/g, '%3E');
  if (!url) {
    $(this.scope).find('.ipsFieldRow.ipsFieldRow_fullWidth').addClass('ipsFieldRow_error');
    return;
  } else {
    $(this.scope).find('.ipsFieldRow.ipsFieldRow_fullWidth').removeClass('ipsFieldRow_error');
  }
  $(this.scope).find('.elLinkError').remove();
  if (!url.match(/^[a-z]+\:\/\//i) && !url.match(/^mailto\:/i) && !url.match(/^\#/)) {
    url = 'http://' + url.replace(/^\/*/, '');
  }
  var editor = CKEDITOR.instances[$(this.scope).data('editorid')];
  var selection = editor.getSelection();
  if (!_.isUndefined(editor._linkBookmarks)) {
    selection.selectBookmarks(editor._linkBookmarks);
    delete editor._linkBookmarks;
  }
  var selectedElement = selection.getSelectedElement();
  if (selectedElement && selectedElement.is('img')) {
    var selectedElement = $(selection.getSelectedElement().$);
    if (!selectedElement.parent().is('a')) {
      var element = CKEDITOR.dom.element.createFromHtml("<a href='" + url + "'>" + selectedElement[0].outerHTML + "</a>");
      editor.insertElement(element);
    } else {
      selectedElement.parent().attr('href', url).removeAttr('data-cke-saved-href');
    }
    this.scope.find('input.cEditorURL').val('');
    this.trigger('closeDialog');
  } else if (selectedElement && (selectedElement.is('a') && $(selection.getSelectedElement().$).children().is('img'))) {
    selectedElement.setAttribute('href', url).removeAttribute('data-cke-saved-href');
    this.scope.find('input.cEditorURL').val('');
    this.trigger('closeDialog');
  } else {
    if ($(this.scope).data('image')) {
      this.scope.find('[data-role="linkURL"]').addClass('ipsField_loading');
      this.scope.find('[data-action="linkButton"]').prop('disabled', true);
      var scope = this.scope;
      var self = this;
      var img = new Image();
      img.onerror = function () {
        scope.find('[data-role="linkURL"]').removeClass('ipsField_loading');
        scope.find('[data-action="linkButton"]').prop('disabled', false);
        scope.find('.ipsFieldRow.ipsFieldRow_fullWidth').addClass('ipsFieldRow_error');
      }
        ;
      img.onload = function () {
        var ajaxUrl = editor.config.controller + '&do=validateLink'
        if ($(this.scope).attr('data-image')) {
          ajaxUrl += '&image=1';
        }
        ips.getAjax()(ajaxUrl, {
          data: {
            url: url,
            width: img.width,
            height: img.height,
            image: 1
          },
          type: 'post'
        }).done(function (response) {
          if (response.embed) {
            scope.find('[data-role="linkURL"]').removeClass('ipsField_loading');
            scope.find('[data-action="linkButton"]').prop('disabled', false);
            scope.find('input.cEditorURL').val('');
            editor.insertHtml(response.preview);
            self.trigger('closeDialog');
          } else {
            scope.find('[data-role="linkURL"]').removeClass('ipsField_loading');
            scope.find('[data-action="linkButton"]').prop('disabled', false);
            scope.find('.ipsFieldRow.ipsFieldRow_fullWidth').addClass('ipsFieldRow_error');
            if (!_.isUndefined(response.errorMessage)) {
              scope.find('.ipsFieldRow.ipsFieldRow_fullWidth').append("<span class='elLinkError ipsType_warning'>" + response.errorMessage + "</span>");
            }
          }
        }).fail(function () {
          scope.find('[data-role="linkURL"]').removeClass('ipsField_loading');
          scope.find('[data-action="linkButton"]').prop('disabled', false);
          scope.find('.ipsFieldRow.ipsFieldRow_fullWidth').addClass('ipsFieldRow_error');
        });
      }
      img.src = url;
    } else {
      if (this.scope.find('[data-role="linkText"]').length) {
        var title = this.scope.find('[data-role="linkText"]').val().replace(/ {2}/g, ' &nbsp;');
        if (!title) {
          title = decodeURI(url);
        }
        title = title.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
        var element = CKEDITOR.dom.element.createFromHtml("<a>" + title + "</a>");
      } else {
        element = selectedElement;
      }
      element.setAttribute('href', url);
      editor.insertElement(element);
      this.scope.find('input.cEditorURL').val('');
      this.trigger('closeDialog');
    }
  }
}

 

我無法保證這裡說的東西完全正確,但是有打斷點檢查過,應該大致上是對的…吧?

順帶一提,如果你想寫腳本確實有需要用到這個editor,除了在CKEDITOR.instances裡面找,在這個div身上也可以拿到OIEeW6HF_o.png

 

 

 

順便再吐槽一下論壇的附件,我忍這東西很久了。直接點擊進行下載的時候不會指定文件名稱(明明在頁面上就有顯示文件名)。而且有些類型的文件不會直接下載,而是會跳轉到新頁面直接顯示(就算加了download attribute也不行。瀏覽器基於安全性的考慮,只有來自同一個來源的時候它才會生效)

,由幽月零修改
链接到点评

创建帐号或登入才能点评

您必须成为用户才能点评

创建帐号

在我们社区注册个新的帐号。非常简单!

注册新帐号

登入

已有帐号? 登入

现在登入
×
×
  • 新建...

重要消息

为使您更好地使用该站点,请仔细阅读以下内容: 使用条款