javascript - 基本 ES6 Javascript 插件 - 在函数之间重用变量

标签 javascript ecmascript-6

我正在尝试构建一个基本的 JS 插件,它可以在单击事件后调用以禁用按钮(以防止用户触发多个 API 调用)并提供正在加载/发生某些事情的反馈。这是它的样子:

enter image description here

这在个人基础上非常有效,但我想将它重新编写为一个插件,以便我可以在整个网站上重复使用它。

这是文件 loader.plugin.js 中 JS 的缩减版本。

let originalBtnText;


export function showBtnLoader(btn, loadingText) {
  const clickedBtn = btn;
  const spinner = document.createElement('div');

  spinner.classList.add('spin-loader');

  originalBtnText = clickedBtn.textContent;
  clickedBtn.textContent = loadingText;
  clickedBtn.appendChild(spinner);
  clickedBtn.setAttribute('disabled', true);
  clickedBtn.classList.add('loading');

  return this;
}


export function hideBtnLoader(btn) {
  const clickedBtn = btn.target;
  clickedBtn.textContent = originalBtnText;
  clickedBtn.removeAttribute('disabled');
  clickedBtn.classList.remove('loading');

  return this;
}


export function btnLoader() {
  showBtnLoader();
  hideBtnLoader();
}

这是我想如何使用它的示例。

import btnLoader from 'loaderPlugin';

const signupBtn = document.getElementById('signup-btn');

signupBtn.addEventListener('click', function(e) {
  e.preventDefault();
  btnLoader.showBtnLoader(signupBtn, 'Validating');
  // Call API here
});

// Following API response
hideBtnLoader(signupBtn);

我遇到的问题是我想存储 showBtnLoader 函数中的 originalBtnText,然后在 hideBtnLoader 函数中使用该变量。我当然可以通过不同的方式实现这一点(例如将值添加为数据属性并稍后获取它)但我想知道是否有一种简单的方法。

我遇到的另一个问题是我不知道调用每个单独函数的正确方法以及我是否正确导入它。我尝试了以下方法。

btnLoader.showBtnLoader(signupBtn, 'Validating');
btnLoader(showBtnLoader(signupBtn, 'Validating'));
showBtnLoader(signupBtn, 'Validating');

但是我得到以下错误:

Uncaught ReferenceError: showBtnLoader is not defined
    at HTMLButtonElement.<anonymous>

我已经阅读了一些不错的文章和 SO 答案,例如 http://2ality.com/2014/09/es6-modules-final.htmlES6 export default with multiple functions referring to each other但我对这样做以使其可重用的“正确”方法有些困惑。

如有任何指点,我们将不胜感激。

最佳答案

我将导出一个函数来创建一个同时具有显示和隐藏函数的对象,如下所示:

export default function(btn, loadingText) {

  function show() {
    const clickedBtn = btn;
    const spinner = document.createElement('div');

    spinner.classList.add('spin-loader');

    originalBtnText = clickedBtn.textContent;
    clickedBtn.textContent = loadingText;
    clickedBtn.appendChild(spinner);
    clickedBtn.setAttribute('disabled', true);
    clickedBtn.classList.add('loading');
  }

  function hide() {
    const clickedBtn = btn.target;
    clickedBtn.textContent = originalBtnText;
    clickedBtn.removeAttribute('disabled');
    clickedBtn.classList.remove('loading');
  }

  return {
    show,
    hide,
  };
}

然后,使用它:

import btnLoader from 'btnloader';

const signupBtn = document.getElementById('signup-btn');
const signupLoader = btnLoader( signupBtn, 'Validating' );

signupBtn.addEventListener('click', function(e) {
  e.preventDefault();
  signupLoader.show();
  // Call API here
});

// Following API response
signupLoader.hide();

如果您需要将它隐藏在与您显示它的位置不同的文件中,那么您可以导出该实例:

export const signupLoader = btnLoader( signupBtn, 'Validating' );

然后导入它。

import { signupLoader } from 'signupform';

function handleApi() {
    signupLoader.hide();
}

关于javascript - 基本 ES6 Javascript 插件 - 在函数之间重用变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44074399/

相关文章:

javascript - react typescript |事件处理程序 Prop 的正确类型

javascript - React - 当 Prop 通过父状态更新时,子组件不会更新

javascript - ReactJS onClick 参数没有传递给父组件

javascript - 以编程方式下载未出现在页面源代码中的文本

javascript - 为什么我们使用原型(prototype)

javascript - 检查电子邮件在 Google Apps 脚本中是否有效

javascript - Node.js 中的 REPL 驱动开发

javascript - Mocha with Blanket、Babel 和 LCOV 记者

javascript - 简单客户端应用程序中的文件处理

javascript - 如何结合使用 anchor 标记和routeParams通过ID获取JSON