Better way to write this code?

Hi,

I want to change the colour of the text on mouse in and mouse out.

The font style is saved in paragraph 3 theme, and I use additional letter spacing of 0.1.

The code below works fine, however, on some occasions, the mouse out doesn’t execute properly (i.e. it glitches and the colour doesn’t revert back even though the mouse is out of the element). Please note the element mouse out action is defined in the properties.

Code I am using is below, any ideas to optimise the code or something I am doing wrong?

export function text2_mouseIn(event, $w) {$w(“#text2”).html = ‘

’ + $w(“#text2”).text + ‘

’}

export function text2_mouseOut(event, $w) {$w(“#text2”).html = ‘

’ + $w(“#text2”).text +‘

’}

Alternatively if anyone knows how to customise a wix button so that the text can include character spacing then that might solve it and I can use a wix button!

Thank you.

You can try to put each text inside a transparent box, and use the mouseIn/Out listeners to detect hovering over the box instead of the text.
This way you can enlarge the detection area, and maybe it’ll be more accurate.

Here’s a quick function I wrote a while back to make this sort of thing work properly :slight_smile:
https://www.skeptischmedia.com/lib/sk/isMouseIn

Hi David, how would this apply if i used the following code: thank you for your help!

export function text5_mouseIn(event, $w) {$w(“#text5”).html = ‘

’ + $w(“#text5”).text + ‘

’}

export function text5_mouseOut(event, $w) {$w(“#text5”).html = ‘

’ + $w(“#text5”).text +‘

’}

So I have the following code in use, credit to @skmedia . Text in element #text1 changes colour ok, but when several text elements use this code, and you quickly mouse in and out, it still gets stuck, and doesn’t mouse out properly…any ideas anyone? thank you.

I am using part 1 and part 2 duplicated for each element I have i.e. #text1,#text2,#text3

//PART 1
$w.onReady(function() {

$w(“#text1”).onMouseIn(() => { $w(“#text1”).html = ‘

’+ $w(“#text1”).text + ‘

’;
isMouseIn(50, () => { $w(“#text1”).html = ‘

’ + $w(“#text1”).text + ‘

’}, $w(“#text1”).id); });

//PART2
export function isMouseIn(interval, callback, id) { if (!id) return false; let c = 1; if (typeof id === ‘string’) { const e = $w(“#text1”);
e.onMouseIn(() => { c = 1;
iF; });
e.onMouseOut(() => c = 0); } else if (Array.isArray(id)) { id.forEach(el => { $w(“#text1”).onMouseIn(() => { c++;
iF; });
$w(“#text1”).onMouseOut(() => c–); }); } const iF = setInterval(() => { if (!c) { callback();
clearInterval(iF); } }, interval); }

Try to format your code, and put it inside a Code Block. It’s hard to read it like that.

Ok ill try:

$w.onReady(function () {
$w("#text1").onMouseIn(() => {
$w("#text1").html = '<p class="font_9"><span style="color:#BAA59B;"><span style="letter-spacing:0.1em;">' + $w("#text1").text + '</span></p>';
isMouseIn(50, () => { $w("#text1").html = '<p class="font_9"><span style="color:#414141;"><span style="letter-spacing:0.1em;">' + $w("#text1").text + '</span></p>' }, $w("#text1").id);
});


export function isMouseIn(interval, callback, id) {
if (!id) return false;
let c = 1;
if (typeof id === 'string') {
const e = $w("#text1");
e.onMouseIn(() => {
c = 1;
iF;
});
e.onMouseOut(() => c = 0);
} else if (Array.isArray(id)) {
id.forEach(el => {
$w("#text1").onMouseIn(() => {
c++;
iF;
});
$w("#text1").onMouseOut(() => c--);
});
}
const iF = setInterval(() => {
if (!c) {
callback();
clearInterval(iF);
}
}, interval);
}


Ah, all you need to do is call the function as you did in the onReady event. You shouldn’t replace anything inside the function as I wrote it, or else you’re only going to be able to use it on text1 the way you have it now, and if you’re still having troubles with it then try adjusting your interval value.

Sorry, how do I do that? Thanks so much for your help

You can just copy paste the function on my site again and use it to replace your modified version. The purpose for the id argument at the end is so that it can handle whatever elements you want to throw at it. Sorry for the weird formatting atm, it’s not intended to be shown on a single line but I’m working on it.

@skmedia

I have put code as follows exactly how you have it but I get error on line 6 “TypeError: e.onMouseIn is not a function”

export function isMouseIn(interval, callback, id) {
if (!id) return false;
let c = 1;
if (typeof id === 'string') {
const e = $w(`#{id}`);
e.onMouseIn(() => {
c = 1;
iF;
});
e.onMouseOut(() => c = 0);
} else if (Array.isArray(id)) {
id.forEach(el => {
$w(`#{el}`).onMouseIn(() => {
c++;
iF;
});
$w(`#{el}`).onMouseOut(() => c--);
});
}
const iF = setInterval(() => {
if (!c) {
callback();
clearInterval(iF);
}
}, interval);
}
$w.onReady(function () {
$w("#text1").onMouseIn(() => {
$w("#text1").html = '<p class="font_9"><span style="color:#BAA59B;"><span style="letter-spacing:0.1em;">' + $w("#text1").text + '</span></p>';
isMouseIn(50, () => { $w("#text1").html = '<p class="font_9"><span style="color:#414141;"><span style="letter-spacing:0.1em;">' + $w("#text1").text + '</span></p>' }, $w("#text1").id);
});
});

My bad, I think the version on the site has improper syntax for the template literals.

export function isMouseIn(interval, callback, id) {
if (!id) return false;
let c = 1;
if (typeof id === "string") {
const e = $w(`#${id}`);
e.onMouseIn(() => {
c = 1;
iF;
});
e.onMouseOut(() => (c = 0));
} else if (Array.isArray(id)) {
id.forEach(el => {
$w(`#${el}`).onMouseIn(() => {
c++;
iF;
});
$w(`#${el}`).onMouseOut(() => c--);
});
}
const iF = setInterval(() => {
if (!c) {
callback();
clearInterval(iF);
}
}, interval);
}