How to re-order and animate text in jquery? - javascript

Firstly, I've made a CODEPEN or jsfiddles
Background:
Ok I have a span tag within a few header tags h1,h2,h3. Inside that spantag is the word
experience which is spelled backwards like so:
<h3>for <span class="hover-spell">ecneirepxe</span>.</h3>
Question
I'm unsure on the best way to approch this but I would like on hover:
reorder to spell experience correctly
if possible animate them overlapping another while re-ordering
I have no idea how to do this but I keep thinking regex, with arrays but this feels overly complicated and I really don't know anything about regex and proper array sorting. Any information to lead me in the right direction would be most appreciated. Or an edit to the codepen or jsfiddles would be so excellent.

One possible solution is to use css to accomplish this. This solution doesn't animate the transition, it just changes the order of the letters. Add this to your css:
.hover-spell:hover{
direction: rtl;
unicode-bidi: bidi-override;
}
Edit: Thanks to Marcel Gwerder for pointing out that it's not possible to animate the direction property
I found this answer, in another post (it goes through a given string of text and wraps each character in a span then assigns transiton styles to each), that may help with a jquery solution.

I've just tried to set up something animated with jquery, it's a bit tricky to get a fancy looking animation. But that one doesn't look too bad (DEMO).
var expElem = $(".hover-spell");
var exp = expElem.text();
var run = false;
expElem.empty();
for(var i = 0; i <= exp.length; i++) {
expElem.append('<span>'+exp.charAt(i)+'</span>');
}
expElem.mouseover(function() {
if(run === true) return false;
run = true;
var stepDuration = 300;
var counter = 0;
(function anim(){
if(counter == exp.length -1) return false; //Remove -1 to get last "e" animated
counter++;
var nth = exp.length;
var elem = $('span:nth-child('+nth+')', expElem);
elem.slideUp(stepDuration, function() {
(function() {
if(counter == 1) return elem.prependTo(expElem);
else return elem.insertAfter($('span:nth-child('+(counter-1)+')', expElem));
})().slideDown(stepDuration, anim);
});
})();
});
To get it working with hover(including mouseleave) is a bit more complicated. You could also try something with storing the position and then slide them over each other but again a bit more complicated.

<span id = "spell">olleh</span> //hello in reverse
<script type="text/javascript">
var newText;
var text = null;
text = document.getElementById("spell").innerHTML;
for (var i = text.length - 1; i >= 0; i--) {
if (i == text.length - 1) {
newText = text.substr(i, 1);
}
else {
newText = newText + text.substr(i, 1);
}
}
alert(newText);
</script>
write this script in body tag...

Related

Wrap a row of blocks in the middle instead of end (CSS/JS/jQ)

How can a row of inline-blocks be wrapped by a shrinking parent resulting in equal (or almost equal) rows?
So instead of wrapping like this:
wrap like this:
And if there's an uneven number of blocks, like this:
You can use CSS Grid grid-template-columns and #media (if you want to wrap by screen-width) or in JS with docment.getElementById('bottomblocks').style.gridTemplateColumns variable to achieve this. (If I understand correctly)
I wrote here an example with JS:
https://jsfiddle.net/Lhbqdt2z/
You can learn about it where I started with it: Coding Tech Talk
Or just from W3Schools
Moz://a has a good examples here
He is something fun I just wrote... Assuming you want an "enhanced wrap" behavior that wraps by the half of its childs, instead of the normal floating.
It's more an "essay" than a strong best practice answer. ;)
$(window).on("load resize",function(){
$(".container div").css({"clear":"initial"});
var wrapped = false;
var wrappedAt = 0;
var wrappedNtimes =0;
var pos = $(".container div").first().offset();
var n = $(".container div").length;
$(".container div").each(function(index){
if(!wrapped){
if( ($(this).offset().top != pos.top)){
console.log("Wrapped at "+index+" out of "+n);
wrapped = true;
wrappedAt = index;
wrappedNtimes++;
}
pos=$(this).offset();
}
});
if(wrapped){
// Force enhanced wrapping... .oO(lol)
console.log("--"+wrappedAt+"--");
var half = Math.ceil(n/(wrappedNtimes+1));
$(".container div").each(function(){
if( $(this).index() != 0 && ($(this).index())%half == 0){
$(this).css({"clear":"left"}); // zero-based.
}
});
}
});
CodePen demo
Here's a solution that inserts <br> elements at the ends of each row. This code can be placed into a function to run whenever you need to wrap the blocks.
// Make sure that the last row of blocks doesn't have 2 less blocks than all
// the previous rows. Assume that all blocks are equal size.
var blocks = sharing.find('.btn');
//what's the parent width
var parentWidth = blocks.parent().width();
//how many blocks can fit in such a width
var maxNumOfBlocksInOneRow = Math.floor(parentWidth / blocks.outerWidth(true));
//repeatable code
var calcNumOfBlocksInLastRow = function(){
var lastRowFull = blocks.length % maxNumOfBlocksInOneRow ? false : true;
if (lastRowFull) {
return maxNumOfBlocksInOneRow;
} else {
return blocks.length % maxNumOfBlocksInOneRow;
}
}
//do we have more blocks than row's maximum?
if (blocks.length > maxNumOfBlocksInOneRow) {
//how many blocks would the last row have
var numOfBlocksInLastRow = calcNumOfBlocksInLastRow();
//if the last row is missing more than 1 block, try with 1 less block in each row
while (numOfBlocksInLastRow < maxNumOfBlocksInOneRow - 1) {
maxNumOfBlocksInOneRow--;
numOfBlocksInLastRow = calcNumOfBlocksInLastRow();
}
//insert <br> at the end of each row
jQuery('<br>').insertAfter(blocks.filter(':nth-child(' + maxNumOfBlocksInOneRow + 'n)'));
}

Javascript body text change when bg color changes NOT A DUPLICATE

This is very similar to a previous question of mine but not the same, I am trying to learn the subtleties of Javascript.
Below is my code, I need to change the text in the body when the image changes, I think I am getting there and working it out but as you can see below, it is not yet exacly how i want it.
I would be very very grateful if you can help me.
<script>
$(document).ready(function() {
element = $("#testElement");
i = 1;
setInterval(function() {
element.removeClass("color"+i);
console.log(i);
i++
if (i == 5) {
i = 1;
}
element.addClass("color"+i);
}, 1000);
})
var arr = ['hi','hello ','how ','are ','you '];
changeColorAndText($('#testElement '), 0);
</script>
Thank you wonderful people in advance, you have taught me lots so far.
Working jsfiddle example
<div id="testElement">This is your element</div>
<script>
$(document).ready(function() {
element = $("#testElement");
var arr = ['hi','hello ','how ','are ','you '];
var i = 1; // localizing scope of this variable (not necessary)
setInterval(function(){
element.removeClass("color"+i);
console.log(i);
i++; // missing semicolon here
if(i == 5) i = 1;
element.addClass("color"+i);
element.text(arr[i]); // change the inner text of element
}, 1000);
});
</script>

Attach a char limit to each comment area jQuery

I am having some issues, and cannot solve this, since I cannot get my head around this. It's kinda a big issue. I want to dynamically attach a char limit and a submit comment button to each post, and each commentArea to be a form of its own. Any help is welcome, I want to make it dynamic, independent from each other.
Thanks!
$(".comment-box").keyup(function(){
var text_max = 140;
var length_reached = $(this).val().length;
var remaining = text_max - length_reached;
$('.counter').html(remaining);
if(remaining < 5 || remaining > text_max)
$(".btn").prop("disabled", true);
else
$(".btn").prop("disabled", false);
});
Here's my jsfiddle: http://jsfiddle.net/3sCfG/25/
EDIT: Trying to make something similar to Twitter's Reply section which is attached to each micropost on their Timeline, but not sure if IDs should be used, found IDs on Twitter's, but not fully clear. I am trying to make a similar comment box to that of Twitter's.
have a look here: http://jsfiddle.net/3sCfG/38/
CODE
$(".comment-box").keyup(function () {
var parent = $(this).parent();
var text_max = 140;
var length_reached = $(this).val().length;
var remaining = text_max - length_reached;
$(parent).find('.counter').html(remaining);
if (remaining < 5 || remaining >= text_max)
$(parent).find(".btn").prop("disabled", true);
else
$(parent).find(".btn").prop("disabled", false);
});
hope it helps
EDIT cleaned up code a little
Your problem is using classes (hence affecting multiple elements) without specifying which part of the DOM you're trying to update.
The simplest solution is to add a "search context" to the selectors in your handler.
I've used $(selector, parent) as a shorthand for $(parent).find(selector):
$(".comment-box").keyup(function() {
var parent = this.parentNode; // new
var text_max = 140;
var length_reached = this.value.length;
var remaining = text_max - length_reached;
$('.counter', parent).html(remaining);
$('.btn', parent).prop('disabled', (remaining < 5 || remaining >= text_max));
});
I've also refactored the .prop call, since:
if (condition) {
.prop('disabled', true);
} else {
.prop('disabled', false);
}
is exactly equivalent to:
.prop('disabled', condition);
and I changed the > text_max to >= text_max, since I presume the intent was to disable the "submit" button if there's no input.
See http://jsfiddle.net/alnitak/ATW9u/
Maybe add a data- attribute to text area and use that to set the max length?
<textarea class="comment-box" type="text" data-limit="10" placeholder="Write a comment"><textarea>
along with that, instead of referring to the counter with its class, navigate to it and reduce the no. of characters from it. (Like this)
$(this).next(".tools").find("span").html(remaining);
Gives the textareas the inpedendance you wanted to give them. Heres your updated fiddle : http://jsfiddle.net/3sCfG/28/

wrapping text words in new line

I'm using the below code for wrapping long text, entered by users in a text area for commenting:
function addNewlines(comments) {
var result = '';
while ($.trim(comments).length > 0) {
result += comments.substring(0,70) + '\n';
comments = comments.substring(70);
}
return result;
}
The problem is shown in the below screen shot. Any ideas on how to solve it? Can we use lastindexof(" ") method to get the last space in a substring to solve this issue logically? Can anyone tweak this little code to make it right?
I believe wrapping a text by CSS is a better solution however there is a link here which may be helpful wrap-text-in-javascript
by the way i remember there is a JQuery plugin for wrapping text google it too.
Try word-wrap: break-word in CSS.
The word-wrap property is well supported by browsers (even IE 5.5+).
More info here: https://developer.mozilla.org/en-US/docs/CSS/word-wrap
Sample usage: FIDDLE
Try one of these:
word-wrap:no-wrap;
word-wrap: break-word
It might solve your problem
The ones above only work 99% of the time. This is the only one that works for me 100%:
http://locutus.io/php/strings/wordwrap/
Hi just apply some css on text area like
style="word-wrap: break-word;"
I use this css code for displaying in Torch browser and it works
I've tried word-wrap:break-word;overflow:ellipsis;....etc, but didn't work.
#xxx{
width: 750px;
word-break: break-word;
}
After looking for the perfect solution using regex and other implementations. I decided to right my own. It is not perfect however worked nice for my case, maybe it does not work properly when you have all your text in Upper case.
function breakTextNicely(text, limit, breakpoints) {
var parts = text.split(' ');
var lines = [];
text = parts[0];
parts.shift();
while (parts.length > 0) {
var newText = `${text} ${parts[0]}`;
if (newText.length > limit) {
lines.push(`${text}\n`);
breakpoints--;
if (breakpoints === 0) {
lines.push(parts.join(' '));
break;
} else {
text = parts[0];
}
} else {
text = newText;
}
parts.shift();
}
if (lines.length === 0) {
return text;
} else {
return lines.join('');
}
}
var mytext = 'this is my long text that you can break into multiple line sizes';
console.log( breakTextNicely(mytext, 20, 3) );
I had the same issue, I solved it using the below function.
function wordWrap(message, lineSize, breakPoint){
let wordsArr = message.split(" "),
wordsLen = wordsArr.length,
finalMsg = "",
linesArr = [""],
currLine = 0;
for(let i=0; i< wordsLen; i++){
if(linesArr[currLine].length + wordsArr[i].length > lineSize){
currLine +=1;
linesArr[currLine] = wordsArr[i] + " ";
} else {
linesArr[currLine] += wordsArr[i] + " ";
}
}
let linesLen = linesArr.length;
for(let i=0; i<linesLen; i++){
finalMsg += linesArr[i] + breakPoint;
}
return finalMsg.trim();
}
Hope this helps.

display alert when mouse hovers over word in text

I have been struggling with this for a few days. I need somebody to steer me in the right direction. I have been searching on the web. I am not sure if I took the right approach. What I need is that each time a person hovers over a particular keyword, it should display an alert box. In this example the word is else. When I run the code it does not give any errors and does not display anything when mouse hovers on the word.
function on_func2()
{
var searchString = 'else';
var elements = document.getElementById('paragraph2');
for (var i = 0; i < elements.length; i++)
{
if (elements[i].innerHTML.indexOf(searchString) !== -1)
{
alert('Match');
break;
}
}
}
I would do something like this:
It will go through and find all else words, and wrap them in a span with a listener bound:
<p id="hello">What else would you say?</p>
-
​var hello = document.getElementById('hello');
var str = hello.innerHTML;
str = str.replace(​​​ /\b(else)\b/g, '<span onmouseover="func1()">$1</span>' );​​​​​​​​​​​​​​​​​​​
hello.innerHTML = str;
function func1() {
alert('there');
}
Check out the fiddle.
Using jQuery lettering plugin
<p class="word_split">if you were not there, else I would not have won.<p>
$(".word_split").lettering('words');
$('.word_split').mouseover(function(event) {
var word=event.target.innerHTML;
if (word == "else")
alert("Yep");
});
here's a demo: jsFiddle

Categories