I am in charge of a website at work and recently I have added ajaxy requests to make it faster and more responsive. But it has raised an issue.
On my pages, there is an index table on the left, like a menu. Once you have clicked on it, it makes a request that fills the rest of the page. At anytime you can click on another item of the index to load a different page.
Before adding javascript, it was possible to middle click (open new tabs) for each item of the index, which allowed to have other pages loading while I was dealing with one of them.
But since I have changed all the links to be ajax requests, they now execute some javascript instead of being real links. So they are only opening empty tabs when I middle click on them.
Is there a way to combine both functionalities: links firing javascript when left clicked or new tabs when middle clicked?
Does it have to be some ugly javascript that catches every clicks and deal with them accordingly?
Thanks.
Yes. Instead of:
...
Do this:
...
And then in your JS, hook the link via it's ID to do the AJAX call. Remember that you need to stop the click event from bubbling up. Most frameworks have an event killer built in that you can call (just look at its Event class).
Here's the event handling and event-killer in jquery:
$("#thisLink").click(function(ev, ob) {
alert("thisLink was clicked");
ev.stopPropagation();
});
Of course you can be a lot more clever, while juggling things like this but I think it's important to stress that this method is so much cleaner than using onclick attributes.
Keep your JS in the JS!
Yes, You need to lookup progressive enhancement and unobtrusive Javascript, and code your site to work with out Javascript enabled first and then add the Javascripts functions after you have the basic site working.
I liked Oli's approach, but it didn't discern from left and middle clicks. checking the "which" field on the eventArgs will let you know.
$(".detailLink").click(function (ev, ob) {
//ev.which == 1 == left
//ev.which == 2 == middle
if (ev.which == 1) {
//do ajaxy stuff
return false; //tells browser to stop processing the event
}
//else just let it go on its merry way and open the new tab.
});
It would require some testing, but I believe that most browsers do not execute the click handler when you click them, meaning that only the link is utilized.
Not however that your handler function needs to return false to ensure these links aren't used when normally clicking.
EDIT:
Felt this could use an example:
<a href="/Whatever/Wherever.htm" onclick="handler(); return false;" />
link text
For more info and detailed explanation view my answer in another post.
Possibly, I could provide two links each time, one firing the javascript and another being a real link that would allow for middle click.
I presume, one of them would have to be an image to avoid overloading the index.
The onclick event won't be fired for that type of click, so you need to add an href attribute which would actually work. One possible way to do this by adding a #bookmark to the URL to indicate to the target page what the required state is.
Related
I wrote this script a while back that's worked better for me than any other right-click-enabling extension.
function rightClickEvent(event) {
event.stopPropagation();
return true;
}
function enableRightClick(elements) {
if (elements.length === 0) return;
Array.prototype.slice.call(elements, 0).forEach(element => {
element.addEventListener('contextmenu', rightClickEvent, true);
enableRightClick(element.children);
});
}
enableRightClick(document.children);
It seems like overkill because it adds an action listener to every single element on the whole page. Is there any way to achieve similar results, like a way to intercept every event for oncontextmenu, without having to traverse the DOM of the entire page?
To clarify, this is for ENABLING right click in environments where a simple change of contextmenu on the button doesn't work.
I'd suggest that you just use document.getElementsByTagName("*") to fetch a nodeList of all the elements in the document rather than recursively walking the hierarchy yourself.
And, for completeness, you may have to monitor for DOM elements being inserted into the page dynamically after you hook up.
How to work around a page that disables right clicking depends entirely upon how the page implements the disable. If you want a method that handles the most possible ways it might disable it, then you HAVE to handle it at the leaf nodes and on every node like you are doing - there is no other way. Any simpler option that uses event propagation to handle the event at a higher level may be blocked by the JS in the page so if you're trying to avoid being blocked by that, then you have to handle it at the leaf node.
I have a standard link setup that fires an event via jquery when clicked
Click Me
All that works great, except that when the pseudo URL is clicked, it appends a hashtag (#) to the url. This hashtag affects how my page reloads if the user decides to refresh the page later on, so i'd like to not have the hashtag appended to the url.
is this possible while still allowing my normal jquery to fire?
Thanks!
You should either return false; from the event handler of A tag
Or, use
Click Me
For those who thinks javascript: void(0) is bad practice
If you use href='#', you must take care of two things
// one
function fn() {
// code
return false;
}
// two
click
And if you forget and just write onclick="fn();" it won't work
Another thing why I used javascript: void(0); is, if the function encounters/throws an error, it wont return false
So if you're a lone developer then you can clearly make your own choice, but if you work as a team you have to either state:
Use href="#", make sure onclick always contains return false; at the end, that any called function does not throw an error and if you attach a function dynamically to the onclick property make sure that as well as not throwing an error it returns false.
OR
Use href="javascript:void(0)"
Which "href" value should I use for JavaScript links, "#" or "javascript:void(0)"?
In end of the you click function, use:
return false;
smartass anwser: use a button.
alternative: you must make sure to trigger the preventDefault in youre jQuery event handler
$("dosomthing").click(function(e){
//make magic happen
e.preventDefault()
})
this works on html forms thats submitting and such.
note on the button thing
it is best pratice to only use a tags for link (somthing that changes the url) and buttons for other sorts of interactions.
search bots and other web crawlers expect a tags to link to a other html document (hyperlink) and up to and including html 4. or to a other point in the current document.
Does it need to be an href at all? you could do:
<span class="dosomething">Click me</span>
.
.dosomething{cursor:pointer}
I wrote an alternative to the jQuery Accordion, as that didn't offer multiple open section support (any idea why they opted to not include support for that? What's the history there?). I did some research on StackOverflow, as well on Google to see what other options others came up. I needed something that could be used on the fly on multiple elements.
After seeing several solutions and experimenting with them, in the end, I wrote my own version (based on Kevin's solution from http://forum.jquery.com/topic/accordion-multiple-sections-open-at-once , but heavily modified).
jsFiddle can be found here: http://jsfiddle.net/3jacu/1/
Inline Code:
$(document).ready(function(){
$.fn.togglepanels = function(){
return this.each(function(){
h4handler = $(this).find("h4");
$(h4handler).prepend('<div class="accordionarrow">▼</div>');
$(h4handler).click(function() {
$(h4handler).toggle(
function() {
barclicked = $(this);
$(barclicked).find(".accordionarrow").html('►');
$(barclicked).next().slideUp('slow');
window.console && console.log('Closed.');
return false;
},
function() {
barclicked = $(this);
$(barclicked).find(".accordionarrow").html('▼');
$(barclicked).next().slideDown('slow');
window.console && console.log('Open.');
return false;
}
);
});
});
};
$("#grouplist").togglepanels(); }
Oddly, the accordion arrow at the right side stopped working once I pasted it in jsFiddle, while it works in my local copy.
In any case, the issue is that toggling isn't working as expected, and when it does, it fires duplicate toggle events which result in it closing, opening, then ultimately closing the section and it won't open from that point on (it toggles open then closes back). That's assuming it works! At first, it won't work as it doesn't respond. I think there's a logic error somewhere I'm missing.
From what I wrote/see in the code, it searches the given handle for the corresponding tag (in this case, h4), pops the handle into a variable. It then adds the arrow to the h4 tag while applying the accordionarrow class (which floats it to the right). It then adds a click event to it, which will toggle (using jQuery's toggle function) between two functions when h4 is clicked.
I suspect the problem here is that I may be mistakenly assuming jQuery's toggle function will work fine for toggling between two functions, that I'll have to implement my own toggle code. Correct me if I'm wrong though!
I'm trying to write the code so it'll be as efficient as possible, so feedback on that also would be appreciated.
Thanks in advance for your time, assistance, and consideration!
You have the toggle binding (which is deprecated by the way) inside of the click binding, so a new event handler is getting attached every time you click the header.
As a random aside you should also fire events within the plugin (where you have the console lines would make sense) so that external code can react to state changes.
I believe your issue is the $(h4handler).click(function() { you have wrapped around the toggle listener. Essentially what this was doing was making so every click of the tab was adding the toggle listener, which was then also firing an event. Removing the click listener will have the behaviour you expect.
You forgot to paste the trailing characters ); to close the function call to jQuery function ready. Fixed: http://jsfiddle.net/LeZuse/3jacu/2/
UPDATE: I've just realised I did not really answer your question.
You are duplicating the .toggle functionality with binding another .click handler.
The doc about .toggle says:
Description: Bind two or more handlers to the matched elements, to be executed on alternate clicks.
Which means the click event is already built in.
NOTE: You should use local variables instead of global, so your plugin won't pollute the window object. Use the var keyword for this:
var h4handler = $(this).find("h4");
I'm editing a start page made by someone else (found here: http://defined04.deviantart.com/art/KMay-Start-Page-184915031?q=gallery%3Adefined04%2F790342&qo=0). This lets you switch search engines by clicking on the different tabs. Is there a way to have the search box automatically selected when I select a tab? At the very least, how can I get the default engine to be selected on page load?
On the click handler of your tab, do this....
document.getElementById('tabs-container').getElementsByTagName('li').onclick = function () {
document.getElementById('search-input-' + this.id).focus();
}
Of course, change it to suit your HTML. Hopefully if you have a tie like that between them, you can write one event handler and not three.
You can use javascript focus() for that. Execute the script when the tab is changed.
Let's say I have a web page with a header menu, when I click the header menu, it calls a servlet that creates the sidebar. Is it possible that without using the document.getElementById? And just simulate keystrokes tab and enter via JavaScript so I don't have to click the menu to view the sidebar?
Could you describe what you want to achieve a bit more?
What I understood is that you want to be able to show ( and may be also hide) the sidebar with the tab button.
You could use the .keypress() function in jQuery - http://api.jquery.com/keypress/
Also check out this tutorial on Nettuts, I think it may be useful for you -
http://net.tutsplus.com/tutorials/javascript-ajax/how-to-create-a-keypress-navigation-using-jquery/
You can use the attribute tabindex on the elements that makes your menu.
eg: <ul tabindex="1">... and set the focus on the first one when opening the page.
They will act as form field when you press tab.
Then for the enter place a single onkeyup listener on a parent node common to all menus items:
menuParent.onkeyup = function(ev){
var selectedMenu = ev.target || ev.srcElement,
keycode = ev.keyCode;
if(keycode === 13){
//the user pressed enter
}
...
}
You can do what you want using JavaScript, but there's a much easier way to do it than by simulating keystrokes.
I am assuming that what happens when you click the link is that a JavaScript function is called, which causes the submenu to appear. All you need to do is to find out what that function call is (let's say it's called "callTheFunction"), and then call it onload, like this:
<script type="text/javascript">
window.onload=callTheFunction;
</script>
Hopefully that will give you the idea. If you need any more help, please provide a URL or code sample.