ES6类中的jQuery触发器无效

时间:2017-09-22 10:01:38

标签: javascript jquery webpack ecmascript-6

我在ES6类中使用了jQuery触发器。我无法弄清楚为什么这个触发器不起作用。

这是我的班级。触发器应该在调用triggerFilter方法时执行。

// vendor import
import $ from 'jquery';

export default class SortingBar {
    constructor() {
        this.element = '[data-sortingBar]';
        this.sortOption = $(this.element).find('.sorting-bar__item');
        this.sortType = '';
        this.sortTypeInput = $(this.element).find('[name="sortType"]');
        this.init();
    }

    init() {
        // early exit
        if ($(this.element).length === 0) {
            return false;
        }

        // trigger filter on sort option click
        this.sortOption.on('click', (e) => {
            this.triggerFilter(e.currentTarget);
        });
    }

    triggerFilter(element) {
        // avoid filter trigger for active sort option
        if ($(element).hasClass('active')) {
            return false;
        }

        // set sort option value for hidden input
        this._setSortTypeInputValue(element);

        // trigger filter change
        this.sortTypeInput.trigger('change');
    }

    _getSortType(element) {
        this.sortType = $(element).data('sort-type');
        return this.sortType;
    }

    _setSortTypeInputValue(element) {
        this.sortTypeInput.val(this._getSortType(element));
    }
}

此模块将像这样

导入主文件中

// modules import
import Overlay from './modules/overlay';
import SortingBar from './modules/sorting-bar';

// modules init
const overlay = new Overlay();
const sortingBar = new SortingBar();


// modules object
const modules = {
    overlay,
    sortingBar
};

// modules object default export
export default {
    modules
};

还有一个旧的filter.js文件,其中更改事件绑定到应该触发的隐藏输入。该文件将在main.js文件之前加载。

$('[name=selectWrapper], [name=sortType], [data-filters=reset]').on('change', refreshByChange);

我使用webpack和babel-loader将文件编译为ES5。这是我的Webpack配置。

// require
const path = require('path');
const webpack = require('webpack');

// check node enviroment
const nodeEnv = process.env.NODE_ENV || 'development';
const isProd = (nodeEnv.trim() === 'production');

// default config settings
const config = {
    entry: {
        desktop: './src/main/js/thymeleaf_desktop/main_desktop.js'
        // mobile: './src/main/js/thymeleaf_phone/main_mobile.js'
    },
    output: {
        filename: 'main_[name].js',
        path: path.resolve(__dirname, 'target/classes/js/thymeleaf_desktop')
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader?cacheDirectory=true',
                    options: {
                        presets: ['es2015']
                    }
                }
            }
        ]
    },
    plugins: [],
    devtool: 'inline-source-map'
};

// production config settings
if (isProd) {
    // eslint config settings
    const eslintConfig = {
        enforce: 'pre',
        test: /\.js$/,
        exclude: /(node_modules|_externals|standalone)/,
        loader: 'eslint-loader',
        options: {
            configFile: path.resolve(__dirname, './src/build/eslint/webpack/.eslintrc')
        }
    };

    config.devtool = false;
    config.module.rules.push(eslintConfig);
    config.output.filename = 'main_[name].min.js';
    config.plugins.push(
        new webpack.optimize.UglifyJsPlugin()
    );
}

module.exports = config;

奇怪的是,当我把触发器放在main.js文件中时,一切正常。

ES6类中是否存在jQuery触发器的已知问题?

2 个答案:

答案 0 :(得分:1)

我通过将jQuery触发器更改为本机Javascript解决了这个问题。

从:

this.sortTypeInput.trigger('change');

为:

const event = new Event('change'); document.getElementById('sortType').dispatchEvent(event);

我不知道为什么jQuery触发器不起作用。

答案 1 :(得分:1)

根据评论,问题是使用了两个jQuery实例。

jQuery2130225834388266846541告诉您jQuery版本2.3.1(整数的前三位,其他数字是实例的唯一ID)用于注册事件监听器。 / p>

import $ from 'jquery';最有可能包含节点模块版本(3.2.1

jQuery中的事件触发不使用本机事件,而是使用自己的事件处理。您只能侦听由用于注册偶数侦听器的jQuery相同实例触发的事件(即使它是相同的jQuery版本),因此您必须确保只使用一个jQuery实例。

这不仅是事件处理的情况,也是.data()的情况,因为jQuery的每个实例都为数据甚至是侦听器创建了一个自己的隔离存储。这不仅会导致像给定的问题,还会导致内存泄漏。