mutationobserver在没有更改和方法未找到时触发]]

问题描述 投票:0回答:1

我使用MutationObserver将观察者放置在元素上。在一个用例中,它的工作原理与预期的一样,并在更改后触发,但在元素未更改的另一个用户操作中,它似乎正在触发-但这样做会导致方法未找到错误,但不会使用相同的观察者出现在第一个用例中。

观察者在元素内更新,当用户选择图像时,该更新会随图像更新。

在工作情况下,用户从图像列表中选择一个图像,然后更新并由观察者触发-一切都很好。在不工作的情况下,用户上传图像-尽管此时目标元素(处于可见状态但在颜色框下方)尚未发生任何更新(不确定是否相关)。

触发本身通常不会有问题,但是在观察者回调中,它会调用一个方法,在第二种情况下它未定义。因此,在第一种情况下没有错误,但在第二种情况下:

我收到错误_this.buttons is not a function at MutationObserver.callback

正在使用webpack编译代码

  1. 1。为什么观察者会触发,而观察到的变化类型却没有出现?
  2. 为什么在这种情况下会发生此错误
  3. -当方法似乎存在并且在发生更改时可以按预期工作吗?

    任何帮助表示感谢

这是代码-此类管理页面的动作-我删除了一些代码以使其简短(但仍然有些冗长-进行重构):

首先,这是观察者的代码:

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在一个元素上放置了一个观察者。在一个用例中,它可以完全按预期工作,并在更改后触发,但在元素未更改的情况下,在另一用户操作中触发...

javascript mutation-observers
1个回答
0
投票
© www.soinside.com 2019 - 2024. All rights reserved.