【问题标题】:Replace Function words for 1 text fields but, not working on multiple fields替换 1 个文本字段的功能词,但不适用于多个字段
【发布时间】:2021-01-01 15:05:38
【问题描述】:

我有一个替换函数,它将字符串或单个单词与定义的输入值匹配,并针对它输出一个指定的单词。

我设计函数的方式只允许它与页面上的单个输入和单个输出文本区域一起工作,我不能应用多个函数,因此来自 1 个输入字段的输入由不同的函数处理并显示在不同的输出文本区域字段。

代码如下:

HTML:

<input id="input_1" class="text-area-main input_mainn" type="text" placeholder="Input Goes Here" oninput="funcinput1()"> //input

<textarea id="output_1" class="text-area-main"></textarea> //output 1
<textarea id="output_2" class="text-area-main"></textarea> //output

JS:

function funcinput1() {
    let translator = {
        "a quick brown fox jumps over a lazy dog": "a fast brown fox jumps ovew a wazy good boy",
        "Hello there":"Ello There",
        "n":"\ud83d\udc68\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c\udffd"
    };
    
    var input = document.querySelector("#input_1");
    var output = document.querySelector("#output_1");

    input.addEventListener("input", () => {
        let text = input.value;
        let translated = translator[text];
        if (!translated) {
            let words = input.value.split(" ");
            translated = words.map(word => translator[word] || word).join(" ");
        }
        output.value = translated;
    });
  };

我知道我在输入字段上应用函数而不是在输出文本区域上做错了,但是我不知道如何使整个场景工作。

简而言之,输入将来自单个输入字段,但可以有多个输出文本区域,每个区域都会根据附加的功能进行处理。

例子:

输入是:“你好”

输出 1 可以是:“Ello There”

输出 2 可以是:“你好”

每个输入最多可以包含 10 或 20 个字段和 20 个不同的功能,但在同一页面上。

我仍在学习,不知道如何以最好的方式做到这一点。

【问题讨论】:

    标签: javascript


    【解决方案1】:

    您可以为每个输出文本区域提供翻译词典。

    在输入时,您可以重用该函数,根据输出区域的id 键和字典中的键进行翻译。

    考虑下面的例子,它可以很容易地扩展到n 输出区域的数量-

    const translator = {
      "output_1": {
        "a quick brown fox jumps over a lazy dog": "a fast brown fox jumps ovew a wazy good boy",
        "Hello there": "Ello There",
        "n": "\ud83d\udc68\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c\udffd"
      },
      "output_2": {
        "a quick brown fox jumps over a lazy dog": "new fox",
        "Hello there": "Hey There",
        "n": "no"
      }
    };
    
    document.querySelector("#input_1").addEventListener("input", (e) => {
      for (const output of Object.keys(translator)) {
        document.querySelector(`#${output}`).value = translate(e.target, output);
      }
    });
    
    function translate(input, outputSelector) {
      const text = input.value;
      let translated = translator[outputSelector][text];
      if (!translated) {
        const words = input.value.split(" ");
        translated = words.map(word => translator[word] || word).join(" ");
      }
      return translated;
    }
    <input id="input_1" class="text-area-main input_mainn" type="text" placeholder="Input Goes Here">
    
    <textarea id="output_1" class="text-area-main"></textarea>
    <textarea id="output_2" class="text-area-main"></textarea>

    如果您希望对每个输出区域执行不同的操作而不是使用字典,请添加if 条件或更好地基于键调用函数(创建要应用的自定义函数的字典)。


    编辑 1:

    使用来自here的解决方案-

    const translator = {
      "output_1": {
        "a quick brown fox jumps over a lazy dog": "a fast brown fox jumps ovew a wazy good boy",
        "Hello there": "Ello There",
        "n": "\ud83d\udc68\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c\udffd"
      },
      "output_2": {
        "a quick brown fox jumps over a lazy dog": "new fox",
        "Hello there": "Hey There",
        "n": "no"
      }
    };
    
    document.querySelector("#input_1").addEventListener("input", (e) => {
      for (const output of Object.keys(translator)) {
        document.querySelector(`#${output}`).value = translate(e.target, output);
      }
    });
    
    function translate(input, outputSelector) {
      const text = input.value;
      const currentTranslator = translator[outputSelector];
      const translated = replaceOnceUsingDictionary(currentTranslator, text, function(key, dictionary) {
        return dictionary[key];
      });
      return translated;
    }
    
    /*
     * @description Replaces phrases in a string, based on keys in a given dictionary.
     *               Each key is used only once, and the replacements are case-insensitive
     * @param       Object dictionary  {key: phrase, ...}
     * @param       String content
     * @param       Function replacehandler
     * @returns     Modified string
     */
    function replaceOnceUsingDictionary(dictionary, content, replacehandler) {
      if (typeof replacehandler != "function") {
        // Default replacehandler function.
        replacehandler = function(key, dictionary) {
          return dictionary[key];
        }
      }
    
      var patterns = [], // \b is used to mark boundaries "foo" doesn't match food
        patternHash = {},
        oldkey, key, index = 0,
        output = [];
      for (key in dictionary) {
        // Case-insensitivity:
        key = (oldkey = key).toLowerCase();
        dictionary[key] = dictionary[oldkey];
    
        // Sanitize the key, and push it in the list
        patterns.push('\\b(?:' + key.replace(/([[^$.|?*+(){}])/g, '\\$1') + ')\\b');
    
        // Add entry to hash variable, for an optimized backtracking at the next loop
        patternHash[key] = index++;
      }
      var pattern = new RegExp(patterns.join('|'), 'gi'),
        lastIndex = 0;
    
      // We should actually test using !== null, but for foolproofness,
      //  we also reject empty strings
      while (key = pattern.exec(content)) {
        // Case-insensitivity
        key = key[0].toLowerCase();
    
        // Add to output buffer
        output.push(content.substring(lastIndex, pattern.lastIndex - key.length));
        // The next line is the actual replacement method
        output.push(replacehandler(key, dictionary));
    
        // Update lastIndex variable
        lastIndex = pattern.lastIndex;
    
        // Don't match again by removing the matched word, create new pattern
        patterns[patternHash[key]] = '^';
        pattern = new RegExp(patterns.join('|'), 'gi');
    
        // IMPORTANT: Update lastIndex property. Otherwise, enjoy an infinite loop
        pattern.lastIndex = lastIndex;
      }
      output.push(content.substring(lastIndex, content.length));
      return output.join('');
    }
    <input id="input_1" class="text-area-main input_mainn" type="text" placeholder="Input Goes Here">
    
    <textarea id="output_1" class="text-area-main"></textarea> 
    <textarea id="output_2" class="text-area-main"></textarea>

    【讨论】:

    • 您好 Nikhil,感谢您的帮助并提出解决方案。这工作得很好,但是,如果你能帮助我解决代码中的另一个错误,那就太棒了。翻译器可以很好地处理完整的句子和单词,但是,如果输入一个完整的句子,其中将翻译几个单词短语,那么如果在定义的值之前或之后有任何单词,则翻译器将无法工作。示例:“a quick brown fox jumps over a lazy dog”可以正常工作,但如果我输入“a quick brown fox jumps over a lazy dog and walks like a羊”,它不会翻译定义的短语。
    • @AhmadWahid,您需要的有点复杂,因为您必须搜索整个字典才能找到与单词或单词部分匹配的内容。当字典中有两个键匹配时,这变得更加复杂。如果您指定匹配键的规则,它会更容易实现。我正在考虑如何实现它,但幸运的是我找到了类似的解决方案。尽管此解决方案仅替换键一次,但它适用于带空格的单词。如果它符合您的要求,也许可以在您的最后检查它?
    • Nikhil,经过一些修改的这段代码似乎对我有用。为此非常感谢!你摇滚:)
    猜你喜欢
    • 2018-04-04
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    • 2023-03-16
    • 1970-01-01
    相关资源
    最近更新 更多