0

Microsoft Translation Widget を使用しています。これを使用して、ユーザーの操作なしで Web ページを自動的に翻訳したいと考えています。

問題は、CSS と JS がウィジェット内の Microsoft 独自のスクリプトから読み込まれるため、document.ready でポップアップしたり隠したりするウィジェットを取り除くことができないことです。

誰もこれを回避する方法を知っていますか? 私はいたるところを見てきましたが、これに対する解決策が見つかりません。

4

2 に答える 2

4

おっと、それでしばらく遊んだ後、私はついにあなたが望むものを達成しました.

いくつかの回避策が必要なため、ちょっと醜いですが、動作します。 fiddle を見てください

手順は次のとおりです。

  1. まず、デフォルトのaddEventListener動作をオーバーライドする必要があります。

    var addEvent = EventTarget.prototype.addEventListener;
    var events = [];
    
    EventTarget.prototype.addEventListener = function(type, listener) {
      addEvent.apply(this, [].slice.call(arguments));
      events.push({
        element: this,
        type: type,
        listener: listener
      });
    }
    
  2. 次に、ヘルパー関数を作成しますremoveEvents。要素のすべてのイベント リスナーを削除します。

    var removeEvents = function(el, type) {
      var elEvents = events.filter(function(ev) {
        return ev.element === el && (type ? ev.type === type : true);
      });
    
      for (var i = 0; i < elEvents.length; i++) {
        el.removeEventListener(elEvents[i].type, elEvents[i].listener);
      }
    }
    
  3. タグを作成するとき、scriptMicrosoft が言う方法で:

    var s = d.createElement('script');
    s.type = 'text/javascript';
    s.charset = 'UTF-8';
    s.src = ((location && location.href && location.href.indexOf('https') == 0) ? 'https://ssl.microsofttranslator.com' : 'http://www.microsofttranslator.com') + '/ajax/v3/WidgetV3.ashx?siteData=ueOIGRSKkd965FeEGM5JtQ**&ctf=True&ui=true&settings=Manual&from=';
    var p = d.getElementsByTagName('head')[0] || d.dElement;
    p.insertBefore(s, p.firstChild);
    

    loadその にイベント リスナーを追加する必要がありscriptます。以下のコードは完全にコメント化されています。

    s.addEventListener('load', function() {
      // when someone changes the translation, the plugin calls the method TranslateArray
      // then, we save the original method in a variable, and we override it
      var translate = Microsoft.Translator.TranslateArray;
    
      Microsoft.Translator.TranslateArray = function() {
        // we call the original method
        translate.apply(this, [].slice.call(arguments));
    
        // since the translation is not immediately available
        // and we don't have control when it will be
        // I've created a helper function to wait for it
        waitForTranslation(function() {
          // as soon as it is available
          // we get all the elements with an attribute lang 
          [].forEach.call(d.querySelectorAll('[lang]'), function(item, i) {
            // and we remove all the mouseover event listeners of them
            removeEvents(item, 'mouseover');
          });
        });
      }
    
      // this is the helper function which waits for the translation
      function waitForTranslation(cb) {
        // since we don't have control over the translation callback
        // the workaround was to see if the Translating label is visible
        // we keep calling the function, until it's hidden again
        // and then we call our callback
        var visible = d.getElementById('FloaterProgressBar').style.visibility;
        if (visible === 'visible') {
          setTimeout(function() {
            waitForTranslation(cb);
          }, 0);
          return;
        }
        cb();
      }
    });
    

更新 1

質問を読み直した後、すべてのウィジェットをまったく非表示にしたいようです。

したがって、翻訳が取得されたらすぐに次のコードを追加する必要があります。

waitForTranslation(function() {
  document.getElementById('MicrosoftTranslatorWidget').style.display = 'none';
  document.getElementById('WidgetLauncher').style.display = 'none';
  document.getElementById('LauncherTranslatePhrase').style.display = 'none';
  document.getElementById('TranslateSpan').style.display = 'none';
  document.getElementById('LauncherLogo').style.display = 'none';
  document.getElementById('WidgetFloaterPanels').style.display = 'none';
  // rest of the code
});

その新しい動作を示す別のフィドルを作成しました。

更新 2

次の CSS コードを追加することで、ウィジェットがまったく表示されないようにすることができます。

#MicrosoftTranslatorWidget, #WidgetLauncher, #LauncherTranslatePhrase, #TranslateSpan, #LauncherLogo, #WidgetFloaterPanels {
    opacity: 0!important;
}

document.bodyまた、デフォルトで非表示にし、ページが完全に翻訳されたときに表示することで、翻訳前のテキストが表示されないようにすることもできます。

(function(w, d) {
  document.body.style.display = 'none';
  /* (...) */

  s.addEventListener('load', function() {
    var translate = Microsoft.Translator.TranslateArray;

    Microsoft.Translator.TranslateArray = function() {
      translate.apply(this, [].slice.call(arguments));

      waitForTranslation(function() {
        /* (...) */
        document.body.style.display = 'block';
      });
    }
  });
});

私が作成した最後のフィドルを見てください。

于 2015-09-25T18:01:48.850 に答える