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.
Related
Suppose you have a div that is at the very top (usually offscreen, due to a long page) that is updated with .append() when any of a bunch of links (scrolling also offpage) is clicked. How do you prevent Chrome from scrolling to the top automatically after each of the link clicks?
Something like this
<div id="updateme"></div>
<img>
...
[hundreds more]
There are several ways to solve this, and it is because you are using an anchor hashtag (#).
<img>
Instead, you could remove the href altogether but I am betting you want the style that href gives you. I would recommend using css to style the a to look and act like a link (which is probably the cleanest method), but you can also do this if you like:
<img>
This could also be covered with a little javascript when the page finishes loading as well if desired, since you listed jquery, it could be something like:
$('a[href="#"]').on('click', function(e) {
e.preventDefault();
});
If going the above route, just in case these are dynamically loaded in, you might want something like:
$('#updateme').on('click', 'a[href="#"]', function(e) {
e.preventDefault();
});
I strongly assume that Chrome doesn't scroll to the top because you are updating the content of the updateme element, but because your link points to #, which acts like an anchor on top of the page.
Personally I'm not a big fan of using href="#", because it makes it possible to middle-click or Ctrl+click the link, opening it in a new tab, which is not an intended functionality. I prefer using href="javascript:", but maybe there is an even better way that I don't know about.
If you want to leave the link as it is, to prevent Chrome from scrolling up when clicking the link, you have to make sure that only the click handler is run when you click the link, and Chrome doesn't actually navigate to the href you have specified, use onclick="event.preventDefault(); DoAppendUpdateMe()" (see preventDefault).
I need to navigate to the element 'divElem1', on click of a button. Is it possible?
If we enter this link in browser, http://myUrl#divElem1, browser will navigate to the page and to the DIV element 'divElem1'. The same behavior has to be obtained through javascript.
The hash change will not work in my application, as there are other events will be fired on hash change.
So, the following will not work.
document.button.onclick = function () {
location.hash = "#divElem1";
};
document.getElementById("divElem1").focus() is also not working since the element is a div
You can use scrollIntoView for that:
document.getElementById("divElem1").scrollIntoView()
This doesn't give fine grain control over where exactly the target element will end up but it WILL be moved into the view-port. Even more, if the element is inside a scrollable container, both the container and the element inside it will be moved into a position so they are visible in the view-port.
If you want "plain" Javascript, use scrollIntoView(). But it really jumps to that position, see this question and answer.
Using jQuery, it can be done jumpy or with some easing, as explained here.
Easing is recommended to provide a better user experience and to let visitors see and understand what is happening.
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']")
Go here: http://www.infinite-scroll.com/
Play with the infinite scroll. Notice that you can't click a link and then hit "back". It has glitches when you do that.
So, I plan on writing my own Infinite scroll.
When the user gets to the bottom, load an AJAX call. Then do a JQuery "append" the result to the div. Then, call my other functions on those elements. (I set the background images of all those elements in javascript).
Will this work? If I do that...will I be able to handle the back button?
I considered the very same thing on a project I worked on. One option I thought about was to allow the back button to return to the place where the link was clicked (just like normal browsing).
Firstly, you need to record what page of the infinite scrolling your on so that you can load up to that section again. You can do this with some clever playing around with the window.location.hash value. If you look at my answer to this question, I explain in more detail how to do it in plain JavaScript or jQuery using Asual's address plugin.
The basic part of it would like like this:
// Whatever you're using to load the next page
function scrollToNextPage(page){
// Your infinite scrolling stuff
$.address.parameter("currentPage", page);
}
$.address.externalChange(function(){
var page = $.address.parameter("currentPage"),
top = $.address.parameter("linkTop");
loadAjaxUpTo(page);
$('html, body').animate({ scrollTop: top }, 500);
});
// Set a parameter for the location of a clicked link
$("a").live('click', function(){
$.address.parameter("linkTop", $(this).scrollTop());
});
I didn't implement the last bit (getting the position of the link clicked) but I can't see why it wouldn't work. It would cause the window to scroll nicely to where you where. You can always set it with an anchor to the loaded page instead (but when you scroll to it, it will always go to the top of the page).
A couple of points though, I wouldn't recommend this. At least for the project I was doing, it wasn't really necessary. In my project, we expected the user to go back to change their options and figured that scrolling wouldn't be a problem (although we didn't have that many pages to scroll through). The AJAX (and your JavaScript to set the images) needs to be loaded and executed again which takes a lot of time depending on how many pages you need to reload. On top of the time to scroll to the link (you could just window.scrollTo but you don't get animation so everything is very jerky. You could always just load the page the person was on and forget about the previous pages, but you're still breaking the user experience that way. Or (what I tried) was to implement a two way infinite scroll. So it would load the page the user clicked from and prepend the previous pages if they scrolled up - this was too much work for what it was though.
Another point is that, if you were to still do it, you want to use a GET request to get your pages (and make sure the cache isn't set to expire immediately). I found that pages requested by Ajax with the GET request would take from the cache (at least on some of the browsers I tried). Sending your details over a POST will always ignore the cache.
The only way to be able to handle the back button is to alter the location hash (the bit after the # symbol). Handling pressing of the back and forward buttons can be done in two ways:
Have an <a name="bookmark1"></a> which is unique to each section added, and change the location.hash to match it.
Use a setInterval with a short time like 100ms to watch the location.hash for changes and go to the required part of the page. You have to do this because you can't actually detect when the back/forward buttons are clicked.
This is an implementation of the second method to show you how it works. In this, each ajax request contains <a name="ajax-section-1"></a> and ajax-section-2 etc.
function addToBottom(htmlToAdd) {
$('#main-div').append(htmlToAdd);
window.location.hash = $('#main-div a[name^=ajax-section-]').last().attr('name');
}
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.