幽月零 发布于七月 17 分享 发布于七月 17 (已修改) 光看標題可能會有點抽象。先說起因,最近看到了這個帖子,https://sstm.moe/topic/358822-不用打开检查界面就通过外链插入音视频控件的脚本直接获取全民k歌电脑网页音频源文件的脚本(基于tampermonkey插件)/,所以去找了下可以準確地將元素插入到相應的編輯框的方法,然後就發現了這個 首先看下圖,隨便找個回覆點修改,可以看到在 CKEDITOR.instances 中有兩個object,帶有id的是最底下新回覆的,先不用管它。comment_value 則是修改回覆用的編輯框。 這時候在"其他媒體" >> "插入外部圖片"中輸入鏈接可以正常插入圖片,到這裡都沒有問題。 但假如在保持之前的修改編輯器存在的情況下再打開另一個,可以看到CKEDITOR.instances 中仍然只有兩個object 這時在任意的修改框裡插入圖片,圖都會出現在最後打開的那一個裡面 問題講完了,再說說原因,首先可以看到這個編輯框是基於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, ' '); if (!title) { title = decodeURI(url); } title = title.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); 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身上也可以拿到 順便再吐槽一下論壇的附件,我忍這東西很久了。直接點擊進行下載的時候不會指定文件名稱(明明在頁面上就有顯示文件名)。而且有些類型的文件不會直接下載,而是會跳轉到新頁面直接顯示(就算加了download attribute也不行。瀏覽器基於安全性的考慮,只有來自同一個來源的時候它才會生效) 七月 17,由幽月零修改 1 链接到点评
推荐贴
创建帐号或登入才能点评
您必须成为用户才能点评
创建帐号
在我们社区注册个新的帐号。非常简单!
注册新帐号登入
已有帐号? 登入
现在登入