当我选择第二个输入框时,为什么音译不起作用?

时间:2018-04-18 06:10:38

标签: javascript jquery html vue.js

<div class="row" v-for="(book, index) in Subsequent" :key="index">
    <div class="col-md-8">
        <div class="form-group label-floating">
            <label class="control-label"> Details</label>
            <input type="text" class="form-control" v-model="book.seizuredetails" id="transliterateTextarea2">
        </div>
    </div>
</div>
<a @click="addNewRow">Add Another</a>
</div>

我在第一个输入框中进行音译。 (第一种情况没问题)

所以,当我在添加另一个时,我能够有一个新的输入框。但因为音译不起作用。

我的音译脚本是

  <script type="text/javascript">

      // Load the Google Transliterate API
      google.load("elements", "1", {
          packages: "transliteration"
      });

      function onLoad() {
          var options = {
              sourceLanguage: google.elements.transliteration.LanguageCode.ENGLISH,
              destinationLanguage: [google.elements.transliteration.LanguageCode.MALAYALAM],
              shortcutKey: 'ctrl+g',
              transliterationEnabled: true
          };

          // Create an instance on TransliterationControl with the required
          // options.
          var control = new google.elements.transliteration.TransliterationControl(options);

          // Enable transliteration in the textbox with id
          // 'transliterateTextarea'.
          var ids = [ "transliterateTextarea", "transliterateTextarea1", "transliterateTextarea2" ];
          control.makeTransliteratable(ids);
      }
      google.setOnLoadCallback(onLoad);
  </script>

因此,当点击添加另一个时,我如何能够为该输入区域提供新的音译ID。

请帮我解决。

1 个答案:

答案 0 :(得分:9)

基本上你会得到makeTransliteratable代码并将其放在一个方法中。之后,您可以在要进行音译的任何输入上调用此方法。

但是,有一些陷阱。

第一个是如何判断谷歌音译是否已加载。我在方法中使用了Promise(window.googleIsloaded)和await window.googleIsLoaded;,以确保它只在谷歌加载后执行

第二个问题更糟糕:当音译时,谷歌直接设置<input>的值,并且在执行此操作时不会发出任何事件。由于没有事件,Vue无法更新v-model属性。为了克服这个问题,我创建了一个Proxy来拦截对输入的任何调用,并在google直接设置值时发出输入事件,这允许Vue选择更改。缺点是Proxy API 在IE 中不可用。

JSFiddle demo here.

更新

好吧,我想出了一个解决方法,在所有IE版本的Vue支持中工作,并且还能够将其转换为 Vue custom directive

所以你要做的就是将v-transliterate="options"添加到<input><textarea>,作为options您的对象或属性,其中包含该特定{{1的音译的配置}} / <input>。例如:

<textarea>

Demo JSFiddle here.代码:

<input type="text" v-model="somevar" v-transliterate="options">
<script src="https://unpkg.com/vue"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script>
  // Load the Google Transliterate API
  google.load("elements", "1", {
    packages: "transliteration"
  });

  Vue.directive('transliterate', function (el, binding) {
      var control = new google.elements.transliteration.TransliterationControl(binding.value);
      // a getter for each property google transliterate reads and a setter for each it modifies
      var inputOrTextareaProxy = {
          get getAttribute() { return el.getAttribute.bind(el); },
          get addEventListener() { return el.addEventListener.bind(el); },
          get blur() { return el.blur.bind(el); },
          get focus() { return el.focus.bind(el); },
          get tagName() { return el.tagName; },
          get type() { return el.type; },
          get id() { return el.id; },
          get style() { return el.style; },
          get selectionStart() { return el.selectionStart; },
          get selectionEnd() { return el.selectionEnd; },
          get value() { return el.value; },
          set value(v) { el.value = v; el.dispatchEvent(new CustomEvent('input')); },
          get nodeType() { return el.nodeType; },
          get ownerDocument() { return el.ownerDocument; },
          get scrollTop() { return el.scrollTop; },
          set scrollTop(v) { el.scrollTop = v; }
      };
      control.makeTransliteratable([inputOrTextareaProxy]);
  });
</script>

<div id="app">
  <div class="row" v-for="(book, index) in Subsequent" :key="index">
    <div class="col-md-8">
      <div class="form-group label-floating">
        <label class="control-label"> Details</label>
        <input type="text" class="form-control" v-model="book.seizuredetails" v-transliterate="options"> (Type "World." with the dot!) {{ book.seizuredetails }}
      </div>
    </div>
  </div>
  <a @click="addNewRow">Add Another</a>
</div>