Question

Rappelez-vous que le message d'absence sur le but qui dit comment:

Aoccdrnig à un rscheearch à Cmabrigde Uinervtisy, il deosn pas mttaer dans quel oredr la ltteers dans un wrod sont, la olny iprmoetnt tihng est que la première et la drenèire soit à la rghit pclae.Rset peut être un toatl microentreprises et les petites entreprises et vous pouvez sitll raed il wouthit porbelm.Tihs est bcuseae la huamn mnid aid pas raed ervey lteter par istlef, mais le wrod comme un wlohe.

De toute façon je suis en train de faire une fonction qui permettrait de le faire à une page entière.Il existe quelques règles pour cette fonction.

  1. moins de 4 caractères laisser seul.
  2. les caractères non-alphanumériques ne comptent pas dans le cadre de la parole.
  3. les mots les mots sont vraiment deux mots
  4. les mots doivent obtenir illisibles si longueur >= 4 (ne peut pas être comme l'original)
  5. Le premier et dernier caractères rester la même et que le milieu caractères se tronqués (Merci Hersheezy)
  6. le texte doit toujours être aléatoires et de produire unique de rendre méconnaissable sur chaque course
  7. Javascript Pure et itère sur tous les nœuds de texte
  8. La plus courte à la plus douce du code de victoires.

De toute façon, il semble assez simple à mettre en œuvre, comment est commencer un concours pour voir qui peut faire le plus propre plus claire de code pour accomplir cette tâche.Hésitez pas à emprunter sans la reconnaissance de mon code (je def ont)

Si j'ai rien oublié de l'ajouter dans les commentaires.De toute façon, j'ai travaillé sur de très hackishly et ici me montrant mon moins que par le travail

DÉMO

var i, j, words, textNodes, punct = /[^a-zA-Z0-9]/;

Array.prototype.shuffle = function() {
    for (var i = 0; i < this.length; i++) {
        var j = i;
        while (j == i) {
            j = Math.floor(Math.random() * this.length);
        }
        var tmp = this[i];
        this[i] = this[j];
        this[j] = tmp;
    }
    return this;
};

String.prototype.shuffle = function() {
    return this.split('').shuffle().join('');
};

function transverse(element, array) {
    if (!array) array = [];
    if (element.nodeType === 3) {
        array.push(element);
    } else {
        for (var i = 0; i < element.childNodes.length; i++) {
            transverse(element.childNodes[i], array);
        }
    }
    return array;
}

function garble(str) {
    if (!str) return '';
    str = str.trim();
    if (/-/.test(str)) {
        str = str.split('-');
        for (var i = 0; i < str.length; i++) {
            str[i] = garble(str[i]);
        }
        return str.join('-')
    }
    if (punct.test(str.charAt(0))) {
        return str.charAt(0) + garble(str.slice(1));
    }
    if (punct.test(str.charAt(str.length - 1))) {
        return garble(str.slice(0, -1)) + str.charAt(str.length - 1);
    }
    if (str.length < 4) return str;
    if (str.length === 4) return str.charAt(0) + str.charAt(2) + str.charAt(1) + str.charAt(3)
    return str.charAt(0) + str.substr(1, str.length - 2).shuffle() +
        str.charAt(str.length - 1);
}


window.onload = function() {
    textNodes = transverse(document.documentElement);
    for (i = 0; i < textNodes.length; i++) {
        words = textNodes[i].data.split(' ');
        for (j = 0; j < words.length; j++) {
            words[j] = garble(words[j]);
        }
        textNodes[i].data = words.join(' ');
    }
};
Était-ce utile?

La solution

Mise à jour (Dernière) : Ne pensez pas que cela puisse obtenir de plus petite .. Demo
Dernière compression (332):

var e=document.body.getElementsByTagName('*'),j,i,l,x,t,b;for(i=0;e[i];i++)for(j=0;b=e[i].childNodes[j];j++)if(b.nodeType==3)b.data=b.data.replace(/\w{4,}/g,function(w){if(/(^.)(\1)+$/.test(x=w.substring(1,l=w.length-1)))return w;t=w;while(t==w)t=w[0]+x.split('').sort(function(){return 0.5-Math.random()}).join('')+w[l];return t}); 

code:

var e = document.body.getElementsByTagName('*'),
    j, i, l, x, t, b;
for (i = 0; e[i]; i++)
for (j = 0; b = e[i].childNodes[j]; j++)
if (b.nodeType == 3) b.data = b.data.replace(/\w{4,}/g, function(w) {
    if (/(^.)(\1)+$/.test(x = w.substring(1, l = w.length - 1))) return w;
    t = w;
    while (t == w)
    t = w[0] + x.split('').sort(function() {
        return 0.5 - Math.random();
    }).join('') + w[l];
    return t;
});


mise à jour même .. plus petit ..

Même plus petite version
Je ne connais pas le mini-faire votre utilisation, mais cela doit être au moins ( modifier 108) d'octets plus petits.
Version comprimée (365 octets):

var e=document.body.getElementsByTagName('*'),a=[],c,j,i,l,x,t,b;for(i=0;c=e[i];i++)for(j=0;b=c.childNodes[j];j++)if(b.nodeType==3){b.data=b.data.replace(/\b[a-z0-9]{4,}\b/gi,function(w){if(/(^.)(\1)+$/.test(x=w.substring(1,l=w.length-1)))return w;t=w;while(t==w)t=w[0]+x.split('').sort(function(){return Math.floor(Math.random()*2)?1:-1}).join('')+w[l];return t})}  

code:

var e = document.body.getElementsByTagName('*'),
    a = [],
    c, j, i, l, x, t, b;
for (i = 0; c = e[i]; i++)
for (j = 0; b = c.childNodes[j]; j++)
if (b.nodeType == 3) {
    b.data = b.data.replace(/\b[a-z0-9]{4,}\b/gi, function(w) {
        if (/(^.)(\1)+$/.test(x = w.substring(1, l = w.length - 1))) return w;
        t = w;
        while (t == w)
        t = w[0] + x.split('').sort(function() {
            return Math.floor(Math.random() * 2) ? 1 : -1;
        }).join('') + w[l];
        return t;
    });
}

éditer
< Nouvelle démo de règles

Code:

var fn = function(e) {
    var ret = [],c;
    for (var i = 0; i < e.length; i++) {
        c = e[i].childNodes;
        for (var j = 0; j < c.length; j++)
            if (c[j].nodeType === 3) ret.push(c[j]);
    }
    return ret;
};
var es = fn(document.body.getElementsByTagName('*'));
for (var i = 0; i < es.length; i++) {
    var e = es[i],len,x;
    e.data = e.data.replace(/\b[a-z0-9]{4,}\b/gi, function(w) {
        if (/(^.)(\1)+$/.test(x = w.substring(1, len = w.length - 1))) return w;
        var tmp = w;
        while (tmp === w) {
            tmp = w[0] + x.split('').sort(function() {
                return Math.floor(Math.random() * 2) ? 1 : -1;
            }).join('') + w[len];
        }
        return tmp;
    });
}

Cela devrait respecter toutes les règles et garder le format et la ponctuation. démo

//select all nodes in document and perform map on it to filter out
//non text node types, then each one of those elements is processed.
$('*').contents().map(function(i, elem) {
    if (elem.nodeType !== 3) return null;
    else return elem;
}).each(function(i, elem) {
 //call strip funciton defined down to get an object, with a word array, and
 //charecters which was stripped along with there index in the orginal string
    var str1 = '',
        tmp = strip(elem.data),
        words = tmp.words,
        sentence;
    // shuffle all words
    words = $.map(words, function(x, i) {
        return shuffle(x);
    });
    //construct raw sentence (non alphanumeric charecters)
    sentence = words.join('');
    //reinsert spaces and punctiouation 
    $.each(tmp.chars, function(i, elem) {
        sentence = sentence.substring(0, elem.index) + elem.char + sentence.substring(elem.index - 1 + elem.char.length);
    });
    //set the element text
    elem.data = sentence;
});

//shuffle funciton takes a word and shuffle the charecters between the last and the firt
function shuffle(txt) {
    //if the word is smaller than 4 charecters or it has repeated charecters in
    //its middle (i.e. loop, 'oo' cannot be shuffled!) then return it;
    if (txt.length < 4 || /(^.)(\1)+$/.test(txt.substring(1, txt.length - 1)))
        return txt;
    var str = txt.split(''),
        ret = [],
        rand, x = 0,
        tmp = txt;
    //while the txt hasn't changed in the first randomization cycle then repeated
    while (txt === tmp) {
        ret = [];
        $.each(str, function(i, c) {
            if (i === str.length - 1 || i === 0) {
                ret[i] = c;
                return;
            }
            while (true) {
                rand = Math.floor(Math.random() * (str.length - 2) + 1);
                if (!ret[rand]) {
                    ret[rand] = c;
                    break;
                }
            }
        });
        tmp = ret.join('');
    }
    return ret.join('');
}

function strip(txt) {
    var punc = /[^A-Za-z0-9]/g,
        res, nonAlphaNum = [],
        arr;
    //punc regex is all non-alphanumeric charecters which will act on the string
    //to point out unwanted charecters and store them in an array along with
    //their index
    while ((res = punc.exec(txt)) != null) {
        nonAlphaNum.push({
            index: res.index,
            char: res[0]
        });
    }
    //split into words
    arr = txt.split(/\s/);
    //remove punctiuation and other unwanted chars
    arr = $.map(arr, function(x, i) {
        return x.replace(punc, '');
    });
    return {
        words: arr,  //words array
        chars: nonAlphaNum //array of stripped charecter objects (chars, index in orginal)
    };
} 

BTW Beau choix de l'article, Wwiwieikikb !!

Autres conseils

Mise à jour

Donc je ne pouvais pas m'empêcher de jouer un peu avec cette chose et voir ce que les autres façons que je pouvais manipuler le document avec aussi peu de code que possible.Il suffit de dire qu'il peut être réduit à travailler dans un scénario, mais j'aime faire des choses avec des options pour l'utilisateur de jouer avec.

Cela dit, voici quelques variations sur le dessus et les avantages/déceptions:


Présentation officielle (473bytes)

Minifiés (473bytes) 1

function t(e){var r=[],w;for(w=0;w<e.length;w++){if(e[w].nodeType===3)r.push(e[w]);else if(e[w].childNodes)r=r.concat(t(e[w].childNodes));}return r;}var e,x=t(document.body.childNodes),y,z;for(y=0;y<x.length;y++){x[y].data=x[y].data.replace(/\b[a-z]{4,}\b/ig,function(w){if(w.length==4&&(/^.([a-z])\1./i).test(w))return w;e=w;while(e==w){z=w.split('');e=z[0]+(z.slice(1,z.length-1).sort(function(a,b){return(Math.random()*2)>1?1:-1;}).join(''))+z[z.length-1];}return e;});}

Onu-version compacte: (479bytes) 1

function t(e){
  var r=[],w;
  for(w=0;w<e.length;w++){
    if(e[w].nodeType===3)r.push(e[w]);
    else if(e[w].childNodes)r=r.concat(t(e[w].childNodes));
  }
  return r;
}
var x=t(document.body.childNodes);
for(var y=0;y<x.length;y++){
  x[y].data=x[y].data.replace(/\b[a-z]{4,}\b/ig,function(w){
    if(w.length==4&&(/^.([a-z])\1./i).test(w))
      return w;
    var e=w;
    while (e==w){
      var x=w.split('');
      e=x[0]+(x.slice(1,x.length-1).sort(function(a,b){
        return(Math.random()*2)>1?1:-1;
      }).join(''))+x[x.length-1];
    }
    return e;
  });
}
  • Pas d'utilisation de jQuery ("javascript")
  • Ajouter <script src="garble.js"></script> juste au-dessus </body> ou placer le code dans l'événement onload.

1 re-placement de var déclarations rend plus court, voir 479bytes vs 473 exemptions)


Des Versions Supplémentaires

De base (démo)

// jQuery Garble
// "Basic" version
//
// Requirements:
// 1. Find all words 4+ letters long (exclude hyphens, punctuation or numbers from
//    the classification)
// 2. The words being garbled must follow:
//    a. They can not remain the same as the previous state
//    b. The first and last character must remain in-tact
// 3. The garbling must be random and produce a new result each iteration.
//
// Usage:
// $(selector).garble(options);
//
(function($){
    $.fn.extend({
        garble: function(options){
            // basic options
            var o = $.extend({
                flagChanges: false,
                changeClass: 'modified'
            },options);
            // iterate over elements
            return this.each(function(i,e){
                var txt = $(e).text();
                // locate words with 4+ letters
                $(e).html(txt.replace(/\b[a-z]{4,}\b/ig,function(w){
                    var e = w;
                    // make sure we get an altered word back
                    while (e==w){
                        var x = w.split('');
                        e = x[0]+(x.slice(1,x.length-1).sort(function(y,z){
                            return (Math.random()*2)>1?1:-1; // randomize
                        }).join(''))+x[x.length-1];
                    }
                    return (o.flagChanges?'<span class="'+o.changeClass+'">'+e+'</span>':e);
                }));
            });
        }
    });
})(jQuery);

Pros

  1. Très mince et
  2. Des Options qui vous permettent de modifier le word modifié (encapsule chaque changement dans un span avec la valeur par défaut "modifié" de la classe ou d'une classe de votre choix).

Cons

  1. Ne fonctionne pas avec les éléments imbriqués (cela signifie que vous devez sélectionner le plus bas possible de l'élément dans l'arborescence DOM.Donc, si vous êtes juste de faire des paragraphes avec pas de liens hypertexte ou s'étend à l'intérieur, c'est votre gagnant)
  2. Si les éléments qui ont des enfants sont utilisés dans le sélecteur, leur mise en forme html (comme un album de linkin un paragraphe) sera dépouillé.

Mince et (démo)

$(function(){                                                              // on load
  $('*','body').contents().map(function(i,e){                              // grab all elements,
    return e.nodeType !== 3 ? null : e;                                    // then filter by textual elements
  }).each(function(i,e){                                                   // amd iterate through them.
    e.data = e.data.replace(/\b[a-z]{4,}\b/ig, function(w) {               // go through and find 4+ letters words
      if (w.length==4&&w.substring(1,2)==w.substring(2,3))                 // (avoid infinite loops on words that
        return w;                                                          // can't be changed [e.g. look])
      var e = w;                                                           // Store the original word for comparison, but
      while (e==w){                                                        // keep scrambling until we have a new word.
        var x = w.split('');                                               // (do so by breaking out middle letters in to array,
        e = x[0] + (x.slice(1, x.length - 1).sort(function(a,b){           // then sort those middle letters
          return (Math.random() * 2) > 1 ? 1 : -1;                         // based on a random number)
        }).join('')) + x[x.length - 1];                                    // Now, rejoin it all back together
      }
      return e;                                                            // and finally return the modified result.
    });
  });
});

Entièrement En Vedette (démo)

// jQuery Garble
// "Feature Rich" version
//
// Requirements:
// 1. Find all words 4+ letters long (exclude hyphens, punctuation or numbers from
//    the classification)
// 2. The words being garbled must follow:
//    a. They can not remain the same as the previous state
//    b. The first and last character must remain in-tact
// 3. The garbling must be random and produce a new result each iteration.
//
// Usage:
// $(selector).garble(options);
//
(function($) {
    $.fn.extend({
        garble: function(options) {
            var o = $.extend({}, $.fn.garble.defaults, options);

            // takes in a string and performs the necessary manipulation(s) on it. Use regex
            // to only collect words greater than or equal to 4 characters long, and consider
            // punctuation not part of the word.
            var garbleStr = function(s,t){
                return s.replace(/\b[a-z]{4,}\b/ig, function(w) {
                    var e = o.algorithm(w);

                    // if we're not performing a low-level parse and they want the changes styled,
                    // return a span with either the detault class or their custom class
                    if (t && !o.lowLevel && o.highLevel.flagChanges)
                        return '<span class="'+o.highLevel.changeClass+'">'+e+'</span>';

                    // just return the new word
                    return e;
                });
            };

            // Very high-level process.
            // Will only change the lowest node's text (so a paragraph
            // with links, only the links will be altered)
            var highLevel = function(i, e) {
                // we're not at the bottom element, keep going
                if ($(e).children().length>0){
                    return $(e).children().each(highLevel);
                }

                var t = $(e).text();
                $(e).html(garbleStr(t,e.tagName!=='TEXTAREA'));
            };
            // Low level process
            // Goes down to each individual element and changes it
            var lowLevel = function(i, e) {
                var d = e.data;
                e.data = garbleStr(d);
            };

            // depending their selection, execute either or
            if (o.lowLevel){
                return this.find('*').contents().map(function(i, e) {
                    return (e.nodeType !== 3 ? null : e);
                }).each(lowLevel);
            }else{
                return this.contents().each(highLevel);
            }
        },
    });

    // Defaults
    $.fn.garble.defaults = {
        // Perform low-level modification? (Modifies all words it finds,
        // not just the one farthests down the tree)
        lowLevel: false,

        // when lowLevel is set to false, these options are available:
        highLevel: {
            // wrap changes in a <span>
            flagChanges: false,

            // the class being applied to the above <span>
            changeClass: 'modified'
        },

        // function used to garble the text. This will be passed each word
        // individually and should return the new word's value.
        algorithm: function(w) {
            // if w = "hello":
            // 1. Make an array out of the letters.
            // 2. keep the first and last in-tact, but use .slice() to extract the middle
            // 3. Perform the specified algorithm on the middle characters
            // 4. return result
            var e = w;
            while (e==w){ // secure it gets changed
                var x = w.split('');
                e = x[0] + (x.slice(1, x.length - 1).sort(function(a,b){
                    return (Math.random() * 2) > 1 ? 1 : -1;
                }).join('')) + x[x.length - 1];
            }
            return e;
        }
    };
})(jQuery);

Pros

  1. Flexible.Cela fonctionne à peu près tous les scénarios, mais un rapide processus de bas-de-la-chaîne alimentaire, de l'élément ou de l'appelant sur l'ensemble de la <body>--cela peut le manipuler.
  2. Très personnalisable:
    1. Pouvez spécifier pour effectuer de bas niveau (chaque élément), des changements, ou de haut niveau (seulement les éléments sans les enfants)
    2. Pouvez spécifier si vous voulez montrer les changements, et ce classe à appliquer (les modifications sont enveloppés dans un span avec le nom de classe spécifié)
    3. Pouvez spécifier une fonction de brouillage (peut-être vous voulez juste inverser les mots ou utiliser une meilleure méthode)

Cons

  1. Peu plus de surcharge, mais il est encore rapide.
  2. Peut-être trop d'options ou tout simplement trop gonflé.
  3. Je suis sûr que quelqu'un va trouver plus cons

Voici mon point de vue sur la fonction.Voir la démo ici .

  • Il utilise l'excellent jquery.ba-remplaTextext plugin pour gérer uniquement le textenœuds
  • gère des mots de longueur arbitraire où tous les caractères internes sont égaux
  • facile à comprendre avec des noms descriptifs

    version complète (1187 octets):

      /* Called on document.ready */
      $(function () {
        $("body *").replaceText(/\b([A-z]{4,})\b/g, scramble_inner );
      });
      /* Scramble the inner characters of a word */
      function scramble_inner(word) {
        return word[0] 
          + force_shuffle(word.slice(1, word.length - 1))
          + word[word.length - 1];
      }
      /* Randomize characters in the string, but check to make sure
       * they're different from the original. Handle's the special
       * case where all inner characters are equal, for instance "moooo".
       */
      function force_shuffle(str) {
        if (all_chars_same(str)) return str;
        var result = str;
        while (str === result) {
          result = str.split('').sort(function() {
            return Math.floor(Math.random() * 2) ? 1 : -1;
          }).join('');
        }
        return result;
      }
      /* Check whether all characters in the string are equal, eg "ooo" */
      function all_chars_same(str) {
        for (i = 0; i < str.length; i++) {
          if (str[i] !== str[0]) {
            return false;
          }
        }
        return true;
      }
    

    version minifiée (348 octets):

    $(function(){$("body *").replaceText(/\b([A-z]{4,})\b/g,a)});function a(w){return w[0]+b(w.slice(1,w.length-1))+w[w.length-1]}function b(s){if(c(s))return s;var r=s;while(s===r){r=s.split('').sort(function(){return Math.floor(Math.random()*2)?1:-1}).join('')}return r}function c(s){for(i=0;i<s.length;i++){if(s[i]!==s[0]){return false}}return true}
    

Note: I ran this through JSLint, which may have been a bad idea. Anyway, the demo is here.

function shuffle(letters) {
    var i = letters.length - 2;
    while (i > 1) {
        var pos = Math.floor(Math.random() * i) + 1;
        var tmp = letters[i];
        letters[i] = letters[pos];
        letters[pos] = tmp;
        i--;
    }
}

function scramble(word) {
    if (word.slice(1, -2) == word.slice(2, -1)) {
        return word;
    }
    var letters = word.split('');
    var result = word;
    while (result == word) {
        shuffle(letters);
        result = letters.join('');
    }
    return result;
}

function process(node) {
    var data = node.data;
    if (/[a-z]{4}/i.test(data)) {
        node.data = data.replace(/[a-z]{4,}/gi, scramble);
    }
}

function traverse(element) {
    var node = element.firstChild;
    while (node) {
        if (node.nodeType == Node.ELEMENT_NODE) {
            traverse(node);
        } else if (node.nodeType == Node.TEXT_NODE) {
            process(node);
        }
        node = node.nextSibling;
    }
}

function garble() {
    traverse(document.body);
}

window.onload = garble;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top