I have a Google Maps map and have some MarkerWithLabels there. When the user hovers over the marker I want to show some additional information about the marker. E.g.
Not hovering => 10
Hovering => 10 people
However, the bottom text should be in another color, so I thought I'd be best using a span to change the text colors of the two texts. I've done this
googleMaps.event.addListener(marker, 'mouseover', function () {
var mouseoverImg = new googleMaps.MarkerImage('/images/pin_xl.png', null, null, null, new googleMaps.Size(53, 72));
this.setIcon(mouseoverImg);
this.set('labelClass' ,'' );
this.set('labelContent', "<p class='startContinentCountryBigTop'>" + poiObject.count + "</p><br><p class='startContinentCountryBigBot'>" + cities + "</p>");
this.set('labelAnchor', new googleMaps.Point(20, 65));
});
googleMaps.event.addListener(marker, 'mouseout', function () {
this.setIcon(markerImage);
this.set('labelContent', poiObject.count);
this.set('labelAnchor', new google.maps.Point(11, 42.5));
this.set('labelClass' ,'startContinentCountrySmall' );
});
The problem is, that with the span, as soon as I mouseover the marker the mouseout function is also triggered. So the Marker get's repeatidly smaller/bigger. When I remove the span and am just using the text it works without problems, but the bottom text needs to have a different color and a different text-size. What are some workarounds to this problem?
These are my css classes
span {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
.startContinentCountrySmall {
cursor: pointer;
color: #bdc3c7;
font-size: 14pt;
font-weight: 100;
}
.startContinentCountryBigTop {
cursor: pointer;
color: #bdc3c7;
font-size: 14pt;
font-weight: 100;
width: 100%;
}
.startContinentCountryBigBot {
cursor: pointer;
color: #f69d00;
font-size: 10pt;
font-weight: bold;
text-transform: uppercase;
width: 100%;
}
Some additional information: It seems to be the problem, that you can't add HTML Elements to a MarkerWithLabel. Even when I created a Node like this
var newDiv = document.createElement("span");
newDiv.className = "startContinentCountryBigTop";
newDiv.innerHTML = poiObject.count;
it doesn't work. The problem occurs when you hover over the text on the marker that has the HTML tags wrapped
I hope you understand the problem. The mouseover and mouseout listener are fired at the same time all the time as soon as I start using span for the text on the marker. Any ideas?
Related
For a chat app, I need to change the color of words starting with a special character, #word inside an input tag, i.e:
Hello #John how are you?
the part #John should change color inside the input, i.e:
Hello #John how are you?
It works after it's posted, but that's obviously another code. I want it to highlight words (#mention) by changing its color right in the input or textarea Element.
Color specific text inside a textarea-alike element
One 5y old idea (Highlight syntax in contenteditable) would be to:
let the user type into a contenteditable DIV with transparent color but visible caret, then get and modify the content on the fly as-you-ype to an underlying DIV, used as a markup highlighter.
Basically:
On "input" event get the editable innerHTML, do some String.prototype.replace() with a regular expression that matches #mentions on the contenteditable value and replace i.e: #John with <span class="mention">#John</span>
Write the result as HTML to the underlying (highlighter) DIV element.
This way you're not replacing and creating any child SPAN elements in the area where the user is typing, but actually on the underlying one.
const colorMention = (elText, elPre) => {
elPre.innerHTML = elText.innerHTML.replace(/(?<=^| )#\p{L}+/gu, "<span class='mention'>$&</span>");
};
const scrollMirror = (elText, elPre) => {
elPre.scrollTo(elText.scrollLeft, elText.scrollTop);
};
const handleKey = (ev, elText, elPre) => {
if (ev.key === "Enter" && !ev.shiftKey) {
// prevent Enter key behavior (new-line)
ev.preventDefault();
// Check message to send...
const message = elText.innerHTML;
if (!message.trim()) {
return; // Nothing to submit. Message is empty
}
// YOUR SUBMIT LOGIC GOES HERE:
console.log(message);
// Clear fields:
elText.innerHTML = "";
elPre.innerHTML = "";
} else {
// Any other key: (scroll areas is necessary)
scrollMirror(elText, elPre);
}
};
document.querySelectorAll(".message").forEach(el => {
const elText = el.querySelector(".text");
const elPre = el.querySelector(".pre");
elText.addEventListener("scroll", () => scrollMirror(elText, elPre));
elText.addEventListener("keyup", () => scrollMirror(elText, elPre));
elText.addEventListener("input", () => colorMention(elText, elPre));
elText.addEventListener("keydown", (ev) => handleKey(ev, elText, elPre));
// Init:
colorMention(elText, elPre);
scrollMirror(elText, elPre);
});
* {
margin: 0;
box-sizing: border-box;
}
body {
font: 16px/1.3 sans-serif;
}
.message {
display: block;
border: 1px solid #888;
position: relative;
width: 100%;
border: 1px solid #ccc;
}
.message .pre,
.message .text {
border: 0;
overflow: scroll;
overflow-x: hidden;
font: inherit;
padding: 10px;
height: 5rem;
resize: none;
width: 100%;
white-space: break-spaces;
word-wrap: break-word;
}
/* The overlay contenteditable with transparent text but visible caret */
.message .text {
position: relative;
background: transparent;
outline: none;
/* transparent color */
color: transparent;
/* but visible caret */
caret-color: black;
}
/* The underlaying element with colors */
.message .pre {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
/* Prevent text selections */
user-select: none;
}
.mention {
color: fuchsia;
}
<div class="message">
<div class="pre"></div>
<div class="text" contenteditable spellcheck="false">Hi #Roko, how are you today?</div>
</div>
<br>
Chat tips:<br> Use <code>#username</code> to mention a user.<br> Use <kbd>Enter</kbd> to send.<br> Use <kbd>Shift</kbd>+<kbd>Enter</kbd> to go to a new line.<br>
Regarding the regular expression for matching mentions:
/(?<=^| )#\p{L}+/gu
here's a Regex101.com example with description, and a related answer.
This question already has answers here:
What do querySelectorAll and getElementsBy* methods return?
(12 answers)
Closed 2 years ago.
my code works fine I just need to switch between two colors white and black I need help to modify the JavaScript code to turn switch between white and black colors.
-CSS
<style>
h1 {
color: green;
}
/* toggle in label designing */
.toggle {
float: none;
position : fixed ;
display : inline-block;
width: 80px;
height: 38px;
background-color: grey;
border-radius: 30px;
border: 2px solid white;
top: 6px;
left: 896px;
}
/* After slide changes */
.toggle:after {
content: '';
position: absolute;
width: 38px;
height: 35px;
border-radius: 50%;
background-color: white;
top: -1px;
left: 0px;
transition: all 0.5s;
}
/* Toggle text */
p {
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
}
/* Checkbox cheked effect */
.checkbox:checked + .toggle::after {
left : 38px;
}
/* Checkbox cheked toggle label bg color */
.checkbox:checked + .toggle {
background-color: #5ad94d;
}
/* Checkbox vanished */
.checkbox {
display : none;
}
</style>
-HTML
<input class='checkbox' id='switch' type='checkbox'/>
<label class='toggle' for='switch'>
<p>ON OFF</p>
</label>
-Javascript
<script>
document.getElementById("switch").addEventListener('click', function(){
document.getElementsByClassName("mainWrapper fullWidth")[0].style.backgroundColor = document.getElementById("switch").toggle ? "white" : "black";
});
</script>
again
my code works fine I just need to switch between two colors white and black I need help to modify the JavaScript code to turn switch between white and black colors.
any ideas ??? thank!
getElementsByClassName() returns an html collection object. It is a collection. If you want to find the first element with the class, you need to use the index [0] like below -
document.getElementById("tog-bg").addEventListener('click', function(){
document.getElementsByClassName("mainWrapper")[0].style.backgroundColor = document.getElementById("tog-bg").checked ? "white" : "black";
});
If you want to do this for all elements with the specified class, then you can loop it like below -
document.getElementById("tog-bg").addEventListener('click', function(){
for(let i = 0; i < document.getElementsByClassName("mainWrapper").length; i++){
document.getElementsByClassName("mainWrapper")[i].style.backgroundColor = document.getElementById("tog-bg").checked ? "white" : "black";
}
});
I am using the ternary operator instead of if else condition in the above snippet. Also, I have replaced the change event with click event in the listener.
getElementByClassName returns collection
So code should be
//add [0] to both getElementByClassName
document.getElementsByClassName("mainWrapper")[0].style.backgroundColor
Also there isn't any class mainWrapper here so you should create a parent div with class mainWrapper
This worked for me in firefox (not styled, but functional) :
document.getElementById("tog-bg").onclick = function(){
var e;
if( (e = document.getElementById("tog-bg")).hasAttribute('checked')) {
var w = document.getElementsByClassName("mainWrapper ");
for(i=0;i<w.length;++i)
{
w[i].style.backgroundColor = "black";
}
e.removeAttribute('checked');
} else {
var w = document.getElementsByClassName("mainWrapper ");
for(i=0;i<w.length;++i)
{
w[i].style.backgroundColor = "white";
}
e.setAttribute('checked','');
}
};
I'm new to programming in general. I'm learning HTML/CSS/Javascript atm.
I created a simple script that allow the user to change the font size of the paragraph element.
I tired my code is jsFiddle and it works fine, but when I copied it into an HTML document and started the page. The HTML and CSS are functioning properly, but the problem is: JavaScript is not working. Btw I'm using Chrome as a browser.
Is something wrong with my HTML document..? I'm so confused!
Here is the working jsFiddle: https://jsfiddle.net/o60gtvh8/
My HTML file (Download link / Dropbox):
https://www.dropbox.com/s/tl0npr5omefntv4/Font%20size%20changer.rar?dl=0
HTML file code ( Copy of the code in the HTML file provided in the download link above ):
<!doctype html>
<html>
<head>
<style>
h1 {
color: blue;
font-size: 25px;
margin: 10px;
}
h2 {
color: blue;
font-size: 15px;
margin: 10px;
}
p {
margin: 10px;
}
a {
margin: 10px;
font-size: 15px;
text-decoration: none;
border: 1px solid grey;
background-color: cyan;
color: black;
padding: 3px;
}
</style>
<script>
function sizeChanger(size) {
return function() {
document.body.style.fontSize = size + 'px';
};
}
var size10 = sizeChanger(10);
var size20 = sizeChanger(20);
var size30 = sizeChanger(30);
document.getElementById('size-10px').onclick = size10;
document.getElementById('size-20px').onclick = size20;
document.getElementById('size-30px').onclick = size30;
</script>
</head>
<body>
<h1>Tiger</h1>
<h2>(From Wikipedia, the free encyclopedia)</h2>
<p>The tiger (Panthera tigris) is the largest cat species, most recognizable for
their pattern of dark vertical stripes on reddish-orange fur with a lighter underside.
The species is classified in the genus Panthera with the lion, leopard, jaguar, and snow leopard.
</p>
Font size 10
Font size 20
Font size 30
</body>
</html>
Move your JavaScript to the end of the page before the closing body element. As it stands now you're trying to access elements that don't exist yet. jsFiddle works because by default they wrap the JavaScript code in a window.onload event.
h1 {
color: blue;
font-size: 25px;
margin: 10px;
}
h2 {
color: blue;
font-size: 15px;
margin: 10px;
}
p {
margin: 10px;
}
a {
margin: 10px;
font-size: 15px;
text-decoration: none;
border: 1px solid grey;
background-color: cyan;
color: black;
padding: 3px;
}
<h1>Tiger</h1>
<h2>(From Wikipedia, the free encyclopedia)</h2>
<p>The tiger (Panthera tigris) is the largest cat species, most recognizable for
their pattern of dark vertical stripes on reddish-orange fur with a lighter underside.
The species is classified in the genus Panthera with the lion, leopard, jaguar, and snow leopard.
</p>
Font size 10
Font size 20
Font size 30
<script>
function sizeChanger(size) {
return function() {
document.body.style.fontSize = size + 'px';
};
}
var size10 = sizeChanger(10);
var size20 = sizeChanger(20);
var size30 = sizeChanger(30);
document.getElementById('size-10px').onclick = size10;
document.getElementById('size-20px').onclick = size20;
document.getElementById('size-30px').onclick = size30;
</script>
So there's nothing really wrong with your code (although you should avoid legacy DOM notation like document.body.style.fontSize) -- you're just executing it too early.
In Anki, I have a note type where one card is effectively a cloze deletion, however I am using other cards at the same time, with the cloze deletion field in it. I've tried to use javascript to replace everything within two '\'s and it appears to work in the preview when editing, but when the card appears during normal use, only the first line appears as plain text. I'm using the desktop linux program for editing, but would also like to be able to use it in AnkiDroid.
So the question is: what's the problem and how can I fix it?
Front Template:
<script>
function showDef() {
document.getElementById("def").innerHTML = '{{Bedeutung 1}}'.replace(/^[^\/]+\/\*!?/, '').replace(/\*\/[^\/]+$/, '');
};
var initial = false;
var beispiel = (function () {/*{{Beispiel 1}}*/}).toString().replace(/^[^\/]+\/\*!?/, '').replace(/\*\/[^\/]+$/, '');
var splitBeispiel = beispiel.split('\\');
document.write(splitBeispiel[0] + "<n id='cloze'>[...]</n>" + splitBeispiel[2]);
</script>
<p onclick="showDef()" id="def">Click to show definition</p>
Styling:
.card {
font-family: arial;
font-size: 20px;
text-align: center;
color: black;
background-color: white;
}
#cloze {
font-family: arial;
font-size: 25px;
text-align: center;
color: blue;
background-color: white;
}
#def {
font-family: arial;
font-size: 15px;
text-align: center;
color: green;
background-color: white;
}
#beispiel {
font-family: arial;
font-size: 15px;
text-align: center;
color: orange;
background-color: white;
}
Back Template:
<script>
var initial = false;
var beispiel = (function () {/*{{Beispiel 1}}*/}).toString().replace(/^[^\/]+\/\*!?/, '').replace(/\*\/[^\/]+$/, '');
var splitBeispiel = beispiel.split('\\');
document.write(splitBeispiel[0] + "<n id='cloze'>" + splitBeispiel[1] +"</n>" + splitBeispiel[2]);
</script>
<hr id=answer>
{{Singular Nominativ}}
The 'Beispiel 1' field in the following example is "ein kirchlicher, ein \gesetzlicher\ Feiertag"
Screenshot of editor preview:
Screenshot of test:
I guess, you should look for the solution here.
Avoid using document.write in your templates and use document.getElementById("HTMLidToReplace").innerHTML = '<b>' + your_var + '</b>';, for example. Hope it helps.
I have written a script to add a Pinterest button to most images on my site. The issue is that when someone has the Chrome Pin it extension enabled in their browser, the "pin it" button shows up twice for the user.
Is there anyway, in JavaScript, to check if the user has this extension enabled in their browser?
(function($) {
$(function() {
$('.container img').each(function() {
if ($(this).parent('a')) {
var $permalink = $(this).parent('a').attr('href');
}
else {
var $permalink = $(location).attr('href');
}
var $permalink = $(location).attr('href'),
$title = $('h1.product_name').text() || $('h2.header');
var $linkhtml = $('<a/>', {
'class':'pin-it-button pinme',
'html': '<img src="//assets.pinterest.com/images/pidgets/pinit_fg_en_rect_gray_20.png" />',
'count-layout': 'horizontal',
'style': 'cursor:pointer; position:absolute; bottom:30px; left:0; border:0 none; opacity: 0.4;',
'href': 'http://pinterest.com/pin/create/button/?url=' + $permalink + '&media=' + $(this).attr('src') + '&description=' + $title
});
if ($(this).parent('a')) {
$(this).addClass('pinme').parent('a').after($linkhtml);
}
else {
$(this).addClass('pinme').after($linkhtml);
}
$('.pinme').hover(
function() {
if ($(this).hasClass('pin-it-button')) {
console.log('hello');
$(this).css('opacity', '1');
}
else {
$(this).parent().siblings('.pin-it-button').css('opacity', '1');
}
}, function() {
if ($(this).hasClass('pin-it-button')) {
$(this).css('opacity', '0.4');
}
else {
$(this).parent().siblings('.pin-it-button').css('opacity', '0.4');
}
}
);
});
});
})(jQuery);
The new Pinterest extension (2017)
injects a <span> hover button directly under <body:
<span style="border-radius: 3px;
text-indent: 20px;
width: auto;
padding: 0px 4px 0px 0px;
text-align: center;
font-style: normal;
font-variant: normal;
font-weight: bold;
font-stretch: normal;
font-size: 11px;
line-height: 20px;
font-family: "Helvetica Neue", Helvetica, sans-serif;
color: rgb(255, 255, 255);
background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMzBweCIgd2lkdGg9IjMwcHgiIHZpZXdCb3g9Ii0xIC0xIDMxIDMxIj48Zz48cGF0aCBkPSJNMjkuNDQ5LDE0LjY2MiBDMjkuNDQ5LDIyLjcyMiAyMi44NjgsMjkuMjU2IDE0Ljc1LDI5LjI1NiBDNi42MzIsMjkuMjU2IDAuMDUxLDIyLjcyMiAwLjA1MSwxNC42NjIgQzAuMDUxLDYuNjAxIDYuNjMyLDAuMDY3IDE0Ljc1LDAuMDY3IEMyMi44NjgsMC4wNjcgMjkuNDQ5LDYuNjAxIDI5LjQ0OSwxNC42NjIiIGZpbGw9IiNmZmYiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxIj48L3BhdGg+PHBhdGggZD0iTTE0LjczMywxLjY4NiBDNy41MTYsMS42ODYgMS42NjUsNy40OTUgMS42NjUsMTQuNjYyIEMxLjY2NSwyMC4xNTkgNS4xMDksMjQuODU0IDkuOTcsMjYuNzQ0IEM5Ljg1NiwyNS43MTggOS43NTMsMjQuMTQzIDEwLjAxNiwyMy4wMjIgQzEwLjI1MywyMi4wMSAxMS41NDgsMTYuNTcyIDExLjU0OCwxNi41NzIgQzExLjU0OCwxNi41NzIgMTEuMTU3LDE1Ljc5NSAxMS4xNTcsMTQuNjQ2IEMxMS4xNTcsMTIuODQyIDEyLjIxMSwxMS40OTUgMTMuNTIyLDExLjQ5NSBDMTQuNjM3LDExLjQ5NSAxNS4xNzUsMTIuMzI2IDE1LjE3NSwxMy4zMjMgQzE1LjE3NSwxNC40MzYgMTQuNDYyLDE2LjEgMTQuMDkzLDE3LjY0MyBDMTMuNzg1LDE4LjkzNSAxNC43NDUsMTkuOTg4IDE2LjAyOCwxOS45ODggQzE4LjM1MSwxOS45ODggMjAuMTM2LDE3LjU1NiAyMC4xMzYsMTQuMDQ2IEMyMC4xMzYsMTAuOTM5IDE3Ljg4OCw4Ljc2NyAxNC42NzgsOC43NjcgQzEwLjk1OSw4Ljc2NyA4Ljc3NywxMS41MzYgOC43NzcsMTQuMzk4IEM4Ljc3NywxNS41MTMgOS4yMSwxNi43MDkgOS43NDksMTcuMzU5IEM5Ljg1NiwxNy40ODggOS44NzIsMTcuNiA5Ljg0LDE3LjczMSBDOS43NDEsMTguMTQxIDkuNTIsMTkuMDIzIDkuNDc3LDE5LjIwMyBDOS40MiwxOS40NCA5LjI4OCwxOS40OTEgOS4wNCwxOS4zNzYgQzcuNDA4LDE4LjYyMiA2LjM4NywxNi4yNTIgNi4zODcsMTQuMzQ5IEM2LjM4NywxMC4yNTYgOS4zODMsNi40OTcgMTUuMDIyLDYuNDk3IEMxOS41NTUsNi40OTcgMjMuMDc4LDkuNzA1IDIzLjA3OCwxMy45OTEgQzIzLjA3OCwxOC40NjMgMjAuMjM5LDIyLjA2MiAxNi4yOTcsMjIuMDYyIEMxNC45NzMsMjIuMDYyIDEzLjcyOCwyMS4zNzkgMTMuMzAyLDIwLjU3MiBDMTMuMzAyLDIwLjU3MiAxMi42NDcsMjMuMDUgMTIuNDg4LDIzLjY1NyBDMTIuMTkzLDI0Ljc4NCAxMS4zOTYsMjYuMTk2IDEwLjg2MywyNy4wNTggQzEyLjA4NiwyNy40MzQgMTMuMzg2LDI3LjYzNyAxNC43MzMsMjcuNjM3IEMyMS45NSwyNy42MzcgMjcuODAxLDIxLjgyOCAyNy44MDEsMTQuNjYyIEMyNy44MDEsNy40OTUgMjEuOTUsMS42ODYgMTQuNzMzLDEuNjg2IiBmaWxsPSIjYmQwODFjIj48L3BhdGg+PC9nPjwvc3ZnPg==") 3px 50% / 14px 14px no-repeat rgb(189, 8, 28);
position: absolute;
opacity: 1;
z-index: 8675309;
display: none;
cursor: pointer;
border: none;
-webkit-font-smoothing: antialiased;
top: 240px;
left: 110px;
">Save</span>
So a simple check would be:
var pin = document.querySelector('body > span[style*="8675309"][style*="rgb(189, 8, 28)"]')
Or you can check for the entire background base64 string which contains the P logo.
Old answer for the old PinIt extension:
Examining a page with Pin It extension installed we can see that it adds its own attribute to <body>:
<body data-pinterest-extension-installed="cr1.39.1">
It's easy to determine the presence of the attribute in js:
if (document.body.dataset.pinterestExtensionInstalled) {
console.log("Pin It extension detected!");
}
Note that the attribute is added after the page has been loaded so you can't check it right in DOMContentLoaded event handler; make a pause with setInterval or use MutationObserver:
Content script with "run_at": "document_end" or "document_idle" (the default mode):
var PinItInstalled = undefined;
new MutationObserver(function(mutations) {
PinItInstalled = document.body.dataset.pinterestExtensionInstalled;
this.disconnect();
}).observe(document.body, {
attributes: true,
attributeFilter: ["data-pinterest-extension-installed"]
});
Content script with "run_at": "document_start":
var PinItInstalled = undefined;
document.addEventListener("DOMContentLoaded", function() {
new MutationObserver(function(mutations) {
PinItInstalled = document.body.dataset.pinterestExtensionInstalled;
this.disconnect();
}).observe(document.body, {
attributes: true,
attributeFilter: ["data-pinterest-extension-installed"]
});
});
P.S. Don't forget to test what happens if the Pin It extension's option to show its button on hover is disabled.
While detecting the presence of the extension or pinit.js on the page may be worthwhile, the easier solution is to simply add the data-pin-no-hover attribute to your images. This will tell the extension to ignore the images.
<img src="whatevz" data-pin-no-hover="true" />
There really isn't any reason to care if it is installed or not if the data-pin attribute is set.
The other option is to not create your own hover buttons, but use pinit.js that creates the hover buttons for you. See the docs.
<script
type="text/javascript"
async defer
data-pin-hover="true"
src="//assets.pinterest.com/js/pinit.js"
></script>