Запуск mutationobserver при отсутствии изменений и не найденном методе - PullRequest
0 голосов
/ 06 мая 2020

Я поместил наблюдателя на элемент, используя MutationObserver. В одном случае использования он работает точно так, как ожидалось, и срабатывает после изменения, но в другом действии пользователя, когда элемент не изменился, он, похоже, запускается, но при этом возникает ошибка метода не найден, который не появляются в первом варианте использования с использованием того же наблюдателя.

Наблюдатель наблюдает за обновлением в элементе, который обновляется изображением, когда пользователь выбирает изображение.

В рабочем случае a Пользователь выбирает изображение из списка изображений, затем оно обновляется, и наблюдатель запускает - все отлично. В нерабочем случае пользователь загружает изображение - на данный момент, хотя не произошло никакого обновления целевого элемента (который находится в поле зрения, но ниже цветовой рамки. (Не уверен, актуально ли это).

сам по себе обычно не был бы проблемой, но в обратном вызове наблюдателя он вызывает метод, который во втором случае, как он говорит, не определен. Итак, в первом случае ошибок нет, но во втором случае:

Я получаю ошибка _this.buttons is not a function at MutationObserver.callback

Код компилируется с помощью webpack

  1. 1. Почему наблюдатель запускает , когда не отображается тип наблюдается изменение?
  2. Почему эта ошибка возникает в этом сценарии - когда метод существует и работает должным образом при изменении?

Любая помощь приветствуется

вот код - этот класс управляет действиями для страницы - я удалил код, чтобы попытаться сделать его кратким (но все же немного длинным - необходимо провести рефакторинг):

* 1 028 * Во-первых, вот код наблюдателя:
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);
        }
    }
}

Я скопировал код из учебника, отсюда и некоторые комментарии, пока не проведу рефакторинг

1 Ответ

0 голосов
/ 13 мая 2020

Добавлено const module = this; within the method and referenced that within the nested function and now pointing to the correct this`

...