Dynamic word swapping animation 3 - javascript

Following on from a previous question from 2011 titled Dynamic word swapping animation.
Thanks to Marek's answer I have been able to create an animation for text on a page that, every few seconds, changes one word out with another word from a list. However where previous question/ example was: "I have a header that says, "This is cool," but I want "cool" to be replaced every few seconds by "neat/awesome/groovy/etc".
I need my header to say eg, (for the sake of continuity) "This is cool man". The problem I have is that because the alternate words are longer it makes the sentence vary in length as it rotates through each of the words. Is there a way to specify, using Pure JS, for "man" to stay a set distance from "is", therefore the alternate words fill the gap between and the overall sentence remains the same length?
And, if the above is possible, can the alternate words be centred between "man" and "is"?
Any help greatly appreciated! Phil
The Pure JS I currently have (from previous post mentioned) reads:
<script>
var words = ["neat", "great", "best", "groovy"];
var i = 0;
var text = "This is cool";
function _getChangedText() {
i = (i + 1) % words.length;
console.log(words[i]);
return text.replace(/cool/, words[i]);
}
function _changeText() {
var txt = _getChangedText();
console.log(txt);
$("#changer").text(txt);
}
setInterval("_changeText()", 1000);
</script>
<span id="changer">This is cool</span>

This is more html/css thing... however, after few mods:
http://jsfiddle.net/X3wZV/1/
var words = ["neat", "great", "best", "groovy"];
var i = 0;
var text = "<span id='first'>This is</span> <span id='inner'>cool</span> <span id='sec'>man</span>";
function _getChangedText() {
i = (i + 1) % words.length;
console.log(words[i]);
return text.replace(/cool/, words[i]);
}
function _changeText() {
var txt = _getChangedText();
console.log(txt);
$("#changer").html(txt);
}
setInterval("_changeText()", 1000);
and a little styling (check CSS, change it according to your needs)...i think this is close to what you want, if i understand your question correctly... :)

Just use the 8th index of the string everytime and append man after the new word.
Is this what you mean?

Related

String concat, test, add extra code or add anyway and remove at the end?

Sorry for the odd title, I'm sure someone has asked something similar before. My question is, I'm building a string with html tags enclosed, my question is is it better to test and add extra tags, in this case a <br />, or to add the tag anyway and have a 'remove' line at the end, which is faster?:
So at the moment we have
bFirst = true;
label = '';
if(...)
{
if (!bFirst)
label += '<br/>';
label+= 'some more text'
}
if(...)
{
if (!bFirst)
label += '<br/>';
label+= 'some more text'
}
and so on...
or
if()
{
label+= 'some more text <br />'
}
and then just remove the last <br /> using the string.substring() method.
Which is faster, better, more correct? I don't need code it is really a performance question, I could test it but I'm sure someone has done this before.
Thanks.
You can define which way is the fastest with this procedure :
Requirements :
You will need an addon like firebug or pagespeed
You'll have to execute those two pages :
Add all extra text and then trim some :
<div id ="concat"></div>
<script type="text/javascript">
var someText = ""
// adds "foo" 10k times
for (i = 0; i < 10000; i++) {
someText += "foo"
}
// crops the 3 last characters off the string 5k times
for (i = 0; i < 5000; i++) {
someText.substr(someText.length - 3, someText.length);
}
// append the final string
$('#concat').append(someText);
</script>
On my browser, it takes between 0.19 sec and 0.30 sec.
Add extra text when it is needed
<div id ="if"></div>
<script type="text/javascript">
var someText = ""
var append = true;
for (i = 0; i < 15000; i++) {
//adds "foo" the first 10k times
if(append == true){
someText += "foo";
}
if(i == 10000){
append = false;
}
}
$('#if').append(someText);
</script>
This code iterates 15k times and only adds "foo" the first 10k times.
The execution of such code can take between 0.10 and 0.12 sec
Conclusion
Adding content to your string only when it is needed seems a better option in terms of performance.
Also, in terms of code readabilty, the second option should be used.
Quick and simple analysis:
First option makes a comparison and a memory reallocation.
Second option (supposing you'd be doing label = label.substring(...)) counts characters, if you want the first N characters, String.prototype.substring() will probably count N times while reading N bytes of characters. Finally, you allocate/reallocate memory.
Now which strategy appears more efficient?
If you're still in doubt try both methods under a timer.

Word count is wrong when adding new line in contenteditable

I count the words in a contenteditable. I split it using spaces. The problem comes when you enter a new line. It doesn’t count the word you’re currently writing on the new line until you add a space.
On top of that, in the following example if you split the example text into two lines, it will “eat up” one word when you do that:
http://jsfiddle.net/MrbUK/
I’m guessing this issue exists because between HTML elements there are no spaces:
<div>some things</div><div>are cool</div> its string would be “some thingsare cool”.
Here’s the code that I have:
function wordCount() {
var content_text = $('#post_content').text(),
char_count = content_text.length,
word_count = 0;
// if no characters, words = 0
if (char_count != 0)
word_count = content_text.replace(/[^\w ]/g, "").split(/\s+/).length;
$('.word_count').html(word_count + " words • " + char_count + " characters");
}
I tried replacing some HTML tags:
word_count = content_text.replace(/ /g, " ").replace(/<div>/g, "<p>").replace(/<\/div>/g, "</p>").replace(/<\/p><p>/g, " ").split(/\s+/).length;
without any luck. I need to discard whether it’s a <p> or <div> and some browsers add when merging lines together.
Any ideas? Thanks!
EDIT:
Thanks to Jefferson below for his clever method, I managed to solve this. For some reason I have to do -1 on the word_count to display the correct number of words:
function wordCount() {
var content_div = $('#post_content'),
content_text,
char_count = content_div.text().length,
word_count = 0;
// if no characters, words = 0
if (char_count != 0)
content_div.children().each(function(index, el) {
content_text += $(el).text()+"\n";
});
// if there is content, splits the text at spaces (else displays 0 words)
if (typeof content_text !== "undefined")
word_count = content_text.split(/\s+/).length - 1;
$('.word_count').html(word_count + " words • " + char_count + " characters");
}
You can use this:
$("#post_content").children().each(function(index, el){buffer += $(el).text()+"\n"})
This way you iterate by all elements inside your div and get only the text, put a "\n" between them.
Jefferson's answer was great, and it helped me with this exact same issue.
The problem I encountered was the contents of my contenteditable div was not entirely wrapped in HTML tags.
For example, my div contained the following HTML code:
This is my first line<div>This is my second line</div>
By using $.children(), it was ignoring the first line and only returning a word count of 5. To get round this I used $.contents() instead. Modified code is below:
$("#post_content").contents().each(function(index, el){buffer += $(el).text()+"\n"})
This returned a line count of 10.
Apologies for adding this as an answer and not as a comment to Jefferson's answer, however my reputation is too low to allow me to do that. I felt it was worth pointing the above out though.

jQuery: Getting syntax error after split() or text()?

What I need to do is grab the first <p> tag within an element, loop through all of the words, and wrap them in <span> tags. I wrote a script for this, which I thought worked, but it appears to break when some characters are in the <p> tag. I don't know which character(s) that causes it to break though.
Here is my current code:
$(document).ready(function(){
// Transform is set on html tag by modernizr
// Apply this on all .quote boxes, even if there are multiple (most likely aren't)
$('.csstransforms .quote').each(function() {
// Get data
var elem = $(this).find('p:first'),
html = elem.text(),
words = html.split(" "),
charCount = html.length
$(this).append('<p class="fixed"></p>');
// Add new words
var tmpWord = '';
for(i=0; i< words.length ; i++) {
tmpWord = $.trim(words[i]);
if(tmpWord && tmpWord != "") {
// Maybe replace with $(elem).next('.fixed') or something?
$('.csstransforms .quote .fixed').append('<span>'+ tmpWord +' </span>');
}
}
// Check word count, make size smaller if needed
if(charCount > 150) {
// Add class to .quote box
$(this).addClass('smaller');
}
// Hide original <p>
$(elem).hide();
});
});
The error i'm getting is as follows, and what you see in the text is the actual quote:
Uncaught Error: Syntax error, unrecognized expression: "In the decade or so, science has discovered a tremendous amount about the role emotions play in our lives. Researchers have found that even more than IQ, your emotional awareness and abilities to handle feelings, will determine your success and happiness in all walks of life, including family relationships". – John Gottman, Ph. D.
Any ideas as to what is causing this, and how to fix it? Been chewing on it on a while without success.
Update: Jsfiddle showing same error: http://jsfiddle.net/Uugbc/
Just for clarification. Your fiddle has
charCount = $(html).text().length;
but your variable html is not a jQuery object.
This will work better
var elem = $(this).find('p:first'),
html = elem.text(),
words = html.split(" "),
charCount = html.length; // here you had $(html).text().length;

Having a <Textarea> with a max buffer

I have seen plenty of code snippets to force a <Textarea> to have only X number of characters and then not allow anymore. What I am in need of is a <Textarea> where you can specify how many characters I can have at one time at most. Almost like a max buffer size. Think of it like a rolling log file. I want to always show the last/newest X number of characters.
Simpler the solution the better. I am not a web expert so the more complicated it gets the more greek it looks to me. :)
I am already using jQuery so a solution with that should be ok.
try this:
<textarea id="yourTextArea" data-maxchars="1000"></textarea>
var textarea = document.getElementById('yourTextArea');
var taChanged = function(e){
var ta = e.target;
var maxChars = ta.getAttribute('data-maxchars');
if(ta.value.length > maxChars){
ta.value = ta.value.substr(0,maxChars);
}
}
textarea.addEventListener('change', taChanged, 1);
for the last chars:
ta.value = ta.value.substr(ta.value.length - 1000);
And jQuery implementation:
$('#text').keyup(function() {
var max = $(this).data('maxchars'),
len = $(this).val().length;
len > max && $(this).val(function() {
return $(this).val().substr(len - max);
});
});
http://jsfiddle.net/WsnSk/
No code, I can't even spell JavaScript, but basically as you're about to add new text, check the length of the existing text. If the old text plus the new text is too long, trim off the beginning of the old text (likely at a newline or whatever). Rinse and repeat.
Here is the working code on Fiddle. It uses Jquery to make it simple.
<textarea id="txtArea"></textarea>
var size = 5;
$('#txtArea').change(function(){
var strValue = $('#txtArea').val();
strValue = strValue.split("").reverse().join("").substring(0, size).split("").reverse().join("");
alert(strValue);
});

Parsing text with Javascript

I'm trying to use Javascript to parse text that has been entered in a text box - which would combine a variety of user-generated variables to create random activities. This might make more sense looking at the example. Some example input might be:
Activity
#Home
#Out
#Home
Read #book for #time
Clean up #room for #time
#Out
Eat at at #restaurant
#book
Enders Game
Lord of the Rings
#room
bedroom
garage
basement
#restaurant
Red Robin
McDonalds
Starbucks
#time
15 minutes
30 minutes
45 minutes
60 minutes
Pound/and signs would be used to separate different categories.
The output would then be determined randomly from the given input, for example:
"Eat at Starbucks."
or
"Read Lord of the Rings for 60 minutes."
or
"Clean garage for 30 minutes."
Is this doable? It seems like it should be fairly straightforward, but I do not know where to start. Any suggestions?
Thanks,
Albert
How about:
var myText = ...; // Input text
var lines = myText.split("\n");
var numLines = lines.length;
var i;
var currentSection;
var sections = Array();
var phrases = Array();
// parse phrases
for (i = 0; i < numLines; i++) {
var line = lines[i];
if (line.indexOf('#') == 1) {
// start of e.g. time section, handled in nex loop
break;
} else {
// phrase
phrase.push(line);
}
}
// parse sections
for ( ; i < numLines; i++) {
var line = lines[i];
if (line.indexOf('#') == 1) {
// start of next section, handled in nex loop
currentSection = line;
sections[currentSection] = new Array();
} else {
// add section entry
sections[currentSection].push(line);
}
}
It's not too sophisticated, but does the job. Didn't test it though, but something like this should work. And where is the fun if this'd just work ;D
No issue at all. Split the textbox value into an array based on line break characters. Then, go through the array one element at a time, sorting the values into variables for each section. Finally, use JavaScript's random number generator to randomly determine which of each group to select. Output to the user by assigning the value to an HTML element.

Categories

Resources