无法从函数中调用removeEventListener

时间:2018-02-22 21:18:34

标签: javascript event-handling

我在下面有以下功能,我想存储与UI行为相关的所有EventListener。

我目前能够毫无问题地添加新事件但我无法删除它们,因为对函数的引用完全丢失了。

我相信我可能不得不使用.bind(this)或handleEvent,但我无法弄清楚如果不从头开始我写的内容是不是无法达到这样的目标。

基本上我会像这样调用函数,如果可能的话,我希望保持这种方式:

addEventListener:getUIbehaviour('scroll-hide-commentbox', 'add');

removeEventListener:getUIbehaviour('scroll-hide-commentbox', 'remove');

感谢您的帮助,

const pathfinder = (obj, path) =>
{
  let current=obj;
  path.split('.').forEach(function(p){ current = current[p]; });
  return current;
};


const getUIbehaviour = (type, action) =>
{

 let behaviours =
{
    'classic-product-search':
    {
        behaviour: function()
        {

            if (window.GLOBAL.agent === 'Desktop')
            {
                document.querySelector('#product-search').focus();
                window.scroll({top: 0, left: 0, behavior: 'smooth' });
                document.querySelector('#product-search').value = '';
            }
            else if(window.GLOBAL.agent === 'Mobile') /* hide #products-ui on #product-search focus */
            {
                document.querySelector('#product-search').focus();
                document.querySelector('#products-ui').setAttribute('class', 'list noselect hidden');
                window.scroll({top: 0, left: 0, behavior: 'smooth' });
                document.querySelector('#product-search').value = '';
            }

        },

        add : function()
        {
            document.querySelector('#product-search').addEventListener('focusin', this.behaviour, false);
        },

        remove : function()
        {
            document.querySelector('#product-search').removeEventListener('focusin', this.behaviour, false);
        }

    },

    'scroll-hide-commentbox':
    {
        behaviour: function ()
        {

    console.log('scrolling');

            let commentbox = document.querySelector('#comments');

            if (commentbox != null)
            {
                commentbox.setAttribute('class', 'hidden');
            }

            if (document.documentElement.scrollTop === 0 && window.GLOBAL.agent === 'Desktop' && commentbox != null)
            {
                commentbox.setAttribute('class', 'block');
            }
            else if (window.pageYOffset === 0 && window.GLOBAL.agent === 'Mobile' && commentbox != null)
            {
                commentbox.setAttribute('class', 'block');
            }

        },

        add : function()
        {
         document.addEventListener('scroll', this.behaviour, false);
        },

        remove : function()
        {
         document.removeEventListener('scroll', this.behaviour, false);
        }
    }

};

 let behaviour = pathfinder(behaviours, type);

 if (action ==='add')
 {
   return behaviour.add();
 }
 else if (action ==='remove')
 {
   return behaviour.remove();
 }

 };

2 个答案:

答案 0 :(得分:1)

您应该做的是从函数behaviours移出对象getUIbehaviour

问题是每当你调用getUIbehaviour函数时它会创建新的behaviours对象

当前版本:

    const pathfinder = (obj, path) => {}; 
    const getUIbehaviour = (type, action) => {
      // Move out from scope
      let behaviours = {};
    };

正常工作版本:

    const pathfinder = (obj, path) => {};
    let behaviours = {}; 
    const getUIbehaviour = (type, action) => {};

这是一个链接https://gist.github.com/andrey-ponamarev/392ee55337c3716ff3a55177289bdb7e

答案 1 :(得分:0)

在您的情况下,快速替代方法是将behaviour移动到命名函数中,如下所示:

const pathfinder = (obj, path) => {
    let current=obj;
    path.split('.').forEach(function(p){ current = current[p]; });
    return current;
};


const getUIbehaviour = (type, action) => {

    function classicProductSearchBehavior() {
        if (window.GLOBAL.agent === 'Desktop') {
            document.querySelector('#product-search').focus();
            window.scroll({top: 0, left: 0, behavior: 'smooth' });
            document.querySelector('#product-search').value = '';
        } else if(window.GLOBAL.agent === 'Mobile') /* hide #products-ui on #product-search focus */ {
            document.querySelector('#product-search').focus();
            document.querySelector('#products-ui').setAttribute('class', 'list noselect hidden');
            window.scroll({top: 0, left: 0, behavior: 'smooth' });
            document.querySelector('#product-search').value = '';
        }
    }

    function showHideCommentbox() {
        console.log('scrolling');

        let commentbox = document.querySelector('#comments');

        if (commentbox != null) {
            commentbox.setAttribute('class', 'hidden');
        }

        if (document.documentElement.scrollTop === 0 && window.GLOBAL.agent === 'Desktop' && commentbox != null) {
            commentbox.setAttribute('class', 'block');
        } else if (window.pageYOffset === 0 && window.GLOBAL.agent === 'Mobile' && commentbox != null) {
            commentbox.setAttribute('class', 'block');
        }
    }

    let behaviours = {
        'classic-product-search': {
            behaviour: classicProductSearchBehavior,
            add: function() {
                document.querySelector('#product-search').addEventListener('focusin', classicProductSearchBehavior, false);
            },
            remove : function() {
                document.querySelector('#product-search').removeEventListener('focusin', classicProductSearchBehavior, false);
            }
        },

        'scroll-hide-commentbox': {
            behaviour: showHideCommentbox,
            add : function() {
                document.addEventListener('scroll', showHideCommentbox, false);
            },
            remove : function() {
                document.removeEventListener('scroll', showHideCommentbox, false);
            }
        }
    };

    let behaviour = pathfinder(behaviours, type);

    if (action ==='add') {
        return behaviour.add();
    } else if (action ==='remove') {
        return behaviour.remove();
    }
};