anchor with hashbang, preventDefault - javascript

I'm working on a cordova project. I have a few links which have a listener, the href is set to "#".
Now in all my functions I'm providing the event and calling preventDefault().
For some reason (when visiting the app in browser). It will still navigate to /#.
Which causes the browser to open a new tab.
I used javascript:void(0) before which works perfectly, but it throws a list of errors on windows phone (metro app). since javascript: is not valid.
Anyone know how I should be able to solve this? (i'm using jQuery and simple HTML5 for this one).
e.g.:
/**
* Toggle the menu
*/
toggleMenu: function(e) {
if (e) {
e.preventDefault();
}
App.Core.menuOpen ? App.Core.hideMenu() : App.Core.showMenu();
return false;
},
So we bind the event like this, so when it's dynamically added it still works.
$(document).on("click", ".header-menu", App.Core.toggleMenu);
html with some strips
<div class="page" data-init="App.Functions.Purchase.init()">
<div id="panel-purchase" class="panel" data-init="App.SomeModule.init()">
<div class="panel-header">
<div class="panel-header-inner">
<span class="icon icon-menu"></span>
<div class="panel-header-title"><span>Some Title</span></div>
<span class="button dummy"></span>
</div>
</div>
...

As long as I don't get a better solution, for now I'm using no href
it's a standard in HTML5, allthough some sites complain it could target to itself. It works fine for a hybrid app, and I've never seen it targeting to itself in this case.
Better solutions are always better, there must be something nasty in the source (It's initially created by a third party).

Related

Jquery click/toggle not working on mobile

I tried some old answers from other questions, but none of them resolved my case. The toggle function is not working fro me. Below is the jquery:
jQuery(document).ready(function($) {
$(".team-member").click(
function() {
$(this).children(".description").toggle();
}
);
});
HTML:
<div class="team-member" data-style="meta_below">
<img alt="yes" src="source/to/img.jpg" title="Candice Rauter">
<h4 class="light">Name</h4>
<div class="position">Position Goes Herer</div>
<p class="description">blablabla</p>
</div>
Link for the section of the website(#our-team section).
Any help would be appreciated!
Thanks!
When you inspect your site on mobile, using sdk and Chrome, you get
Ignored attempt to cancel a touchend event with cancelable=false, for example because scrolling is in progress and cannot be interrupted.
warnings on your page.
Try using .on('click') rather than .click()
$(".team-member").on('click', function(){
$(this).children(".description").toggle();
});
This should work even for dynamically added elements. And I think your page is using ajax to load its content (from what I can see in the inspector).

Responsive Durandal dialog

I'm using Durandal in my new application and I have an issue with Durandal's dialog window (I'm using it to get some data from users).
When I set width of window manually, (by default Durandal set window position from JavaScript) and if I want to have window width 600px , I need to do that through CSS with .dialog { width: 600px! important}. and that's where all the problems starts.
On window resize, dialog is not responsive anymore, and when I have big form in it and window height is small, for example on laptops I cant see a half of my form and I don't get any scroll.
On mobile devices it's a total mess. Does anyone knows how to make this thing work?
I believe the Durandal modal is receiving love in Durandal 2.1 although I do not know if it will be responsive.
In the meanwhile, Durandal provides all the hooks you need to implement your own modal functionality - including the ability to define different types of modal dialogs. You can read more about it here:
http://durandaljs.com/documentation/Showing-Message-Boxes-And-Modals.html
I experimented briefly with this via some code found on google groups and was able to get bootstrap 3 modals working.
You're welcome to try it out and see if it works for you. Note that you must be using bootstrap 3 for this to work (durandal 2.0 starterkit etc comes with bootstrap 2)
In dialog.js, just before return dialog;
dialog.addContext('bootstrap', {
addHost: function (theDialog) {
var body = $('body');
$('<div class="modal fade" id="myModal"></div>').appendTo(body);
theDialog.host = $('#myModal').get(0);
},
removeHost: function (theDialog) {
setTimeout(function () {
$('#myModal').modal('hide');
$('body').removeClass('modal-open');
$('.modal-backdrop').remove();
}, 200);
},
compositionComplete: function (child, parent, context) {
var theDialog = dialog.getDialog(context.model);
$('#myModal').modal('show');
},
attached: null
});
and then activate with:
dialog.show(viweModel, null, 'bootstrap')
or I believe this would work also but I didn't test it:
dialog.showBootstrap(viewModel)
And your view should follow the markup pattern:
<div class="messageBox">
<div class="modal-header">
Header Markup
</div>
<div class="modal-body">
Body Markup
</div>
<div class="modal-footer">
Footer Markup
</div>
</div>
Here is the gist where I got the code:
https://gist.github.com/webm0nk3y/7603042
And the relevant google groups thread:
https://groups.google.com/forum/#!topic/durandaljs/8g7DDCuvlpU
If you want to disable the width-setting for custom modals, you can add the following style definition to your outermost div:
<div style="width:auto;">
Please note that this can cause strange behaviour in some browsers.
If there is something else you would like to have for MessageBoxes or Modals, especially for their positioning and sizing, please let me know and I can make some changes to the code. My email is tommi.gustafsson at loyalistic.com.
UPDATE 14 Jan 2014:
I made a new revision of dialog.js, which helps with problems with customizing the MessageBox (not custom modals). You can find it at:
https://github.com/TommiGustafsson/Durandal/blob/master/src/plugins/js/dialog.js
(That's still unofficial, since it's in my fork of Durandal.)
You can find the instructions how to use it here:
https://github.com/BlueSpire/Durandal/pull/362#issuecomment-32180718
If you have problems with MessageBox, I think this might help you.

HTML Anchor is not clickable after adding elements to the DOM

I've created an html page that looks like that:
<body>
...
<div id="calendar-cont">
...
<div id="overview">
<div id="overview-type">
<h3>Selected Shift Type</h3>
<div id="selected-shift-type-cont"></div>
</div>
<div id="overview-dates">
<h3>Selected Dates</h3>
<ul id="selected-dates-cont"></ul>
</div>
Submit
</div>
</div>
</body>
I also have a jQuery click listener for the tag:
$("#submit-overview").click(function() {
console.log("click");
submitDates();
});
This listener works as long as the DOM stay the way it is now. Whenever I add an element to the selected-shift-type-cont or the selected-dates-cont the listener does not work anymore. Does anyone has an idea why this problem occurs?
I add elements this way:
var tmp = new Date(date.getTime());
dates[dates.length] = tmp;
$("#selected-dates-cont").append("<li>" + getDateString(tmp, "dd.mm.yyyy") + "</li>");
and
$("#selected-shift-type-cont").html("<div>" + shiftType.name + "</div>");
As soon as one of these two pieces of code are executed, I cannot click the anchor anymore.
Update:
I use jQuery 1.9.1. Also I use Chrome (version 28.0.1500.71) for developing. When I test it on Firefox 22 everything works as expected. Since I use the jQuery .load() method to change the main content according to what the user clicked in the navigation bar. Therefore I need to run the website on localhost which I do using the python -m SimpleHTTPServer 8001 command on my Mac. This command starts a webserver from the directory I called that command. Is it possible one of these factors might be the problem
Update 2:
I did not mention until now that I use the fullCalendar jQuery plugin. I also created a jsFiddle that reproduces the problem http://jsfiddle.net/XagK5/3/. It contains all important parts, I also included the whole fullCalendar minified javascript code, because I did not know how to include an external script.
Update 3:
It does work if I add the following CSS:
#submit-overview {
position: relative;
z-index: 99;
}
http://jsfiddle.net/72wyN/1/
Everything works for me with FF 22.
You must be using an older (read: obsolete) version of jQuery or your code is doing more than you showed us or your browser is defunct. Please elaborate further.
$("#submit-overview").click(function() {
console.log("click");
alert("still works");
});
window.setInterval(function() {
$("#selected-dates-cont").append("<li>1/1/2000</li>");
$("#selected-shift-type-cont").html("<div>blah</div>");
}, 4000);

Javascript and target="_top"

I'm working with a legacy frames website that was just moved into an iFrame.
Assuming I have the following function:
<script language = "javascript">
function myFunction(){
<!-- no console.log in IE 7 (my required target browser) -->
alert('sup, yo?');
}
</script>
and the following hyperlink triggering the function:
click me
before the move into an iFrame this worked ok. Once the website was moved into the iframe, clicking the link in IE (not FF or Chrome), I would get the ever-so-helpful error:
Line: 1
Object expected
Once I removed the target="_top" attribute the function would work, so I don't need help solving the problem, but my question is:
What is IE doing with the target attribute when calling a javascript function to invoke this behavior? I don't have other versions of IE installed, is this current behavior in 8+ as well?
Thanks.
It does not make sense to try to understand the behavior. You're using a technique that is not well defined and is not used by developers nowadays.
Instead of href="javascript:myFunction();, just use onclick="myFunction(); return false" or even better, set the handler from JS like the following
<a href="pageForUsersWithoutJs.html" id="my-link" >click me</a>
<script type="text/javascript">
// This is old school, but works for all browsers, you should use a library instead
document.getElementById('my-link').onclick = function() {
// Do your thing
return false; // so the link isn't followed
};
</script>

How can I tell if a page has jumped to the anchor (#) in JavaScript?

I have some JavaScript that can appear on many different pages. Sometimes those pages have been accessed via a URL containing an anchor reference (#comment-100, for instance). In those cases I want the JavaScript to delay executing until after the window has jumped. Right now I'm just using a delay but that's pretty hackish and obviously doesn't work in all cases. I can't seem to find any sort of DOM event that corresponds to the window "jump".
Aside from the simple delay, the only solution I've come up with is to have the JS look for the anchor in the URL and, if it finds one, watch for changes in scrollTop. But that seems buggy, and I'm not 100% sure that my script will always get fired before the scrolling happens so then it would only run if the user manually scrolled the page. Anyhow, I don't really like the solution and would prefer something more event driven. Any suggestions?
Edit to clarify:
I'm not trying to detect a hash change. Take the following example:
Page index.php contains a link to post.php#comment-1
User clicks the link to post.php#comment-1
post.php#comment-1 loads
$(document).ready fires
Not long later the browser scrolls down to #comment-1
I'm trying to reliably detect when step 5 happens.
You can check window.onhashchange in modern browsers. If you want cross compatible, check out http://benalman.com/projects/jquery-hashchange-plugin/
This page has more info on window.onhashchange as well.
EDIT: You basically replace all anchor names with a similar linking convention, and then use .scrollTo to handle the scrolling:
$(document).ready(function () {
// replace # with #_ in all links containing #
$('a[href*=#]').each(function () {
$(this).attr('href', $(this).attr('href').replace('#', '#_'));
});
// scrollTo if #_ found
hashname = window.location.hash.replace('#_', '');
// find element to scroll to (<a name=""> or anything with particular id)
elem = $('a[name="' + hashname + '"],#' + hashname);
if(elem) {
$(document).scrollTo(elem, 800,{onAfter:function(){
//put after scroll code here }});
}
});
See jQuery: Scroll to anchor when calling URL, replace browsers behaviour for more info.
Seems like you could use window.onscroll. I tested this code just now:
<a name="end" />
<script type="text/javascript">
window.onscroll = function (e) {
alert("scrolled");
}
</script>
which seems to work.
Edit: Hm, it doesn't work in IE8. It works in both Firefox and Chrome though.
Edit: jQuery has a .scroll() handler, but it fires before scrolling on IE and doesn't seem to work for Chrome or Firefox.
To detect when the element appears on the screen, use the appear plugin:
$('#comment-1').appear(function() {
$(this).text('scrolled');
});

Categories