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

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.

Related

Despite having onkeydown event handlers, Firefox is telling me "Focusable elements should have interactive semantics"

I'm trying to add accessibility to my website, but I'm running into a weird issue with Firefox's accessibility scanner. I've put onclick and onkeydown handlers on my interactive elements, but onkeydown doesn't seem to be enough; Firefox is telling me "Focusable elements should have interactive semantics." The [Learn More] link provided in the notice sends me to this page, which recommends a keydown or keyup event handler... which is already in the code. What am I missing here?
Here's a sample code I used to test the issue:
<img
src="https://www.google.com/logos/doodles/2022/seasonal-holidays-2022-6753651837109831.8-ladc.gif"
alt="Google"
title="Google"
tabindex="0"
onclick="alert('Google')"
onkeydown="alert('Google')">
In Firefox 108's Developer Console, under the Accessibility tab, using "Check for issues" for all issues gives me a notice on this element, saying "Focusable elements should have interactive semantics." despite the fact that onkeydown is defined and performs the same action as onclick.
EDIT: This question is not a duplicate of What does "Focusable Elements Should Have Interactive Semantics" mean in a figure? because that question regards an incorrect use of the role and aria-label attributes in a link, whereas my problem (as explained by the answer I've marked as correct, thank you!) was completely missing the role attribute and better resolved by wrapping this in a button.
The key thing here in the error statement:
Focusable elements should have interactive semantics.
is the word "semantics".
semantics refers to what an element actually "means" or "does" in the context of the page. Specifically, we are talking about the role of an element as exposed to the operating system's underlying accessibility API. An img element (providing it as alt text as you have correctly given it) has default role img (which is obvious, I hope - that comes from the table on this page), which you can view in the ARIA specification. I won't quote anything from that as what's most important in this context is what's not there. Basically, an image is not expected to be interactive - unlike elements with different roles such as button.
If you were to actually test your page with a screenreader - something I would highly recommend every front end developer does with some regularity - you would see the problem. Yes, knowing how your application behaves, you can press a key and have the intended functionality happen. But there's nothing in your HTML that implies that anything interactive will happen here - it's just an image, they're not expected to be interactive. So a screenreader will not announce anything to the effect of "oh by the way you can click on this" (or press enter or whatever) (actually from memory NVDA says "clickable" for elements with click handlers - but other screenreaders such as Voiceover won't, so you shouldn't rely on this. Even knowing the element is "clickable", users without a mouse or who are unable to see where they're clicking will not know how to trigger this "click".).
The solution is to give your element the correct semantics. Since this does something when you click it, and that thing isn't navigation to a new page, it strikes me that the correct role would be button. So you could do this, adding the correct role attribute:
<img
src="https://www.google.com/logos/doodles/2022/seasonal-holidays-2022-6753651837109831.8-ladc.gif"
alt="Google"
title="Google"
tabindex="0"
onclick="alert('Google')"
onkeydown="alert('Google')"
role="button">
This would be a big improvement - I'd expect it to no longer bring up the error you're seeing, as well as to be much more usable to users with assistive technologies.
But, whenever you find yourself using a role which corresponds to an alternative HTML element - and in this case it will not surprise you to know that the button role is automatically applied to the HTML <button> element - you should ask yourself if there's any good reason why you can't just use the correct element.
Only you can answer that question, but I'd be very surprised if such a reason existed. At worst, using a <button> may change your styles, but I'm assuming you have control of the CSS so you can update that as needed.
You do still want the image there because that's seen by sighted users so screenreader users should be told about it the same. What I would do is wrap the image in a button, attach the onclick handler to that button, and remove both the tabindex and the onkeydown, because one of the nice things about using the correct HTML element is that browsers handle most of the behaviour for you, in this case making buttons be in the tab order and trigger their click effect whenever Enter or Space is pressed when focused.
So this would be in my opinion the best way to code this:
<button onclick="alert('Google')">
<img
src="https://www.google.com/logos/doodles/2022/seasonal-holidays-2022-6753651837109831.8-ladc.gif"
alt="Google"
title="Google"
>
<button>
and you should get everything you need, including being accessible "for free" (and the button having the image's alt text as its "accessible name"), and at worst just have to add/update some styles.

How to trigger the onclick function by code by writing an javascript extension?

There's this website that logs me off if I don't click a button in a form that periodically pops up. I'd like to write a script to automate this.
What's the phrase that describes such web task automation?
How do I detect such pop up?
How do I trigger the onclick function in that form via code?
Usually, all you need is to be able to identify a unique selector for the element. When you see the button appear, right-click it and Inspect it in the Elements panel of your browser. Look for something that makes it unique, such as an ID, or a class (that no other button has), or being a descendant of a similar unique container.
For example, the "Post Your Answer" button on Stack Exchange has an ID of submit-button, so you can select it with #select-button:
Once you have the selector, either periodically check for it in an interval, or use MutationObserver (more complicated and more expensive, but it'll click the button ASAP, and doesn't require polling). Whenever the element exists, .click() it.
setInterval(() => {
const elm = document.querySelector('#my-btn');
if (elm) {
elm.click();
}
}, 1000);
You might find it easier to put this code into a userscript rather than a standalone Chrome extension - userscripts are far easier to manage IMO, all you need to do is type the Javascript and it's ready to go.
https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
You can use MutationObserver for particular HTML tag/element which renders every time when the pop-up is shown. Once you got the DOM element, click the required button to remain logged in into the website.
Make the automation script for the same.

Remove / move the Google Chrome bottom left status bar (link address bar)

I am working on a website which is designed with a key navigation element in the lower left corner. Within Google Chrome there is a status bar on the lower left which appears when you roll over a link on the page and displays the URL of the page. Though if you get close enough this moves to the lower right. This is getting in the way of this navigation element.
My question is can this be removed / moved (lower right) using CSS, HTML or JavaScript? Please see some notes below.
Ideally I would like to move this to the right permanently.
I am aware this is required / best practice for many reasons so I would like to avoid removing.
I am aware I can remove the href from the link and use an onClick event, this might be a possible workaround but moving right would be a better solution in this instance.
I am also sure there is a large debate to be had to about having this navigation element lower left anyway, but I am looking for a solution within the parameters I have to work with.
Thanks
Chrome reads the HREF attribute from your link to display the link in the status bar.
So if you remove the HREF from your A tags, the status bar will not be displayed. However the link won't work either, :). That's why you can create an event handler on MouseOver to address that and keep your links working.
$("body").on('mouseover', 'a', function (e) {
var $link = $(this),
href = $link.attr('href') || $link.data("href");
$link.off('click.chrome');
$link.on('click.chrome', function () {
window.location.href = href;
})
.attr('data-href', href) //keeps track of the href value
.css({ cursor: 'pointer' })
.removeAttr('href'); // <- this is what stops Chrome to display status bar
});
You might run in extra issues, like disabled links or links that have other event handlers. In this case, you can tweak your selector to 'a:not(.disabled)' or perhaps just add this delegation to known elements with the css class ".disable-status", therefore your selector would be: "a.disable-status".
As you can see from this screenshot, it seems that Chrome moves the status bar outside the extent of the window when you roll-over a link that is on the edge (the "add comment" link in this instance).
So... I wouldn't worry about it. It's built in browser behaviour, so it's going to be very hard to alter. Once upon a time you could use javascript to modify the content of the status bar, but the browser vendors put a stop to this for all sorts of security reasons.
Don't be tempted down the onclick bodge. You will lose accessibility, and the html demons will haunt your every sleeping moment.
In fact, you could think of this all as desirable behaviour: your navigation and the status are right next to each other, making it very easy for the user to make the right navigation choice (assuming your URLs are user friendly).
tl/dr: Don't.
as it seems this little status with link is poped up on with href. you can create the element without the href attribute and instead use the onclick event to direct the user.
just on thing, I think you'll lack the visited functionallity.

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']")

HTML simulate textarea with div container

I want to create a little WYSIWYG editor.
The idea:
First I want to add the feature to write and change text. So I add an onClick and onKeyBoard Listener to my div container. When I click the div I set a varaible named "focused" to true. When an key event is fired I check if focused is true. In case focus is false nothing will happen else the new charater will be added on the cursor's position.
My questions:
Is this the right way? I tried to check how other editors handle the text input but I wasnt able to get it.
In case this is the right way - how can I simulate a blinking cursor. In a textarea the cursor will blink but who about a div container? The cursor will hide immideatly after clicking.
I'm assuming you're doing this for fun/practice. If you're doing this for professional reason then I HIGHLY recommend you don't reinvent the wheel and use something like Ckeditor, tinyMCE or YUI.
That being said; you need to look into event handling. Specifically, for your question about focusing, you can look here. The way you're describing (setting a variable to true/false) seems like it is going to just run into problems. If you use the standard events attribute (as opposed to setting a "focus" variable onclick) you should define functions to execute and then set them as an onfocus/onblur attribute for the element you're listening to.
That is if you aren't using a javacript library like mootools, jquery, extJS, etc. If you're using one of those they likely have their own way of handling events, so you should search their respective documentation for how to implement event handlers.
One more note; you really should be using a textarea over a div (unless I'm misunderstanding and you just want to do something when a user focuses on your div). If you're using javascript only to completely reinvent a texteditor from a div; then your web page will not function without javascript. If you keep the text area; users could still type information in and you still get the benefit of grabbing text contents for form submits but using divs means your web page will just be rendered useless without javascript.

Categories