Do you really think Google translation doesn't affect the function of "front-end" pages?

Do you really think Google translation doesn't affect the function of "front-end" pages?

background

It was another fleeting working day. QA students suddenly put forward a bug, and the "counting" function of the text input box failed. After many searches, we finally found that it was because the test students turned on "Google translation" that they could not "count", which aroused my great interest. In the end, how did this seemingly "harmless to humans and animals" translation function affect my input box? From then on, the battle between Wei, Shu and Wu began. Ah ~ er (hit the arrow).

This article is written according to my exploration process, so it doesn't find the right direction at once. Follow my ideas at that time.

1, Change of dom structure (take react code as an example)

To know why the "translation function" affects the page, start by observing the changes in the page structure when the "translation" function takes effect. The simplest piece of code:

return ( <div>Hello</div> )

Before translation:

Translation:

Query the properties of the font tag. It is not recommended to use it anymore:

Try whether you can get the font tag element and modify the code

  function handleShowDom() {
    console.log(document.getElementById("box").children);
  }

 return( 
   <div id="box" onClick={handleShowDom}>
    Hello
   </div>
 )

It's interesting to get this element. If there is logic in the code to operate by obtaining child elements in some cases, there will be a problem in theory.

Is it because of the change of dom structure that the counting function of the text input box will disappear?

2, Compare various ui libraries between vue and react

By looking at the source code of element ui, no special code logic is found. What's going on? Full of questions gave me an idea. Is it related to the principles of vue and react framework itself? Next, I will experiment with the effects of four ui frameworks:

1: React - > antd (no bug) 👍🏻)

antd official website

2: React - > Arco (bug)

arco official website

3: Vue - > element (bug)

There's no need to demonstrate this. It's the beginning.

4: Vue - > iView (bug)

iview official website

Only antd has solved this bug perfectly (must: inspect), so we must study how it "presses the crowd"?

3, Delve into textarea

Since this is the problem with the input box element, let's start with it and see what the textarea element generated by element UI and antd looks like:

The difference is obvious. The content information of element UI is not placed inside the tag, because we can't view the content from the perspective of dom structure, but antd is just the opposite, which may be a breakthrough.

Let's focus our "firepower" on < textarea > and see how many assignment methods it has:

  return (
    <div className="App">
      <textarea rows="5" cols="40">
        Content 1
      </textarea>
      <br />
      <textarea rows="5" cols="40" value="Content 2"></textarea>
      <br />
      <textarea rows="5" cols="40" defaultValue="Content 3"></textarea>
   </div>

It's amazing. The above three ways of writing will produce the same dom structure. So I'm curious about what kind of writing method can hide the text in the tag? I've tried to specify value in js:

  useEffect(() => {
    document.getElementById("wrap").value = "Hello world";
  }, []);

  return (
    <div className="App">
      <textarea id="wrap" rows="5" cols="40">
        Content 4
      </textarea>
   </div>
 )

Sure enough, the problem here is that the initial value stored in the dom structure is actually the correct value displayed outside. What's the difference between these? Let's print out the relevant values:

vs🌩

I really don't know. It turns out that the implementation of libraries with different effects of the same components is so poor. I feel that the attribute values are quite poor.

However, through experiments, it is found that these attributes are not the direct cause of the bug. We still need to explore the source code. At this time, I realized that this problem may not be the responsibility of elemnet.

4, Does Google Translate affect vue

After many attempts, even I can't believe that the two-way bound data such as vue's calculation properties will become invalid after translation:

<template>
  <div id="app">
    <button @click="handleClick">Hello: {{n}}</button>
  </div>
</template>

<script>
export default {
  name: 'App',
  methods:{
    handleClick(){
      this.n += 1;
      console.log(this.n)
    }
  },
  data(){
    return {
      n:1
    }
  },
}
</script>

It can be seen from the above that the variable of vue has changed, but the page cannot be updated correctly due to the change of dom structure.

This is a very dangerous hidden danger, because some users may choose "always translate", which leads to the complete confusion of page functions!

5, Does Google Translate affect react

Since there will be problems with the arco framework of react, the react framework will certainly be affected. Let's try to find out what situations will cause bug s. After translation, click:

import { useState } from "react";
import "./App.css";

function App() {
  const [n, setN] = useState(0);

  function handleClick() {
    setN(n + 1);
    console.log(n + 1);
  }
  return <div onClick={handleClick}>Hello:{n}</div>;
}

export default App;

If changed to, it will not be affected:

<div onClick={handleClick}>{n}</div>;

6, Affected area (take the writing method of react as an example)

By observing the difference between the implementation of antd and element UI, I found that antd is done using the after pseudo class. Is this related to the pseudo class? This also proves that some situations are not affected. Let's experiment with the writing methods affected by Google Translation:

1: Splice text

Unaffected writing, or even every time n this writing changes, will remove the dom structure of the font tag.

<div>{n}</div>;

The affected writing is mainly spliced text.

<div>Hello {n}</div>;

<div>{n} {n}</div>;
2: Pseudo element (not translated)

Empty dom

<div className={"box"}>.</div>

Define pseudo elements

.box {
  height: 10px;
  width: 10px;
  border: 1px solid red;
}
.box::after {
  content: 'hello';
  display: inline-block;
}

Therefore, it is likely that there are no bug s in antd because of pseudo elements. If antd is not unintentional, it is too detailed.

3: Properties (very special)

The reason why it is very special is that whether attributes are translated needs to be discussed in two cases, whether there are text elements, and this text cannot be the text inside input.

The first case: the page has only one input box

    <div>
      <span>
        <input
          type="Please enter content"
          value={value}
          onChange={change}
          placeholder={"Please enter content"}
        />
      </span>
    </div>

Obviously, this input box is not translated:

The second case: add a string at will

    <div>
      <span>Hello</span>
      <span>
        <input
          type="Please enter content"
          value={value}
          onChange={change}
          placeholder={"Please enter content"}
        />
      </span>
    </div>

The translation is successful, and attributes such as placeholder that may be displayed to users are also translated, and other functional attributes will not be translated.

<span xxx={"xxxxxxxxx hello"}>Hello</span>

7, How to block translation

In order to prevent the bad experience caused by Google translation, you only need to add the translate="no" attribute on the html tag to shield the translation function:

8, What is the detection translated into

In fact, some users turn on Google translation by default. What's more, you do international projects. People in different languages are more likely to use the default Google translation when using your website. Without direct shielding, we should at least listen to what language users translate our website into. This will also facilitate our understanding in the future Optimize the i18n of the website.

For example, our website does not have Korean translation, but it is often used to translate into Korean, so can we consider adding Korean?

For another example, although we provide Korean translation, users still take the initiative to translate the website into Korean, so we should consider whether we can give users more explicit tips on the existing translation functions? After all, our own translation is more accurate and better experience.

1: Introduction to mutationobserver

All changes of dom elements can be monitored. After instantiation of MutationObserver, a configuration item will be passed in. This configuration item can customize which changes of dom need to be monitored. The main attributes are listed below:

  1. attributes Boolean value to monitor the attribute changes of dom
  2. The attributeFilter array monitors the change of a specific attribute of the dom. Filling in this parameter eliminates the need to judge which attribute changes each time
  3. childList Boolean value, change of child elements
  4. characterData Boolean value, which monitors the change of character data contained in the specified target node or child node tree

It should be noted that at least one of the three attributes childList, attributes or characterData must be true, otherwise a TypeError exception will be thrown.

2: Thoughts on monitoring translation

Since Google Translate will modify the lang attribute of our < HTML lang="en" > tag every time, we monitor the change of this attribute, and even if it is lang="en" Google translated into English or lang="en", it will be detected, so this technical scheme is also feasible.

Create a new listener i18n.js file and import it as a plug-in:

(function () {
  const oHtml = document.getElementsByTagName("html")[0];
  const observer = new window.MutationObserver((mutations) => {
    console.log(`Report: Translate as  ${oHtml.getAttribute("lang")}`);
  });
  observer.observe(oHtml, { attributes: true, attributeFilter: ["lang"] });
})();

Fortunately, even if you set < HTML lang = "en" translate = "no" > to disable the translation function, the above method can still detect what language users want to translate with Google translation.

I have compiled a comparison table of Google translation. Please take it yourself if you need it. It is not comprehensive, but it lists the commonly used countries:

[
  {
    "name": "Simplified Chinese",
    "lang": "zh-CN"
  },
  {
    "name": "English",
    "lang": "en"
  },
  {
    "name": "Arabic",
    "lang": "ar"
  },
  {
    "name": "irish",
    "lang": "ga"
  },
  {
    "name": "Belarusian",
    "lang": "be"
  },
  {
    "name": "Bulgarian",
    "lang": "bg"
  },

  {
    "name": "Traditional Chinese",
    "lang": "zh-TW"
  },
  {
    "name": "Polish",
    "lang": "pl"
  },
  {
    "name": "farsi",
    "lang": "fa"
  },
  {
    "name": "Danish",
    "lang": "da"
  },
  {
    "name": "German",
    "lang": "de"
  },
  {
    "name": "Russian",
    "lang": "ru"
  },

  {
    "name": "French",
    "lang": "fr"
  },
  {
    "name": "Filipino",
    "lang": "tl"
  },
  {
    "name": "Finnish",
    "lang": "fi"
  },
  {
    "name": "Khmer",
    "lang": "km"
  },
  {
    "name": "Georgian",
    "lang": "ka"
  },
  {
    "name": "kazakh",
    "lang": "kk"
  },
  {
    "name": "Korean",
    "lang": "ko"
  },
  {
    "name": "Dutch",
    "lang": "nl"
  },
  {
    "name": "Lao",
    "lang": "lo"
  },
  {
    "name": "romanian",
    "lang": "ro"
  },
  {
    "name": "Malay",
    "lang": "ms"
  },
  {
    "name": "mongolian",
    "lang": "mn"
  },
  {
    "name": "Bengali",
    "lang": "bn"
  },
  {
    "name": "Burmese",
    "lang": "my"
  },
  {
    "name": "Nepali",
    "lang": "ne"
  },
  {
    "name": "norwegian",
    "lang": "no"
  },
  {
    "name": "Portuguese",
    "lang": "pt"
  },
  {
    "name": "Japanese",
    "lang": "ja"
  },
  {
    "name": "Swedish",
    "lang": "sv"
  },
  {
    "name": "Esperanto",
    "lang": "eo"
  },
  {
    "name": "Thai",
    "lang": "th"
  },
  {
    "name": "Turkish",
    "lang": "tr"
  },
  {
    "name": "Ukrainian",
    "lang": "uk"
  },
  {
    "name": "Spanish",
    "lang": "es"
  },
  {
    "name": "Greek",
    "lang": "el"
  },
  {
    "name": "Hungarian",
    "lang": "hu"
  },
  {
    "name": "Italian",
    "lang": "it"
  },
  {
    "name": "Indonesian",
    "lang": "id"
  },
  {
    "name": "Vietnamese",
    "lang": "vi"
  },
  {
    "name": "Javanese",
    "lang": "jw"
  }
]

9, Summary

It seems that the translation function of "harmless to humans and animals" hides various "pits" of different depths. If some users of "amount settlement page" use Google translation, will it cause no small problems? Therefore, the best way is to provide a perfect "language switching" function.

end

This is it. I hope to make progress with you.

Tags: Javascript Front-end html5 React Vue.js

Posted on Sun, 05 Dec 2021 09:37:26 -0500 by CoolAsCarlito