0

I'm trying to translate some phrases with jQuery. This code mostly works great:

changeText = function(text, newText){
var currentText = $('span.example').html();  
$('span.example').html(currentText.replace(text,newText)); };
window.setTimeout(function(){changeText("TranslateMe", "Translation")}, 0000);

However, it's mostly useless when you wait for ajax generated results. To clarify - this is a search script with the following procedure:

  1. When you click Search, you get a part of the page loaded "normally". I can change these text strings without any problems.

  2. Afterwards there are results loaded dynamically through ajax I guess and there are div "blocks" getting loaded one after another. These phrases don't get translated.

A workaround is to wait for some time until everything gets loaded and then it does work for some parts. E. g.:

window.setTimeout(function(){changeText("TranslateMe", "Translation")}, 20000);

However, that's not a good solution, because users see untranslated strings that way for some time.

Therefore, I'm looking for a solution that would change strings as they get displayed. Is there a way to do that?

Thanks in advance!

EDIT:

Trying charlie's approach:

<script>
changeText = function(text, newText, $el) { 

$el.html(function(i, currentText){
    return currentText.replace(text, newText);
});    
};

$(function(){
changeText(text, newText,$('span.example'));
});

$.ajax({
  success:function(data){
        var $changeEl=$(data).find('span.example');
        changeText(text, newText,$changeEl);

var currentText = $('span.example').html();  
$('span.example').html(currentText.replace(TranslateMe,Translation));
};

  })
})
</script>
tommie111
  • 3
  • 2

3 Answers3

0

Your best/cleanest approach would be to add a callback from where the AJAX Call is being made and the content has been inserted in the divs.

If that is not possible for you there might be a possibility for you to get a callback if the DOM changes as asked here and here

Community
  • 1
  • 1
Tyron
  • 1,938
  • 11
  • 30
0

I agree with Tyron that if you can, you should add or modify the callback function to the AJAX calls.

as for detecting the changes and translating without access to the ajax. something like this might help.

var c = document.getElementById('[ID OF CONTAINER FOR  UNTRANSLATED BLOCKS]');
c.__appendChild = c.appendChild;

//this function catches the element before it is appended
c.appendChild = function(){

    //this applies the change
    c.__appendChild.apply(c, arguments);

    var newBlock = $(c).children().last();
    //this hides the newly added block
    newBlock.hide();
    // now perform your translations on the newBlock contents
        //here
    // and then make the block visible again
    newBlock.show();
};
jkofron.e
  • 5,043
  • 1
  • 17
  • 16
  • Why would you mix DOM functions with jQuery? Also interfering with the native DOM like this is a bad practice. – Bergi Dec 22 '12 at 19:22
  • I mixed them because it looks as though the OP was using jQuery and I believe it will be easier to use and understand as an example if he can just plug his translate code right in and test it. As for bad practice, its the only way outside of modifying the ajax callback that I could think of. – jkofron.e Dec 22 '12 at 19:41
  • If he uses jQuery ajax, you could easily hook on it. And for the DOM, use mutation events or something, but do not overwrite native methods. – Bergi Dec 22 '12 at 19:44
0

If you change the function to add a context argument you could do something like:

changeText = function(text, newText, $el) { 
     /* html method allows for function as argument to modify element*/
    $el.html(function(i, currentText){
        return currentText.replace(text, newText);
    });    
};

Then on page load:

$(function(){
    changeText( text, newText,$('span.example'));
});

And in AJAX success look for the new elements and modify them:

$.ajax({
      success:function(data){
            var $changeEl=$(data).find('span.example');
            changeText( text, newText,$changeEl);
           /* your code that inserts the new html here*/
      })
})
charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • I have tried with your suggestion, but it seems quite complicated. Could you check my edit? I have tried to combine all of it into one script. – tommie111 Dec 22 '12 at 19:37
  • you don't need `setTimeout` if the only time content will change after page load is due to ajax. Also you kept your original code in the ajax success which is duplicating efforts – charlietfl Dec 22 '12 at 19:40
  • this comment `your code that inserts the new html here` means code that appends the ajax response to appropriate place in page...not `changeText` which is already done – charlietfl Dec 22 '12 at 19:43
  • OK, I have removed that line, but what bothers me is where to put the translations. They are one line above now. Sorry for being a noob, but being totally new to jquery and javacsript, all of this seems very complicated. Thanks for helping. – tommie111 Dec 22 '12 at 19:51