JQuery创建的一个Wizard组建

369 阅读2分钟

这是小弟的第一次在掘金上发表文章,技术能力有限要喷请轻点喷。。。。。(尬。。。) 最近接触一个老项目,用的Jquery, 需要写个向导插件 于是结合了自己的想法用Jquery 实现了一下

组件样例

代码

// 公用流程组件
(function ($) {
  $.fn.CommonWizard = function (options) {
    /*当没有这个元素或者不是DIV的时候返回*/
    if (this.length !== 1 || this.prop('tagName') !== 'DIV') {
      return;
    }

    const params = $.extend({}, $.fn.CommonWizard.defaults, options);
    //控制跳转的 初始化的时候为true
    params.canJumpToNext = true;

    this.empty();

    this.append(
      `
      <div class="wizard">
        
        <div class="wizard-content">
          <iframe src="${params.contentList[0]}" frameborder="0" scrolling="no"></iframe>
        </div>
        <div class="wizard-footer">
          <div class="pre">
            <button class="btn btn-info pre-btn" >上一步</button>
          </div>
          <div class="next">
            <button class="btn btn-success save-btn">保存</button>
            <button class="btn btn-info next-btn">下一步</button>
          </div>
        </div>
      </div>
      `
    );

    const $wizard = this.find('.wizard');
    const $preBtn = $wizard.find('.pre-btn');
    const $nextBtn = $wizard.find('.next-btn');
    // 开始就隐藏上一步按钮
    $preBtn.hide();
    let tabIndex = 1;

    //检查状态
    const checkWizardBtnState = (tabIndex) => {
      $preBtn.show();
      $nextBtn.show();

      if (tabIndex === 1) {
        $preBtn.hide();
      }

      if (tabIndex === params.titles.length) {
        $nextBtn.hide();
      }
    };

    this.init = function () {
      // $loading.hide();
      renderContent(0);
      renderWizardLi(params.titles, params.type);
    };

    this.next = function () {
      params.canJumpToNext = true;
    };

    /* 渲染head */
    const renderWizardLi = (titles, type) => {
      if (type === 'big') {
        const $wizardUl = $(`<ul class="bwizard-ul"></ul>`);

        $wizardUl.prependTo($wizard);
        $.each(titles, function (index, item) {
          $(
            `
            <li class="item ${index === 0 && 'active'}">
              <div class="text">
                <div><span class="iconfont ${params.icons[index]}" ></span></div>
                <div>${index + 1}${item}</div> 
              </div>
            </li>
          `
          ).appendTo($wizardUl);
        });
      } else {
        const $wizardUl = $(`<ul class="wizard-ul"></ul>`);
        $wizardUl.prependTo($wizard);
        $.each(titles, function (index, item) {
          $(
            `
            <li class="item ${index === 0 && 'active'}">
              <div class="text" data-text="${item}">${index + 1}</div>
            </li>
          `
          ).appendTo($wizardUl);
        });
      }
    };

    // 在切换Iframe 之前
    const beforeChangeIframe = () => {
      const iframeWindow = $wizard.find('iframe').get(0).contentWindow.window;
      const iframeUrl = $wizard.find('iframe').attr('src');
      params.beforeChangeIframe && params.beforeChangeIframe(iframeUrl, iframeWindow);
    };

    /* 切换渲染的内容 */
    const renderContent = (index) => {
      params.canJumpToNext && $wizard.find('iframe').attr('src', params.contentList[index]);
    };

    this.init();

    /* ================================事件绑定============================================ */
    $wizard.find('.text').click(function (e) {
      e.stopPropagation();
      e.preventDefault();

      // 切换iframe 之前
      beforeChangeIframe();

      //如果不能跳转 一下都不执行
      if (!params.canJumpToNext) {
        return;
      }
      //计算处于哪个tab
      tabIndex = $(this).parent().prevAll().length + 1;

      $wizard.find('.item').each(function (index, item) {
        $(item).removeClass('active');
      });
      $(this).parent().addClass('active').prevAll().addClass('active');
      //监测按钮状态
      checkWizardBtnState(tabIndex);
      renderContent(tabIndex - 1);
    });

    $wizard.find('.pre-btn').click(function (e) {
      e.stopPropagation();
      e.preventDefault();

      // 切换iframe 之前
      beforeChangeIframe();

      //如果不能跳转 一下都不执行
      if (!params.canJumpToNext) {
        return;
      }

      $wizard
        .find('.item')
        .eq(tabIndex - 1)
        .removeClass('active');

      tabIndex -= 1;
      checkWizardBtnState(tabIndex);
      renderContent(tabIndex - 1);
    });

    $wizard.find('.next-btn').click(function (e) {
      e.stopPropagation();
      e.preventDefault();

      // 切换iframe 之前
      beforeChangeIframe();

      //如果不能跳转 一下都不执行
      if (!params.canJumpToNext) {
        return;
      }
      $wizard.find('.item').eq(tabIndex).addClass('active');

      tabIndex += 1;
      checkWizardBtnState(tabIndex);
      renderContent(tabIndex - 1);
    });

    $wizard.find('iframe').on('load', function () {
      const iframeWindow = $wizard.find('iframe').get(0).contentWindow.window;
      const iframeUrl = $wizard.find('iframe').attr('src');
      params.renderIframe && params.renderIframe(iframeUrl, iframeWindow);
      // 跳转后 重置为false 控制一下次跳转
      params.canJumpToNext = false;
    });

    return this;
  };

  $.fn.CommonWizard.defaults = {};
})(jQuery);

代码思路

  • 1.外层DIV
  • 2.里面嵌入iFrame

备注

  • 1.添加了next方法来控制是否可以进入下一步
  • 2.渲染iframe的时候因为有渲染时间,所以绑定了onload事件 , 每次在回填数据的时候 需要调用settimeout
  • 3.写了2个钩子函数 检测生命周期 renderIframe 渲染, beforeChangeIframe渲染之前
  • 4.调用iframeWindow 来操作里面的子页面 iframeUrl来判断Iframe的连接地址

使用如下

CommonWizard = $body.find('#Wizard').CommonWizard({
      titles: ['基本信息', '操作列表'],
      contentList: ['url1', 'url2'],
      renderIframe: function (url, window) {
        iframeWindow = window;
        iframeUrl = url;
        // 每次渲染页面都在回填
        if (iframeUrl === 'url1') {
          setTimeout(function () {
            iframeWindow.feedData();
          }, 100);
        }

        if (iframeUrl === 'url2') {
          setTimeout(function () {
            iframeWindow.feedData();
          }, 100);
        }
      },
      beforeChangeIframe: function () {
        // 刚开始载入的时候 是没有Iframe和iframeWindows的
        if (!iframeUrl || !iframeWindow) {
          return;
        }

        if (iframeUrl === 'url1') {
          basicData = iframeWindow.getFormData();
          if (!basicData) {
            return;
          }
          CommonWizard.next();
        }

        if (iframeUrl === 'url2') {
          CommonWizard.next();
        }
      },
    });

    //添加取消按钮
    $(`<button class="btn btn-danger cancel-btn" style="">取消</button>`).appendTo($body.find('.next'));
  };