I have a div and I have a link inside this div. I want the user to be able to click anywhere in the div and they go to the page that's in the link. The link can be changed to a <span>/<p>, that's not important. There are the following conditions, however:
I cannot use css to make the <a> tags into display: block;
If I use onClick I want the user to be able to use the middle-mouse button (or right click, new tab) to open the page in a new tab if they so desire. I currently do not have this functionality if I use onClick and javascript.
I want it to be valid CSS i.e. I don't want to have <a><div> .... </div></a>
That pretty much sums up the problem I have. I've tried reading around but most people seem to solve the problem with either onclick, display: block or putting images, or forcing the user to open the page in a new window. I do not want any of these solutions, I just want a div to work as a normal link (if possible).
Many thanks
You could try wrapping the A tag with your DIV instead of vice-versa.
Instead of:
<div><a>link</a></div>
Try:
<a><div>link</div></a>
So, maybe it's not valid mark up (before HTML5) but the fact that it is now acceptable by HTML5 standards seems like hindsight that this is at least a good way to accomplish what you need.
The middle-mouse/right click functions are part of how the browser interacts with an anchor, not part of your code. There's nothing you can do in code to make it work different. If changing the anchor to take up the whole space (act like a DIV) isn't possible, I don't see how you're going to do this in exactly the same way.
You could approximate it by detecting which mouse button is pressed with event.which and doing different things based on which mouse button is clicked. It won't be the browser interface that the user is interacting with and some of the options may not be possible, but you could make it close.
$('#myDiv').mousedown( function(e) {
var href = $(this).find('a:first').attr('href');
if (e.which == 1) {
window.parent.location = href;
}
else if (e.which == 2) {
window.open(href);
}
else {
...popup a menu with the various options...
}
});
// prevent all clicks on the actual anchor from bubbling to the DIV handler
$('#myDiv a').click(function(e) {
e.stopPropagation();
});
One way that I have approached this in the past is to wrap the div inside of the tag.
So, try something like this
<div style="min-width: 20px; min-height: 20px;">test</div>
Sure you can make <a>tags into display: block; but be careful you need to add height: inherit; if you don't want to set a fixed height
Update:
onclick event can't handle right click and middle click but onmousedown can!
Example:
$("a").mousedown(function(e){
switch(e.which)
{
case 1: //left click
$(this).attr("target", "_self"); //this tab
break;
case 2: case 3: // right and middle click
$(this).attr("target", "_blank"); //new tab
e.preventDefault();
break;
}
});
Related
I am working on a large project and need to fix some accessibility issues.
These is a section which has been generated by https://www.atbar.org/ in a JS format I am not familiar with. The user clicks buttons to change font size, background colour and other html elements to assist them with reading content.
When you click on the buttons with your mouse they work fine. This is an example of how the buttons appear:
<li class=“access-button">
<a title="Decrease Text Size" id="block_accessibility_dec" tabindex=“0">A-</a>
</li>
If I focus my Chrome inspector on the link element I can see there is an event listening for my click:
This appears to trigger the change in font size. I found the code that triggers this click, it is in a JS format that I am not familiar with:
M.block_accessibility = {
init: function(Y, autoload_atbar, instance_id) {
this.defaultsize = M.block_accessibility.DEFAULT_FONTSIZE;
// This event triggers after clicking
Y.all('#block_accessibility_textresize a').on('click', function(e) {
if (!e.target.hasClass('disabled')) {
M.block_accessibility.changesize(e.target);
}
});
// This is the function it runs, it has many cases for all the different buttons.
changesize: function(button) {
Y = this.Y;
switch (button.get('id')) {
case "block_accessibility_dec":
Obviously this is just snippets of the code with comments I added.
What I require is the user to be able to change the font size using just tab and enter, so I added the following JQuery:
$("#block_accessibility_dec").keyup(function(event) {
if (event.keyCode === 13) {
$('#block_accessibility_textresize #block_accessibility_dec').click();
}
});
This is not triggering the change in font size. Yet when I click on the button it does? There is probably a really simple solution here but I've been stuck for ages. I tested the .click() on other elements on the screen and it works for them so the JS is definitely executing.
I have also tested:
$(this).click();
But to no avail.
Try to trigger the click event by the native way:
$('#block_accessibility_textresize #block_accessibility_dec')[0].click();
Source: I tried their demo page together with the chrome inspector and couldn't get the click working with JQuery.
But with the native click event it suddenly worked.
Unfortunately I can't really explain to you, why JQuery doesn't work here. Maybe something with their version (1.11)?
Replace your code with the following code and add the keyup event. This should work when you press the enter key.
Y.all('#block_accessibility_textresize a').on('click keyup', function(e) {
if (e.keyCode == 13 || e.keyCode ==9) {
if (!e.target.hasClass('disabled')) {
M.block_accessibility.changesize(e.target);
}
}
});
You should use the following Jquery:
$('#block_accessibility_textresize #block_accessibility_dec').trigger("click");
Please let me know if this doesn't work.
Challenge: prevent mouse middle button to open new tab in anchor tag with a particular class.
my problem is I have tried but it stopped working of all anchor tags in page but I don't want it.I want to stop working of middle button to open a new tab in anchor tab having class name tab1.
visit: http://jsbin.com/wemapehadu/edit?html,output
can anybody have solution for that...
Another simple solution
$(function(){
$(document).on("click", function(e){
if($(e.target).is("#google") && e.button===1)
e.preventDefault()
})
})
JS Bin
Google Bing
[FIDDLE LINK][]
http://jsfiddle.net/kezcrxop/1/
In your jsfiddle you forgot to enable JQuery, so it could never work.
Your Javascript didn't quite work, but you were going in the right direction. This will work (with JQuery enabled):
$(document).ready(function() {
$(document).on("mousedown","a.aa",function(e) {
if(e.which == 2) {
e.preventDefault();
}
});
});
We have a select2 dropdown in a row (just a div) and we need to be able to click that entire row to trigger the dropdown. I have no problem showing it, but trying to hide it has become a problem, and I'm wondering if my logic is flawed somewhere. select2 AFAIK doesn't have a toggle method on the version we're on, so I have to manually use it's open and close methods. This is what I tried.
$('[data-variable-type=select]').on('click', function(e){
e.stopPropagation();
var _dropdown = $(this).find('div.interface_dropdown');
if( _dropdown.hasClass('select2-dropdown-open') ) {
$(this).find('select.interface_dropdown').select2('close');
}
else {
$(this).find('select.interface_dropdown').select2('open');
}
});
This causes it to open properly, but when you click to close it, it closes on mousedown but reappears on mouseup.
Is there someway I can get it toggling properly?
Will you post relevant HTML? It's hard to understand what you're doing without seeing content.
$('[data-variable-type=select]').on('click', function(e){
e.stopPropagation();
var _dropdown = $(this).find('div.interface_dropdown');
if( _dropdown.hasClass('select2-dropdown-open') ) {
_dropdown.removeClass('select2-dropdown-open');
_dropdown.select2('close');
} else {
_dropdown.select2('open');
_dropdown.addClass('select2-dropdown-open');
}
});
It looks like you forgot to add/removethat class, maybe this will work better? Again, I'm kind of feeling around in the dark here without seeing your content.
if( _dropdown.hasClass('select2-dropdown-open') ) {
$(this).find('select.interface_dropdown').select2('close');
}
in later versions of select2 (3.3+ iirc) this will never get triggered because when opened select2 creates a transparent mask over the entire browser and listens to click events. when the mask is clicked currently opened select2 is closed. this was the only reliable way to close a select2 when the user is ready to do something else.
The proper way is:
$('select').data('select2').toggleDropdown()
I've created dialog windows; and I want them to be closed whenever the uses clicks anywhere else than the dialog window buttons (hyperlinks).
I was creating one large "overlay" div (0 opacity) at the back of dialog window to catch the clicks, but that becomes quite problematic when the user wants to clck anything at the back (like another hyperlink) as well as closing the dialog at the same time. Since there is overlay, it becomes activated (to close the dialog) and the clicked hyperlink is not catched.
Shortly, I need a solution for this situation where I'll close the dialog windows whenever user does anything except clicking the dialog window buttons.
I hope it's clear; thank you.
This is being caused by event bubbling. It's a shame that 2 people downvoted #Lilith2k3 answer because he wasn't wrong and #Xotic750 had way too complex a solution. You do need an event handler on your body, but you need simply to filter out clicks from the your dialog.
You need two onclick() handlers. One in your body to close the dialog, and the other in your dialog to cancel event bubbling. See below
function dlgClickHandler(e) {
// do dialog stuff, then...
e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); // cancel event bubbling so body click handler not activated
}
function bodyClickHandler(e) {
// close dlg
}
This is also the reason you can't do this simply by comparing the ID of the dialog, because the click may have come from one of the children (eg. your OK, cancel buttons).
Working DEMO
Without jQuery DEMO
I've wrapped the functions in a module pattern to make it a neater component, and although I've used jQuery in the first example (which I suspect you are not) the technique pre-dates jQuery.
One of the reasons I suspect you're not using jQuery, is because if you were you'd probably already have stumbled across one of the many jQuery popup plugins for handing dialogs like this. If you've not tried jQuery take a look, it might help you out in many other ways too.
This is a very basic demonstration. We have a yellow div on the screen that represents your dialog. If you click anywhere in the div then it remains visible, you could fill this div with more HTML and event handlers to do as you wish. Click anywhere outside of the div and the div will become hidden. Note: I am not cleaning up any event handlers, which you will want to do.
Please see the answer by cirrus, where he actually gives an explanation about event propagation and why you will need it in your solution, which I haven't done here. He also gives you a solution using vanilla javascript and jquery, which I don't. He also demonstrates the javascript module pattern where I have not. I wouldn't have been able to bring you this answer without his constructive critisism and tuition, which prompted me to come back here and improve on my original poor, time constrained answer. Good luck.
CSS
.box {
width:300px;
height:100px;
position: absolute;
top: 30%;
left: 30%;
background-color:yellow;
border:2px solid;
}
#message {
position: absolute;
right: 50%;
bottom: 50%;
}
#button1 {
position: absolute;
right: 0;
bottom: 0;
}
#button2 {
position: absolute;
right: 4em;
bottom: 0;
}
HTML
<div id="box" class="box">
<div id="message"></div>
<button id="button1">
<img src="http://img856.imageshack.us/img856/3817/ticklf.png" alt />Ok</button>
<button id="button2">
<img src="http://img822.imageshack.us/img822/1917/crossn.png" alt />Cancel</button>
</div>
JavaScript
function dontBubble(evt) {
evt.stopPropagation();
}
function hideBox(evt) {
box.hidden = true;
}
function messgage() {
document.getElementById("message").textContent = "I'm ignoring you";
}
document.getElementById("box").addEventListener("click", dontBubble, false);
document.getElementById("button1").addEventListener("click", messgage, false);
document.getElementById("button2").addEventListener("click", hideBox, false)
document.addEventListener("click", hideBox, false)
;
On jsfiddle
At best, you would bind a click event to $("body"), which checks, where the user clicked and in case the user clicked not within the dialog, you could unbind the event and close the dialog.
Suppose I have a button, which goes into a down state when someone clicks on it, but before the mouse is released.
Now suppose instead that someone presses the 'a' key, I want the button to go into the down state, until the key is released, at which point it is triggered. Is this possible?
After dooing some research here is the final answer I got:
You can trigger mousedown or mouseup events on a button element using keyup and keydown
if your button is programmed to change its style according to these events than you are good to go.
See this fiddle example: http://jsfiddle.net/FwKEQ/15/
Note that if you use jQuery's UI components than it does work. But for standard buttons there is no way that you can move them to their pressed state using javascript
html:
<button id="jQbutton">Press 'A' to move me to pressed state</button>
Javascript:
<script>
$( "#jQbutton" ).button();
$(document).keydown(function(event) {
if ((event.keyCode === 97)||(event.keyCode === 65))
$("#jQbutton").mousedown();
});
$(document).keyup(function(event) {
if ((event.keyCode === 97)||(event.keyCode === 65))
$("#jQbutton").mouseup();
});
</script>
EDIT:
There might be a hack that we could utilize:
using accesskey for the button element and then try to simulate the accesskey press (that i am not sure if possible)
here is where i'm at so far http://jsfiddle.net/FwKEQ/28/
EDIT 2:
So looking further into this topic i have found the following:
Default buttons (without styles) are rendered by the OS, I was not able to find a formal proof for that but if you try to load the same page using a mac OS you'll get mac OS style buttons while in windows you will get the "ugly" gray button.
Because the default buttons are rendered by the OS they comply to OS events meaning events that are sent by the browser and are trusted.
this is not true for custom styled buttons as they comply to CSS an JS to change their appearance on press that is why the JQ button is affected by JS.
so to summarize you would need a trusted press event to fire on a default button to change its style and that cannot be done due to security constraints.
read a bit more about trusted events here: http://www.w3.org/TR/DOM-Level-3-Events/#trusted-events
and if someone could find a formal reference with regards to the default buttons being rendered by the OS please comment or edit this answer.
Unfortunately the rendering of the active state on default buttons neither
is a simple matter of css styling nor can be easily changed by applying
javascript.
An option to do this on default buttons is to use the hotkeys jquery plugin: https://github.com/jeresig/jquery.hotkeys or implement alternative key codes for different browsers.
and to apply 50% opacity to the default button when pressed (to indicate the keydown).
(To me it seems almost perfect ;-) It probably is as good as it can easily get to work across platforms and browsers using default buttons.
jsfiddle DEMO
and the code ...
html:
<button id="test">Test Button</button>
Selected: <span class="selected" id="out"></span>
javascript:
$('#test').click(function () {
fn_up();
});
fn_down = function(event){
$('#test').css("opacity", 0.5);
$('#test').focus();
event.preventDefault();
}
fn_up = function(event){
$('#test').css("opacity", 1);
$('#out').append(" test");
event.preventDefault();
}
//to bind the event to the 'a' key
$(document).bind('keydown','a', fn_down);
$(document).bind('keyup','a', fn_up);
//to get the same effect with the 'space' key
$(document).bind('keydown','space', fn);
$(document).bind('keyup','space', fn2);
In the fiddle I apply it to the space button and the mousedown/up to achieve the same effect with all events (but you could just use it with the 'a' key ... this is a matter of taste).
Here is a jsfiddel that shows how it's done using jQuery: http://jsfiddle.net/KHhvm/2/
The important part:
$("#textInput").keydown(function(event) {
var charCodeFor_a = 65;
if ( event.which == charCodeFor_a ) {
// "click" on the button
$('#button').mousedown();
// make the button look "clicked"
$('#button').addClass('fakeButtonDown');
// do some stuff here...
// release the button later using $('#button').mousedown();
}
});
The button event is triggered when entering "a" in the input field. But as Mark pointed out you need to fake the styling for the clicked button because the browser doesn't do it.
Edit: I'm not sure if you're using jQuery in your project. I just wanted to show that it is possible at all. If it can be done with the jQuery library there is also a way to do it in pure javascript. ;)