我使用MutationObserver
将观察者放置在元素上。在一个用例中,它的工作原理与预期的一样,并在更改后触发,但在元素未更改的另一个用户操作中,它似乎正在触发-但这样做会导致方法未找到错误,但不会使用相同的观察者出现在第一个用例中。
观察者在元素内更新,当用户选择图像时,该更新会随图像更新。
在工作情况下,用户从图像列表中选择一个图像,然后更新并由观察者触发-一切都很好。在不工作的情况下,用户上传图像-尽管此时目标元素(处于可见状态但在颜色框下方)尚未发生任何更新(不确定是否相关)。
触发本身通常不会有问题,但是在观察者回调中,它会调用一个方法,在第二种情况下它未定义。因此,在第一种情况下没有错误,但在第二种情况下:
我收到错误_this.buttons is not a function at MutationObserver.callback
正在使用webpack编译代码
任何帮助表示感谢
这是代码-此类管理页面的动作-我删除了一些代码以使其简短(但仍然有些冗长-进行重构):
首先,这是观察者的代码:
,其中包含观察者方法。const callback = (mutationsList, observer) =>{ // Use traditional 'for loops' for IE 11 for(let mutation of mutationsList) { if (mutation.type === 'childList') { console.log('A child node has been added or removed.'); module.buttons(); module.initialiseControls(); } else if (mutation.type === 'attributes') { console.log('The ' + mutation.attributeName + ' attribute was modified.'); } } };
这里是类
export let fileImageWidgetControls = class { constructor({ previewBtn = '.preview-image', addBtn = '#add-image', replaceBtn = '#replace-image', removeBtn = '#remove-image' } = {}) { this.options = { previewBtn: previewBtn, addBtn: addBtn, replaceBtn: replaceBtn, removeBtn: removeBtn } this.filemanager = new filemanagerHandler; //file selector class this.imageWidget = new updateWidget; //handles updating the image this.initialiseControls(); //sets up the page controls this.observer(); //sets up the observer } openFileManager = () =>{ //open colbox (which opens filemanager page //When filemanager loaded then initialise filemanager $(document).bind('cbox_complete', ()=>{ console.log('Colbox complete'); this.filemanager.init(); }); //handle colbox closing and update image in widget (if needed) $(document).bind('cbox_closed', ()=>{ let selectedAsset = this.filemanager.getSelectedAsset(); if(selectedAsset) { this.imageWidget.update(selectedAsset.filename); } }); colBox.init({ href: this.options.serverURL }); colBox.colorbox() } remove = ()=> { //clear file and update visible buttons this.buttons(); } /** * preview the image in a colorbox * @param filename */ preview = function () { //open image in preview } /** * select image via filemanager */ select = () =>{ console.log('select'); this.openFileManager(); } replace = () => { // image already exists in widget but needs replacing console.log('replace'); this.openFileManager(); } initialiseControls = () => { console.log('init controls'); //preview button $(this.options.previewBtn).on('click', (e) => { e.preventDefault(); this.preview(); }).attr('disabled', false); $('#img-preview-link').on('click', (e)=> { e.preventDefault(); this.preview(); }); // add button $(this.options.addBtn).on('click', (e) => { e.preventDefault(); this.select(); }).attr('disabled', false); //replace button $(this.options.replaceBtn).on('click', (e) => { e.preventDefault(); this.replace(); }).attr('disabled', false); //remove button $(this.options.removeBtn).on('click', (e) => { e.preventDefault(); this.remove(); }).attr('disabled', false); this.buttons(); } //set an observer to watch preview image for changes observer= ()=> { const module = this; const targetNode = document.getElementById('image-preview-panel'); const config = { attributes: true, childList: true, subtree: true }; const callback = (mutationsList, observer) =>{ // Use traditional 'for loops' for IE 11 for(let mutation of mutationsList) { if (mutation.type === 'childList') { console.log('A child node has been added or removed.'); module.buttons(); module.initialiseControls(); } else if (mutation.type === 'attributes') { console.log('The ' + mutation.attributeName + ' attribute was modified.'); } } }; const observer = new MutationObserver(callback); observer.observe(targetNode, config); } buttons = function() { let imagePreview = $('#image-preview'); if(imagePreview.data('updated')=== true && imagePreview.data('updated') !== "false") { console.log('image present'); $(this.options.addBtn).fadeOut().attr('disabled', true); $(this.options.removeBtn).fadeIn().attr('disabled', false); $(this.options.replaceBtn).fadeIn().attr('disabled', false); $(this.options.previewBtn).fadeIn().attr('disabled', false); } else { console.log('image not present', imagePreview.data()); console.log('image element:', imagePreview); $(this.options.addBtn).fadeIn().attr('disabled', false); $(this.options.removeBtn).fadeOut().attr('disabled', true); $(this.options.replaceBtn).fadeOut().attr('disabled', true); $(this.options.previewBtn).fadeOut().attr('disabled', true); } } }
我从教程中复制了代码,因此在重构之前有一些注释
我已经使用MutationObserver在一个元素上放置了一个观察者。在一个用例中,它可以完全按预期工作,并在更改后触发,但在元素未更改的情况下,在另一用户操作中触发...