Zoom effect on text/words on mouseover - javascript

I can't find a solution to my problem elsewhere so, here it is:
The fuctionality i want is, when a user hovers the mouse over a set of 3-4 words, it gets zoomed.
So far I only managed to do this hardcoded, I mean that I splited all the text with span elements and added fuctionality in css. But I know this is bad:
Gets messy/looks ugly
Can't do this at huge text's
It's hard to add more text
So I want a way to do this "span separate text" automatically, maybe with regular expressions. But I don't know how.
Here it is what i came up so far
body {
padding: 10px;
margin: 10px;
}
h1 {
font-family: Arial;
font-size: 20px;
color: #000000;
}
h1 span {
display: inline-block;
-webkit-transition: all 0.1s ease-out;
}
h1 span:hover {
-webkit-transform: scale(1.5);
color: yellow;
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
cursor: pointer;
}
<h1>
<p>Yesterday i went out at a festival where i ate a lot of corn</p>
<!--I just split the text with span elements. -->
<p><span>Yesterday i went</span> <span>out at a festival</span> <span>where i ate</span> <span>a lot of corn</span></p>
</h1>

I don't really know about the zoom, but If you want to split your text into groups of 3 words to wrap them with a , you could use jquery and do something like:
var p = $('p'); //selector
var originalText = p.text().split(' '); //original text between <p></p>
var spannedText = [];
for (var i = 0; i < originalText.length; i += 3) { //per group of 3 words
spannedText[i] = ('<span>' + originalText.slice(i,i+3).join(' ') + '</span>'); //wrap the 3 words with <span></span>
}
$(p).html(spannedText.join(' ')); //display the new wrapped text
https://jsfiddle.net/hjmoc1mq/3/

Related

How to change color of text in a textarea

I have a textarea and when I type something, for some words the color should change.
For example, if the typed text is next one: He went to the market to buy an apple
The "market" word should become green
The "apple" word should become red
This is my current code:
var str = 'market';
var value = str.includes('market');
if (value == str) {
document.getElementById("text").style.color = "green";
} else {
document.getElementById("text").style.color = "red";
}
<textarea rows="9" cols="100" id="text" onClick="changeText();"></textarea>
Unfortunately, you can't add markup inside a textarea, but here is an idea you could take as a starting approach, it comes from this link. The approach will be based on this:
The basic idea is to carefully position a <div> behind the <textarea>. Then JavaScript will be used to copy any text entered into the <textarea> to the <div>. A bit more JavaScript will make that both elements scroll as one. With everything perfectly aligned, we can add markup inside the <div> to give colors to some particular words, and we going to set text color to transparent on the <textarea>, completing the illusion.
Base Implementation:
// Initialization.
const colorMap = {"apple": "red", "market": "green", "banana": "orange"};
let textArea = document.getElementById("myTextArea");
let customArea = document.querySelector(".custom-area");
let backdrop = document.querySelector(".backdrop");
// Event listeners.
textArea.addEventListener("input", function()
{
customArea.innerHTML = applyColors(textArea.value);
});
textArea.addEventListener("scroll", function()
{
backdrop.scrollTop = textArea.scrollTop;
});
function applyColors(text)
{
let re = new RegExp(Object.keys(colorMap).join("|"), "gi");
return text.replace(re, function(m)
{
let c = colorMap[m.toLowerCase()];
return `<spam style="color:${c}">${m}</spam>`;
});
}
.backdrop, #myTextArea {
font: 12px 'Open Sans', sans-serif;
letter-spacing: 1px;
width: 300px;
height: 100px;
}
#myTextArea {
margin: 0;
position: absolute;
border-radius: 0;
background-color: transparent;
color: transparent;
caret-color: #555555;
z-index: 2;
resize: none;
}
.backdrop {
position: absolute;
z-index: 1;
border: 2px solid transparent;
overflow: auto;
pointer-events: none;
}
.custom-area {
white-space: pre-wrap;
word-wrap: break-word;
}
<div class="container">
<div class="backdrop">
<div class="custom-area">
<!-- Cloned text with colors will go here -->
</div>
</div>
<textarea id="myTextArea"></textarea>
</div>
Note this is just a base approach to understand the underlying idea. But with some work on it, maybe you can get a generalized version. For example, by now, the textarea can't be resizable. But maybe you can detect that event and rezise the backdrop dinamically.
You can style the text in the textarea as a whole, but since a textarea does not have sub-elements such as or you cannot give separate text within that textarea separate styles.
on the other hand if you had a separate div displaying a copy of the text you could in the innerHTML of the div assign
apple
to replace the word apple in the .. but the text in the textarea would remain unchanged.. possibly overlay div on top of the textarea but hidden until text is entered in the textarea. Not certain of the precise code to do that piece or if it would work. but at least it is a viable logic chain that I hope may help you find a solution.
To color a specific word from that text you must wrap that word with a html tag. But textarea doesn't support html tag.
You can do it outside of the textarea field.

CSS selector and border issue

I would like to achieve the following with my code:
Issue (a) Change only Click Here to be surrounded by a box.
Issue (b) The border for the box in (a) should disappear and reappear.
Currently, I face the following issues with my code:
Issue (a)
For (a), my code does not just change Click Here to be surrounded by a box. It also changes Pinterest to be surrounded by a box. I believe the issue is with selecting the top level ul but I have not succeeded in doing so.
Relevant CSS code
.cover-buttons ul:first-of-type li:nth-last-child(5) a {
color: black;
border: 1px solid black;
padding: 14px 18px!important;
font-weight: 400;
line-height: 17px;
font-size: 12px;
display: inline-block;
transition: all .2s ease;
overflow: hidden;
border-radius: 2px;
box-sizing: border-box;
list-style-type: none;
font-family: 'Varela Round', 'Poppins', sans-serif;
}
Issue (b)
For (b), I can't seem to get the box border to blink.
Relevant Javascript code
$(function(){
var count = 0, $input = jQuery('.buttons.medium.button-outlined').not('.add-review, .bookmark, .show-dropdown, .sn-share'), interval = setInterval(function() {
if ($input.hasClass('blur')) {
$input.removeClass('blur').addClass('focus'); ++count;
} else {
$input.removeClass('focus').addClass('blur');
}
if (count === 3) { clearInterval(interval); }
}, 2000);
});
Relevant CSS code
.focus {
border: 1px solid white;
}
.blur {
border: 1px solid black;
}
The strange thing about issue (b) is that it seems to work when I change the background-color as shown here: https://jsfiddle.net/75nvLs4x/12/. However, when I try to modify the border thickness it does not work.
Full script including HTML is included here: https://jsfiddle.net/75nvLs4x/14/
Thank you for your help.
Issue A
Your selector is: .cover-buttons ul li:nth-last-child(5) a this will affect any ul inside .cover-buttons. As there are two uls that have li:nth-last-child(5), both have the li:nth-last-child applied.
You can fix this by saying only the ul that's directly inside .cover-buttons and only the li directly inside that ul
.cover-buttons > ul > li:nth-last-child(5) a
Issue B
Your border issue is due to specificity - the border in the .cover-buttons ul li:nth-last-child(5) a section is more specific than just .focus so is always used. You could add !important to the border inside .focus, but that's not best practice - instead, remove the border from the main block and it works fine.
Updated fiddle: https://jsfiddle.net/75nvLs4x/18/

Edit cursor not displayed on Chrome in contenteditable

When you open this page (see Live demo) with Chrome :
<span id="myspan" contenteditable=true></span>
CSS :
#myspan { border: 0; outline: 0;}
JS :
$(myspan).focus();
the contenteditable span has focus (you can start to write things and you will see that it already had focus), but we don't see the "I" edit cursor.
How to make that this cursor is displayed ? (Remark : outline:0 is needed, as well as the fact that the span is empty even with no white space).
Note : With Firefox, the cursor is displayed.
The problem is that spans are inline elements. Just add display:block; to your CSS and it will fix the problem.
$(myspan).focus();
#myspan {
border: 0;
outline: 0;
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<span id="myspan" contenteditable=true></span>
I added padding to the left and the cursor appears.
#myspan
{
border: 0;
outline: 0;
min-width: 100px;
height: 30px;
padding-left: 1px;
}
Demo in jsFiddle
.cont_edit {
outline: 1px solid transparent;
}
This just has to do with the way an empty ContentEditable area is rendered. To prove it's not about the focus, add some text to your editable div, and then delete it. When the last character is gone, the cursor will disappear
From the question Setting the caret position to an empty node inside a contentEditable element
The selection/range model is based around indexes into text content, disregarding element boundaries. I believe it may be impossible to set the input focus inside an inline element with no text in it. Certainly with your example I cannot set focus inside the last element by clicking or arrow keys.
It almost works if you set each span to display: block, though there's still some highly strange behaviour, dependent on the existence of whitespace in the parent. Hacking the display to look inline with tricks like float, inline-block and absolute position make IE treat each element as a separate editing box. Relative-positioned block elements next to each other work, but that's probably impractical.
You could also try adding a zero-width character like ​
document.getElementById('myspan').focus();
#myspan {
border: 0;
outline: 0;
}
<span id="myspan" contenteditable="true">​</span>
The solution was to change <span> to <div> (I've seen that this solves many contenteditable problems in other questions here and there) + to add a min-width.
Indeed, with the following code, the size of the <div> would be 0px x 18px ! That explains why the caret (edit cursor) would be hidden !
HTML
<div id="blah" contenteditable=true></div>
CSS
#blah {
outline: 0;
position: absolute;
top:10px;
left:10px;
}
JS
$("#blah").focus();
Then, adding
min-width: 2px;
in the CSS will allow the caret to be displayed, even with Chrome : http://jsfiddle.net/38e9mkf4/2/
The issue I faced on Chrome v89.0.4389.90 was that contenteditable fields would sometimes show the blinking caret on focusin and sometimes not. I noticed it always blinks when there's already content in the field before focusing. It's when there's no content that the sometimes will/won't behavior occurs.
At first, I thought there must be some conflicting event handler that's erratically taking focus away. I disabled all my event binds and timers. Still the same erratic behavior. Then I thought it might be some conflicting CSS, so I disabled all stylesheets. At least now the behavior was consistent: the caret blinks 100% of the time when the field has content; the caret does not blink 100% of the time when the field has no content.
I enabled binds and stylesheets again. My div was already set to display: block; with min-width, min-height, and padding set in the final computed style set. None of the other answers here worked. I do have a placeholder on :empty:before that was a possible culprit. I commented that out. Now the behavior was consistent again, same as if the stylesheet was off. Oddly enough, the runnable snippet on SO works with the same computed CSS stack. I want to keep the placeholder, so it requires further research with my actual codebase...
The only solution I could get to work 100% of the time with my current issue involved forcibly placing the caret inside empty fields by creating a blank space and removing it immediately afterwards. Best I can do for a workaround until debugging the root cause.
//force caret to blink inside masks
let force_caret = function() {
if (!this.textContent) {
this.textContent = ' ';
let r = document.createRange(),
s = window.getSelection();
r.setStart(this.childNodes[0], 0);
r.collapse(true);
s.removeAllRanges();
s.addRange(r);
this.textContent = '';
}
}
//binds
let els = document.querySelectorAll("[contenteditable]");
for (let i = 0; i < els.length; i++) {
els[i].addEventListener('focusin', force_caret, false);
}
/* styles irrelevant to the issue, added for visual assist */
:root {
--b-soft: 1px solid silver;
--bs-in: inset 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px rgba(255, 255, 255, 0.1);
--c-soft: gray;
--lg-warm: linear-gradient(30deg, rgb(254, 250, 250), #eedddd);
}
body {
font-family: system-ui, -apple-system, -apple-system-font, 'Segoe UI', 'Roboto', sans-serif;
}
[contenteditable] {
outline: initial;
}
[contenteditable][placeholder]:empty:before {
content: attr(placeholder);
color: var(--c-soft);
background-color: transparent;
font-style: italic;
opacity: .5;
font-size: .9em;
}
.input {
border-bottom: var(--b-soft);
padding: .2em .5em;
}
.input_mask {
display: flex;
align-items: baseline;
color: var(--c-soft);
}
.mask {
box-shadow: var(--bs-in);
border-radius: .2em;
background: var(--lg-warm);
font-weight: 500;
border: 1px solid transparent;
text-transform: uppercase;
/* styles possibly relevant to the issue according to other proposed solutions */
margin: 0 .4em .1em .4em;
padding: .2em .4em;
min-width: 3em;
min-height: 1em;
text-align: center;
}
<div data-type="tel" data-id="phone" class="input input_mask">
<span>+1 (</span>
<div maxlength="3" contenteditable="true" placeholder="111" class="mask"></div>
<span>)</span>
<div maxlength="3" contenteditable="true" placeholder="111" class="mask"></div>
<span>-</span>
<div maxlength="4" contenteditable="true" placeholder="1111" class="mask"></div>
<span>x</span>
<div maxlength="5" contenteditable="true" class="mask"></div>
</div>
Add a CSS style of
min-height: 15px;
you may also need
display: block;
to your contenteditable="true" tag
For me setting it content of contenteditable div to <br> works. I tried setting it to nbsp; but that creates extra character space in the div before i start editing. So, i choose this:
<div id="blah" contenteditable=true><br></div>
over:
<div id="blah" contenteditable=true>nbsp;</div>
Hope this helps.
I use Chrome and your Code works fine.
Try to use cursor: text; in your CSS. See here

Unselectable text in div to selectable leaflet

As the title says, I used this (Example)
More specifically I used the info box in top right corner(US Population Density). I modified it to show me some more info onclick etc. Now I have a problem, this div is unselectable. I need to be able to select text (for copy text purpose), instead of selecting the text, it just moves the map. Is there a "quite easy solution" to it, because I can't find the right place. Maybe somehow in CSS?
.info {
position: fixed;
right: 0;
bottom: 23px;
padding: 6px 8px;
font: 14px/16px Arial, Helvetica, sans-serif;
background: white;
background: rgba(255,255,255,0.8);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
border-radius: 5px;
/*-webkit-user-select: text;
-moz-user-select: text;
user-select: text;
-webkit-user-drag: text;*/ /*Tried this, didn't work. */
}
.info h4 {
margin: 0 0 100px;
color: #777;
}
Edit: I should add, when I start selecting on other div, then I can select it. As seen on picture, if I start selecting on div where my layers are shown, I can select text, but if I try to directly select from that div (on top right corner of picture) it moves map. I know picture is cut quite small, hope it gives the info/vision wha needed.
Picture: http://www.upload.ee/image/3839164/asd.PNG
Thanks,
Kristjan
Use disableClickPropagation in your controls onAdd method.
onAdd: function (map) {
var container = L.DomUtil.create('div', 'my-custom-control');
container.innerHTML += 'This is an example using disableClickPropagation.';
L.DomEvent.disableClickPropagation(container);
return container;
}
http://jsfiddle.net/9q756/1/
You can fix this by re-enabling pointer-events on the bottom en top control-containers. These get set to none in leaflet.css:
https://github.com/Leaflet/Leaflet/blob/master/dist/leaflet.css#L93
You need to overrule this in your own custom CSS:
.leaflet-top,
.leaflet-bottom {
pointer-events: all;
}

Javascript Object String Value - HTML code being rendered when it should be hidden

I have a js object (it's actually an object within another object):
item2 : {
itemTitle : "This is item 2",
itemContent : "To me, in France, a friend speaks from America. The energy that brings me his voice is born of dammed-up waters a thousand miles from where he sits. <p> The energy I burn up in listening to him is dispensed in the same instant by a lake formed in the River Yser..."
},
The two items (itemTitle and itemContent) are displayed in respective p elements within divs, they make up an accordion display (titles displayed, content hidden until title is clicked).
It works fine except when I add content with html tags in it, in this case a p tag. The first paragraph is hidden, the second one is displayed, but since both paragraphs are encased in a p element whose display is set to none I would think both should be hidden.
So I am thinking the browser (Firefox latest) is seeing the p element and rendering that second paragraph. I thought maybe if I closed off the second p element that would take care of it. But no dice.
I've spent the last two years doing objective-c stuff so my css/js/html foo is off a bit. Why would the browser display this if it is within a element that is hidden?
Here is how I am generating the html:
//loop through the accordian properties and build out the html code for them
var i = 0;
for (thisItem in accordian.accordianItems) {
i++;
var thisItemData = accordian.accordianItems[thisItem];
var thisItemCode = "<div id=\"itemContainer\" itemID=\"item_" + i.toString() + "\">" + "<div id=\"itemTitle\"><p class=\"title\">" + thisItemData.itemTitle + "</p></div>" + "<div id=\"itemContent\"><p class=\"content\">" + thisItemData.itemContent + "</p></div>" + "</div>";
accordianCode += thisItemCode;
}
//push the code out to our container div
$("#accordianContainer").html(accordianCode);
my css:
#itemContainer {
margin: 0 0 5px 0;
}
.title {
margin: 0 0 2px 0;
height: 20px;
vertical-align: middle;
background-color: #39F;
color: #fff;
font-family: Arial, Geneva, sans-serif;
font-size: 14px;
font-weight: 900;
}
.title a {
color: #fff;
text-decoration: none;
}
.content {
margin: 0 0 0 5px;
color: #333;
font-family: "Times New Roman", Times, serif;
font-size: 12px;
font-weight: 200;
display: none;
}
Any help would be appreciated.
And yes, I did spell accordion wrong throughout my code, I fixed it there but not here. : P
Edit: Switched the p tags for a br and the problem went away. So my new guess is something with a p being a block item? I guess I could style the br tag but I'd rather have the p's, any suggestions?
Only inline elements are allowed in a p. See http://www.w3.org/TR/html401/struct/text.html#h-9.3.1. The browser is choosing to render it as its own element, which takes it out of the hidden p.

Categories