jQuery 插件仅在 Firefox 中不适用于 Aurelia

jQuery plugin not working with Aurelia in Firefox only

我已经启动了一个 Aurelia 项目并且我选择使用 this plugin to enable input masking for phone numbers using an implementation similar to that seen in this post

它在 Chrome 和 Safari 中运行良好 - 然而,它在 Firefox 中显然不起作用。没有错误或其他有用的信息。然而,上面链接的演示页面上的示例工作得很好,所以我确定它一定与我的实现有关:

JS:

import {inject, NewInstance} from 'aurelia-dependency-injection';
import {ValidationController, ValidationRules, validateTrigger} from 'aurelia-validation';
import 'igorescobar/jQuery-Mask-Plugin'

@inject(NewInstance.of(ValidationController))

export class MyForm {
  async activate(params, routeConfig) {
    // do stuff if there are route parameters
  }

  bind() {
    $('#PhoneNumber').mask('(000) 000-0000');
  }

  constructor(controller) {
    this.controller = controller;
    this.controller.validateTrigger = validateTrigger.manual;
  }

  submit() {
    this.controller.validate()
      .then(errors => {
        if (errors.length === 0) {
          // do a thing
        } else {
          // do something else
        }
      });
  }
}

ValidationRules
  .ensure('phoneNumber').displayName('Phone number')
  .minLength(10).withMessage('Phone number must be at least 10 characters')
  .maxLength(14).withMessage('Phone number is too long')
  .matches(/[(][0-9]{3}[)] [0-9]{3}-[0-9]{4}/).withMessage('Please provide a valid phone number')
  .on(MyForm);

HTML

<input class="form-control" id="PhoneNumber" type="tel" minlength="10" maxlength="14" pattern="[(][0-9]{3}[)] [0-9]{3}-[0-9]{4}" value.bind="phoneNumber & validate" required="required">

我试过删除 pattern 属性并将其更改为常规文本输入,但无济于事。我真的在这个问题上挠头。任何想法或建议将不胜感激。

您可以在 attached() 事件(在 html-渲染之后)上使用 jquery 命令,而不是在 bind() 上。试试看:

attached() {
  $('#PhoneNumber').mask('(000) 000-0000');
}

我和 Jan 一起工作 - 我们从来没有按照原始问题的编码方式让它在 Firefox 中工作。

我们最终用 jquery.inputmask 替换了它,因为我们 运行 遇到了与 jquery.mask('igorescobar/jQuery-Mask-Plugin').

的兼容性问题

这是让它起作用的粘合剂(基于 Two-Way binding in an Aurelia Custom Attribute):

输入-mask.js

import {inject, customAttribute, bindable, bindingMode} from 'aurelia-framework';
import 'jquery.inputmask';
import 'jquery.inputmask.numeric';

@customAttribute('input-mask')
@inject(Element)
export class InputMaskCustomAttribute {

  @bindable({defaultBindingMode: bindingMode.twoWay}) unmaskedValue;

  @bindable maskOptions;

  element;

  isValidInputElement;
  // The maskedinput jquery pluggin does not allow the events that aurelia needs
  // for binding to get through.  So we will manually put them through.
  // This is the list of events we are going to look for.  "focusout" allows for the value
  // to be correct intime for "onblur".
  aureliaBindEvents = 'focusout';
  eventTarget = undefined;

  constructor(element) {
    if (element instanceof HTMLInputElement) {
      this.element = element;
      this.isValidInputElement = true;
      this.eventTarget = $(this.element);
    } else {
      this.isValidInputElement = false;
    }
  }

  bind() {
    this.element.value = this.unmaskedValue;
  }

  attached() {
    this.setupMask();
  }

  detached() {
    this.tearDownMask();
  }

  maskOptionsChanged(newValue, oldValue) {
    this.tearDownMask();
    this.setupMask();
  }

  setupMask(mask) {
    if (this.isValidInputElement && this.maskOptions) {
      this.eventTarget.inputmask(this.maskOptions);
      this.eventTarget.on(this.aureliaBindEvents, (e) => {
        this.unmaskedValue = this.eventTarget.inputmask('unmaskedvalue');
        this.fireEvent(e.target, 'input');
      });
    }
  }

  tearDownMask() {
    if (this.isValidInputElement) {
      if (this.eventTarget) {
        this.eventTarget.off(this.aureliaBindEvents);
        this.eventTarget.inputmask('remove');
      }
    }
  }

  createEvent(name: string) {
    let event = document.createEvent('Event');
    event.initEvent(name, true, true);
    return event;
  }

  fireEvent(element: HTMLElement, name: string) {
    var event = this.createEvent(name);
    element.dispatchEvent(event);
  }

}

widget.html

<require from="input-mask"></require>
<input class="form-control" type="text" maxlength="12" 
  input-mask="mask-options.bind: {alias: 'currency', rightAlign: false, allowMinus:false, allowPlus: false}; unmasked-value.bind: target['monthly-payment'] & validate" />