jQuery "window.location.hash" - getting hash too late? - javascript

I'm working on some script but it have a serious problem with hashes.
I have a list of link-images like:
<img src="1.jpg" />
<img src="2.jpg" />
<img src="3.jpg" />
All I want to do is to load file files/#1.html after clicking the first image, files/#2.html after the second etc.
Here's my jQuery function:
$("a img").click(
function()
{
var hash = window.location.hash;
$("#displayFile").load('files/'+ hash +'.html');
$("#displayFile ").fadeIn(300);
});
So when I click a image it should add hash to the url (href="#1"), load the right file to #displayFile div and fade it in.
But actually when I click the image it shows empty #displayFile div and after i refresh the site with the same hash it loads the content. I believe the script gets the hash long before it's in URL.
How to fix it?
Thanks.

Event handlers run before default actions. Short of nasty tricks involving setTimeout you can't get the link to be followed before the function completes.
Read this.href instead.
That said, it sounds like you are using arbitrary fragment identifiers instead of URIs to sensible things. If so: I'd fix up the href so it points to a real URL that loads the image. Build on things that work.

When you click the link, code will be executed in the following order:
jQuery click-handlers
onclick-handlers
native/default behavior (calling the link, writing it to window.location)
I would recommend that you use this.href instead. Also use e.preventDefault() so the native/default behavior isn't performed by the browser.

Since the default event changing the location.hash hasn't happened yet, you can fetch the .hash from the anchor directly instead, like this:
$("a img").click(function() {
var hash = this.parentNode.hash;
$("#displayFile").load('files/'+ hash +'.html').fadeIn(300);
});
Though, since the image is the only thing, you can attach the handler to the <a> itself, like this:
$("a").click(function() {
$("#displayFile").load('files/'+ this.hash +'.html').fadeIn(300);
});

Related

how to call or display a div by changing url using href?

i am trying to show a div which is currently hide and inside body tag.by changing url using anchor tag attribute href.Like below---
<a id="ai" href="managevendors" class="tablink" onclick="openCity()">Manage Vendors
</a>
<div class="w3-container city" style="display: none;" id="managevendors">
<h1>hi,how are you</h1>
</div>
when i click on this anchor tag my url will definitely changed.and based on url i wants to display a div.
my js code...
function openCity() {
if (window.location.hash == "managevendors") {
$("#managevendors").show();
}
}
i dont know why this is not working.but i teide with different way like below..
<a id="ai" href="#managevendors" class="tablink" onclick="openCity('managevendors')">Manage Vendors
</a>
and js code.....
function openCity()
{
if (window.location.hash == "#managevendors") {
$("#managevendors").show();
}
}
but i dont want the # sing,how can i solve it.help me experience brothers.thanks in advance.
You must use the hash if you expect the navigation to work. Once you do that, you don't need to check for it, you can just show the section:
$("#ai").on("click", openCity);
function openCity() {
// The only reason this code is running is because the link was clicked.
// No need to test for it.
$("#managevendors").show();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- You have to include the hash in the href for navigation to work -->
<a id="ai" href="#managevendors" class="tablink">Manage Vendors
</a>
<div class="w3-container city" style="display: none;" id="managevendors">
<h1>hi,how are you</h1>
</div>
I think the problem here is that you are using an anchor tag when you should be using a button. The reason the first way is not working is due to the page refreshing when you click the link.
Try changing your <a> to a <button>
From what I understand, you most likely need the href="#xyz" with a hash. This will keep clientside logic active without trying to solve the url and take a detour to the server for nothing. If you're going to capture that part, keep it local.
I suggest to remove the onclick handler from HTML. To capture the link you can use jQuery to keep your HTML "clean". If you must, for some odd reason, by all means you can reference onclick="openCity(this)", so the element you click on is passed directly to openCity.
// vanilla
function openCity(element){
var href = element.getAttribute('href'), // expecting a hash here
id = href.substr(1), // remove the hash
target = document.getElementById(id);
target.className += " active";
return false;
}
As Scott suggests with jQuery:
//$('.tablink').on('click', openCity);
$('.tablink[href^="#"]').on('click', openCity);
Then the function can be made dynamic by referencing the href from the clicked element:
function openCity(ev){
var el = $(ev.currentTarget),
id = el.prop('href'), // expecting a hash here
target = $(id);
// since you're providing both with and without hash, the default behaviour is to follow the link, unless referenced with a hash
ev.preventDefault();
target.addClass('active');
}
If the id was not found on the page, this will void silently.
Now if you want to work with the url as entry point, note that this will only happen on load event => share a link and someone clicks on it (with the #xyz attached) or type directly in the address bar.
// 1. bind the event
$(window).load(function(){
/*loadCity defined here or outside*/
loadCity();
});
// 2. define what happens
function loadCity(){
var id = window.location.hash, // expecting a hash here
target = $(id);
target.addClass('active');
}
Since this solution only solves state of an element, the actual show/hide part can be made in CSS. Very simple as you probably already did or with animations, transitions and so on.
.city { display: none; }
.city.active { display: block; }

Maintain Scroll position after div.toggle (JQUERY)

How do I maintain my page scroll position after JQUERY toggle event, I have searched and researched but couldn't find any solution to remedy this problem.
<script src="Scripts/_hideShowDiv/jquery-1.3.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#adddriverpanel').hide();
$('a#adddrivertrigger').click(function () {
$('#adddriverpanel').toggle(400);
});
});
</script>
After reviewing your code, you simply need to update your html to the following:
<a id="adddrivertrigger" href="javascript:void(0);" class="auto-style2">Add Drivers</a>
The '#' you had in the link is what is taking you to the top of the page.
If you're going to use an anchor tag with an href for a click event, you need to prevent the href from firing (assuming you don't want it to). You can usually do this with adding
return false;
To your click event, but better practice for empty href attributes is to create a null javascript call as opposed to a '#'.
For giggles, here are some other things you should /not/ do with href attributes:
All of the above are either invalid javascript or pose inconsistency problems with different browsers.
Another way you could have solved it (via jQuery) is as follows:
$('a#adddrivertrigger').click(function () {
$('#adddriverpanel').toggle(400);
return false;
});

Replacing asp:imagebutton with processing image using jquery

So I have an asp:imagebutton for lets say loginning into a web site.
OnClick the page does xyz and then redirects you, there is a pause time between the redirect from when the button was clicked. To make the wait a bit more user friendly I am replacing the button with a processing image and text the javascript that does this is:
$(document).ready(function () {
$(".ShowProcessing").click(function () {
$(this).replaceWith("<img src='/content/images/processing.gif' /> Processing");
});
});
This is the button:
<asp:ImageButton ID="Login" runat="server" OnClick="Login_Click" CssClass="ShowProcessing" />
The problem is the change to processing image happens but the asp OnClick event however does not fire.
Instead of replacing the entire element with something else entirely, just alter the src of the current element:
$(".ShowProcessing").click(function () {
$(this).attr("src", "/content/images/processing.gif");
});
This is if ImageButton is rendered as an img proper, somewhere, and not just some funky input with scripting (I don't recall off the top of my head, and webforms does some things in strange ways). Then proceed to insert text after the existing element as desired.
Instead of using .replace() tried and succeeded with:
$(".ShowProcessing").click(function () {
$(this).hide();
$(this).after("<img src='/content/images/processing.gif' /> Please wait..." )
});
I guess you may try to remove the first image and then add the new processing image.
instead of replace use (Remove then add) functions.

How to get Anchor Links to work in Jquery Mobile?

Jquery Mobile has decided to treat anchor links as page requests of sort. However, this isn't good if you have a load of blog posts which have anchor links to the same page (ie href="#specs").
Is there a way to disable jquery mobile's anchor link usage on a specific page which I know I won't be using it on so I can use anchor links as they were intended, to drop down to a part of the page?
I only need a solution for anchor links on the same page (ie: href="#specs").
thanks
You could try adding a data-ajax="false" on the anchor tag.
Linking without Ajax
Links that point to other domains or that have rel="external",
data-ajax="false" or target attributes will not be loaded with Ajax.
Instead, these links will cause a full page refresh with no animated
transition. Both attributes (rel="external" and data-ajax="false")
have the same effect, but a different semantic meaning: rel="external"
should be used when linking to another site or domain, while
data-ajax="false" is useful for simply opting a page within your
domain from being loaded via Ajax. Because of security restrictions,
the framework always opts links to external domains out of the Ajax
behavior.
Reference - http://jquerymobile.com/demos/1.0.1/docs/pages/page-links.html
If you are like me, converting an existing site and you don't want to go through every page right now. You can add one line of code to your header and all of your header and all of your existing internal anchor links will get the data-ajax="false" tag added.
Of course, this assumes you are including your own javascript file up in the header already. If you are not you would have to touch every page anyway. But I have a single javascript file that is included in every page already so I added this line...
$("a").each(function () { if(this.href.indexOf("#")>=0) $(this).attr("data-ajax",false); });
This goes in your $(document).ready() block. If you don't have that block yet, here is the entire block.
$(document).ready(function() {
$("a").each(function () { if(this.href.indexOf("#")>=0) $(this).attr("data-ajax",false); });
});
Hope this helps. It is the same solution user700284 offers but in an automated way.
You can add the following code to the end of your page:
<script type="text/javascript">
$('a.native-anchor').bind('click', function(ev) {
var target = $( $(this).attr('href') ).get(0).offsetTop;
$.mobile.silentScroll(target);
return false;
});
</script>
And add the class "native-anchor" to your anchor links.
It is not a total sollution, because the back button of your browser will move you to the previous page and not to the position of the link, but it is better than the links not working at all.
I found this sollution here: jQuery Mobile Anchor Linking
$(document).bind("mobileinit", function () {
$.mobile.ajaxEnabled = false;
});
First you have to place this code into a custom.js file
$(document).bind('mobileinit', function () {
$.mobile.loader.prototype.options.disabled = true;
$.mobile.ajaxEnabled = false;
$.mobile.linkBindingEnabled = false;
$.mobile.loadingMessage = false;
});
Then add this file into your webpage before the jquery mobile js is loaded. becuase 'mobilinit' event is triggered immediately
Thank you
this solution worked for me
<script>
$(document).ready(function() {
$("a").each(function() {
if (this.href.indexOf("index.php") >= 0) $(this).attr("data-ajax", false);
});
});
</script>
I replaced # with index.php which is my document root.
But, it doesn't work for form button i.e input type="submit"
// On page load on mobiles only, look for the specific a tag you want to take control over,
// alternatively you can still target all 'a' tags
$('a[href*="#component"]').each(function () {
// then set data-ajax to false,
$(this).attr("data-ajax", false);
// at this point you can add the class to your target a tags.
// You can do it elsewhere but because for this example my
// 'a' tags are automatically generated so I just add the class here
$(this).addClass('in-pagelink');
// then target the class and bind to a click event
$('a.in-pagelink').bind('click', function (ev) {
// here I redirect the page with window.location.assign
// as opposed to window.location.href. I find that it works better
window.location.assign(this.href);
// then I close my navigation menu
closeAll();
});
});

Executing JavaScript when a link is clicked

Which is preferable, assuming we don't care about people who don't have JavaScript enabled?
Or
Is there any difference?
Or there any other ways I'm missing besides attaching an event to the anchor element with a JavaScript library?
The nice thing about onclick is you can have the link gracefully handle browsers with javascript disabled.
For example, the photo link below will work whether or not javascript is enabled in the browser:
foobar
it's better to use the onclick because that's the way the things should be.
The javascript: was somekind of hackish way to simulate the onclick.
Also I advice you to do some non intrusive Javascript as much as possible, it make the code more easy to read and more maintainable!
href="#" has a number of bad side effects such as showing # in the browser footer as the destination URL, and if the user has javascript disabled it will add a # at the end of their URL when they click the link.
The best method IMHO is to attach the handler to the link in your code, and not in the HTML.
var e = document.getElementById("#myLink");
e.onclick = executeSomething;
This is essentially the pattern you'd want to follow:
Write your HTML markup
Attach event handlers from JavaScript
This is one way:
<a id="link1" href="#">Something</a>
<script type="text/javascript">
// get a reference to the A element
var link1 = document.getElementById("link1");
// attach event
link1.onclick = function(e) { return myHandler(e); };
// your handler
function myHandler(e) {
// do whatever
// prevent execution of the a href
return false;
}
</script>
Others have mentioned jQuery, which is much more robust and cross-browser compatible.
Best practice would be to completely separate your javascript from your mark up. Here's an example using jQuery.
<script type="text/javascript">
$(function() {
$('a#someLink').click( function() {
doSomething();
return false;
});
});
</script>
...
some text
Yes I would agree to use onclick and leave the href completely out of the anchor tag... Don't know which you prefer to do but I like to keep the 'return false' statement inside by function as well.
The main difference is that:
The browser assume by default the href attribute is a string (target url)
The browser knows that in a onclick attribute this is some javascript
That's why some guys specify to the browser "hey, interpret javascript when you read the href attribute for this hyperlink" by doing ...
To answer the question, that's the difference!
OTOH what's the best practice when using javascript events is another story, but most of the points have been made by others here!
Thanks

Categories

Resources