How to fire mouse event when page loads without moving the mouse? - javascript

I have a link to my homepage that changes color when the mouse gets over it. When the user clicks, however, the page refreshes and the link turns back to the old color. I want the link to change to the new color again just because the mouse is there, but no mouse event is being fired with the mouse stopped. In JSFiddle, however, it works (putting the mouse over the text and refreshing all the page with F5), so I guess there must be a way. I don't want to use css :hover because the color is changed often, and I've found that changing a css value in javascript is kind of a nightmare. Or isn't it? Also, no JQuery, please.
function colorize() {
this.style.color = '#C83';
}
function load() {
var p1 = document.getElementById('p1');
p1.addEventListener('mouseover',colorize);
}
p {
font-size: 2em;
background-color: #385;
}
<body onload='load()'>
<p id='p1'>Some big text</p>
</body>

I gotta be honest with you, this scenario of yours
When the user clicks, however, the page refreshes and the link turns
back to the old color.
seems more like an issue of force refreshing your page. Why are you forcing a refresh?
Based on this thread,
You can't. It's not a trusted event.
Events that are generated by the user agent, either as a result of
user interaction, or as a direct result of changes to the DOM, are
trusted by the user agent with privileges that are not afforded to
events generated by script through the
DocumentEvent.createEvent("Event") method, modified using the
Event.initEvent() method, or dispatched via the
EventTarget.dispatchEvent() method. The isTrusted attribute of trusted
events has a value of true, while untrusted events have a isTrusted
attribute value of false.
Most untrusted events should not trigger default actions, with the
exception of click or DOMActivate events.
You have to add a class and add/remove that on the mouseover/mouseout
events manually
There's just no standard/worth mentioning native way to do it.
You would have to retain the state somehow when refreshing. Passing a query string ?isMouseOver=true and parsing it back after the refresh should suffice. Just execute the same mouseover function after verifying the query string, no need to programmatically fire a mouseover event.
Or you can use jQuery, which has trigger-able mouse events.
But I would honestly avoid that force refresh solution and come up with something else

Related

How can I stop the effects of the users clicks?

I am making a chrome extension to edit properties of images that are clicked on. I am using a package called element picker to select the images (this is triggered through an html button in a popup). The code works and I can change the properties of the image. However the package does not stop whatever action is linked to the image, which can often lead to the user being taken to a new page. How can I stop any of the actions of the users click between the time they press the button in the popup and they have selected an image?
Thank you in advance.
var elementPicker = require('element-picker')
function onClick(elt) {
[.....]
}
elementPicker.init({ onClick })
I don't usually recommend using this but CSS pointer-events can solve this problem. The idea is that any element with pointer-events:none will ignore any interactions. This works to block default HTML interactions like <a> or <button> as well as any javascript actions attached to the element.
This is the technique frequently used with a modal window to prevent clicks from going "through" the area around a modal. It should also work for what you described.
You could either set that style on the image element or on All Elements by using the * {styles...} selector. If you go the "all" route, you'll need to explicitly re-enable pointer-events on any elements in your extension interface that you still need actionable by using the 'auto' property.
Remember to reset pointer events when your extension is finished * {pointer-events: initial;} or you'll leave the page completely in-actionable.
If there is an Event object being passes through to the function then you could use the Event.preventDefault() function.
This function stops any default behavior and allows you to handle the event in your own manner.
Reference: https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault

What exactly acts as a trigger for a custom event in Javascript

I've been reading about custom events and looked at some examples. Perhaps I am misunderstanding what custom events are and how they are triggered and would appreciate some help.
Example Problem
To trigger an event when the background colour of a div changes from one colour to another.
Situation A) The colour changes as result of user activity detectable from within the script, eg by onclick, onmouseover, onkeypress then I would set up a listener for these events and respond accordingly. This I understand how to do.
Situation B) The colour changes as the result of user activity not detectable from within the script, eg a new theme applied to the page, then am I correct in thinking the following are necessary?
I would need to create a custom event for colour change.
Add a listener for the event to the appropriate DIV
The listener would need to poll the DIV at intervals to check for colour changes
Really its step 3 I am not clear about. If you are not polling the DIV how does the event colour change trigger an event? In other words how does the script know that a colour change has taken place?
Custom events are not like DOM events, they don't fire because some interaction happened in the browser. They happen when the person who writes the code decides for them to happen. You have to explicitly trigger custom event when you need one.
For example, you might have function like
function updateBackground (element, color) {
elmenet.css('background-color', color);
// element has to be an object that has `trigger` function on its prototype
// like jQuery wrapped element, for example
element.trigger('updated-background', color);
}
Then every time this code is executed you'll have 'updated-background' fired in context of this element.
UPD.
Using browser options a user can change font size, background colours
etc, ie apply a new theme. As far as I know there are no native events
within javascript to deal with these so I would need to create a
custom event within my script. What I am trying to ask is how to you
find out when a custom event takes place?
You find out because you create them. You are correct (to my knowledge) that there are no DOM events fired when user changes font-size / default body background etc. You could poll for body and fire custom event when you detect a change, as you said.
In JavaScript, a custom event is simply a message, broadcast to all event listeners, that says, "Attention everyone: event X just happened!" Any listener that cares about that event can then run some function.
However, your custom event still needs to be fired somehow. Custom events aren't fired unless, somewhere in your code, you call .dispatchEvent (or .trigger, in jQuery). Your program must decide when it is time to fire the event. If the browser doesn't natively fire an event that you can use as a cue for your own custom event, then often polling is the only way to know when to fire the event.
The bottom line here is events are just messages. It's up to you and the code you write to decide when to fire them.

How do I make links with no href attribute accessible?

A third party script is being used on a site I work on that replaces a few instances of <a href=""> with <a>. The links still work thanks to another part of the script, but they are no longer treated as links by user agents.
I can restore them to the tabbed navigation order by adding tabindex="0" but how can I make assistive technologies announce them as links or include them in a list of all links on a page?
Would adding role="link" help at all?
I am pushing the third party to improve their script so that the href is left intact. But in the meantime how do I best repair the damage that's being done?
I can't add either the original href or something like href="#" back to the links as the third party code will no longer do what it does. I hope that they improve their code so that I can, but for now I need to make the link accessible without the 'href'.
To make a non-href <a> behave like an <a> (and be accessible), you'd have to add role=link, tabindex=0, style it to look like a real link, and add keyboard handler code to treat Return as a click.
role="link" isn't sufficient; a screenreader may report it as a link, but without tabindex="0" and appropriate visual styles, a sighted user won't be able to tab to it in the first place, and without a keyboard event handler, only mouse users will be able to click it. (Technically screenreader users typically have hotkeys to simulate a mouse click, but keyboard-only sighted users generally don't have that option, so don't rely on it.)
Alternatively, if (big if!) the crazy script you're using allows for it, you could try shimming a 'keyboard click source' (my terminology) <a> just inside the original one: so where you have:
<a>foo</a>
you replace it with:
<a><a class='shim' href="javascript:void(0)">foo</a></a>
(The class='shim' is only needed if you need to do the event stuff described later...)
You can do this in jQuery using something like: (borrowing from Jack's answer)
$("a:not([href])").wrapInner("<a class='shim' href='javascript:void(0)'></a>")
How this works is that the inner newly-added <a ...> has a href, so it is exposed as a link and is tabbable. More importantly, if a user tabs to it and presses return, the default A behavior converts that keyboard input into a click event. This specific A has a href that returns undefined/void(0), so no actual navigation happens, but the click event will still bubble up to the original A, which gets to act on it.
(This is a neat pattern for allowing some parent element - often a DIV or similar - to handle click events, adding a child tabbable A that can source click events from keyboard gives you UI that's both mouse and keyboard usable.)
The big caveat here is that it assumes that your original script doesn't care about the target of the event. If that script does check this, it will get confused when it sees click events coming from the shim A's rather than the original As. One way to get around this is to capture and re-raise the event, which can be fiddly, and may only work on recent browsers - eg using something like:
// 'shim' class used so we can do this:
$("a.shim").click(function(e) {
e.preventDefault();
e.stopPropagation();
// the following works if listener using jQuery or is setting onclick directly, otherwise...
// $(e.target).parent().click();.
// More general way to raise events; may need alternate for IE<9
var e2 = document.createEvent("UIEvents");
e2.initUIEvent("click", true, true, window, 1);
e.target.parentNode.dispatchEvent(e2)
});
Whilst it's not very pretty, you can get at all anchors without a href attribute like so, using jQuery;
$("a:not([href])")
You can then just set the href attribute on those links to "#" and that should make them work again as regular links.
Here's a working JSFiddle
Sorry to reply with a jQuery solution...but doing this in regular JavaScript would be much more verbose.
Another way would be to give the anchors a role and then select them that way:
$("a[role='link']")

Using JavaScript, how can you tell if a user is tabbing backwards?

I've got an HTML link, and I want to take some action when the user tabs away from it - but only if the user is tabbing forwards through the document, as opposed to backwards.
Is there a reliable cross-browser way to detect which way the user is tabbing through the document, or indeed if they're tabbing through the document at all? I'm binding to the blur event, but that doesn't necessarily mean that the user is tabbing.
I've had a look at inspecting the value of document.activeElement, or the hasFocus attribute of the previous focusable element in the source, but:
those seem like relatively recent additions, and thus might not be widely supported, and
I'm not sure they'll be inspectable when the blur event fires, as even if the user is tabbing, I don't think the next element will be focused yet.
You will have to handle keydown event on the link itself.
$("your link selector").keydown(function(evt){
if (evt.which === 9)
{
if(evt.shiftKey === true)
{
// user is tabbing backward
}
else
{
// User is tabbing forward
}
}
});
Check this JSFiddle example that detects forward and backward tabbing on a particular link.
Sidenote: You didn't specify jQuery tag on your question al though I provided jQuery code in my answer. Since you hold Javascript as well as jQuery badges I suppose it's going to be trivial for you to convert my code to pure Javascript.
As an alternative to a good solution from Robert, maybe you can leverage tabindex attribute? Set it for your html links and other “tabbable” items. Then check it in javascript.
Solution with tabindex: jsfiddle
Side effect: Elements will also react on mouse clicks. They will behave correctly. So this might be a good side effect or bad side effect depending on your needs.

Show underlining immediately when html element has contenteditable="true" spellcheck="true"

I would like to highlight misspelling in a span on page load, e.g.,
<span contenteditable="true" spellcheck="true">gibberishnonesense</span>
Currently, the gibberishnonesense does not underline unless I click into the span. I would like the underlining to happen on page load. It seem that the underlining only happens once you actively start to edit.
Is there a setting I need to switch to this is underlined without editting? Is there an event I can send to the span that will activate it - and not change the activeElement or focus (avoid el.focus();?
I am aware of styling with text-decoration-style: wavy; but that underline style is different and I would like to leverage the user agent's spellchecker.
===
Things I have tried:
Changing the elements content via JS
el.innerText += ''
Sending a "change" event via JS
var manualChange = new Event('change');
el.dispatchEvent(manualChange);
===
Some research indicates this is a Chrome specific behavior; however, I am targeting Chrome and therefore need it to work there.
I see from another question that there is a forceSpellchek method which is not yet implemented in Chrome
I have never found a satisfactory solution to this - as you say, spell-check doesn't kick in until you click in the contenteditable document.
The only answer I came up with is to insert a banner (eg: div) on load at the start of the document, saying 'Click to activate spell-check' - then on click, delete the div.
The very act of clicking on the div activates spell-check, but it's a bit clumsy and as all my users create articles from new I eventually dropped it.
I also believe spell-check kicks in on insert, so that might be a route worth investigating - it's not something I've tried.

Categories