PDA

View Full Version : Resolved JQuery .click mouse event not working, .hide effect does.



GSimon
09-25-2013, 04:50 AM
Website link: classfind.com/guelph/room/ALEX100other

I want to register a click event when I use the left arrow and right arrow keystroke.

I am using two scripts, the first script adds the class CurrentSelection to the first list item's href.


<script>
$(document).ready(function() {
$("#steplist2 li a").first().addClass("CurrentSelection");
});
</script>

The second script then hides the class CurrentSelection when I hit the left arrow key, then shows the class CurrentSelection when I hit the right arrow key.

<script>
$(document.documentElement).keyup(function (event) {
if (event.keyCode == 37) {
$('.CurrentSelection').hide();
} else if (event.keyCode == 39) {
$('.CurrentSelection').show();
}
});
</script>

So this works, but when I replace $('.CurrentSelection').hide(); with $('.CurrentSelection').click() it doesn't work. I have read many solutions saying I need to include .live or .on, but I don't know where to add it in. For instance this doesn't work $('.CurrentSelection').on().click()

Please help! I am having a difficult time troubleshooting this one...

jscheuer1
09-25-2013, 05:49 AM
.click() is fine there. However, I think it does something other than you imagine. It doesn't click the element. It executes any previously assigned jQuery click event(s) for that element. If there are none, it does nothing. It can also be used to assign a click event to an element, see:

http://api.jquery.com/click/

for more info.

If, on the other hand I've misunderstood and you do know what jQuery .click() does, what are you trying to do there? What does the markup look like?

If you want more help, please include a link to the page on your site that contains the problematic code so we can check it out.

GSimon
09-25-2013, 06:34 AM
That would make sense.....that it's registering a click event but there's nothing assigned to it.

I actually did include a link to the page in the original post lol. Here it is again though: classfind.com/guelph/room/ALEX100other

The end goal is to create this effect: http://jqueryfordesigners.com/adding-keyboard-navigation/ and I need this event to register before I can start working on the rest of the code.

Got the idea from imggur, here is an example of how they use it: http://imgur.com/a/sArwl (using arrow keys to go from one image to the next)

jscheuer1
09-25-2013, 03:04 PM
Add these styles to the stylesheet:


.mappics.activemap, .mappics2.activemap {
background-color:#fc2424;
}

.mappics.activemap #stepnumber, .mappics2.activemap #stepnumber {
background-color:#504f5b;
text-shadow: 2px 2px 0 #000000;
border:1px solid black;
height:28px;
}

and use this script instead of the two you have there now:


<script>
jQuery(function($){
var $steps = $("#steplist2 li a").removeClass("CurrentSelection").click(function(e){
$steps.removeClass("CurrentSelection");
$(this).addClass("CurrentSelection");
var $targ = $(this.hash);
$('.activemap').removeClass('activemap');
$targ.addClass('activemap');
$('html, body').animate({scrollTop: $targ.offset().top}, 'slow');
e.preventDefault();
}), $current, total = $steps.length, curindex, newindex, action;
$(document.documentElement).keydown(function (event) {
curindex = $('.CurrentSelection').length === 1? $('.CurrentSelection').parent().index() : null;
action = event.keyCode - 38;
if (Math.abs(action) === 1) {
if(curindex === null){curindex = -action;}
newindex = (curindex + action + total) % total;
$steps.eq(newindex).click();
event.preventDefault();
}
});
$(window).load(function(){setTimeout(function(){$('html, body').scrollTop(0);}, 0);});
});
window.onunload = function(){};
</script>

GSimon
09-25-2013, 04:36 PM
!!!!

Amazing!! Thanks so much John! I think replicating that on my own would have been a mind bending experience that wouldn't of resulted in something that good. Cool how it can jump from the last step, to step 1, then back to the last step again. Sent a tip

Also am your 3000th thank :P

You can see the result here: classfind.com/guelph/room/ALEX100other2

The only thing I changed was keydown to keyup, keydown works better it some ways because you can just hold down the right arrow/left arrow key to navigate, but it can make the page go crazy by registering too many keystrokes at once. If there's a way for it to stop it from registering a new keystroke until it reaches the next container that would be ideal, but really this is fine as is, I might look into that more later though.

jscheuer1
09-25-2013, 06:38 PM
Great! And thanks. I think that's a good way of dealing with keydown/keyup I hadn't thought of that. I did notice how holding down the key with keydown caused it to repeat, sometimes a lot. The alternative is to set and unset a flag. On keydown set the flag, if the flag is true, subsequent actions are not carried out. On keyup the flag is set to false. So you still need keyup. Not sure if that's an improvement or not. The less code and flags needed, generally the better. I always thought keydown was the way to go for anything like this, but that's leftover from years ago, before I ever started working with jQuery, something someone I respected said in these forums. It might have been more applicable then and/or to the specific situation then than it is with this code*.

BTW, the jump to number thing will still work without javascript, but of course not the arrow keys.

And, just looking at it again, I left an extra variable in there that's not used and you of course copied it:


<script>
jQuery(function($){
var $steps = $("#steplist2 li a").removeClass("CurrentSelection").click(function(e){
$steps.removeClass("CurrentSelection");
$(this).addClass("CurrentSelection");
var $targ = $(this.hash);
$('.activemap').removeClass('activemap');
$targ.addClass('activemap');
$('html, body').animate({scrollTop: $targ.offset().top}, 'slow');
e.preventDefault();
}), $current, total = $steps.length, curindex, newindex, action;
$(document.documentElement).keyup(function (event) {
curindex = $('.CurrentSelection').length === 1? $('.CurrentSelection').parent().index() : null;
action = event.keyCode - 38;
if (Math.abs(action) === 1) {
if(curindex === null){curindex = -action;}
newindex = (curindex + action + total) % total;
$steps.eq(newindex).click();
event.preventDefault();
}
});
$(window).load(function(){setTimeout(function(){$('html, body').scrollTop(0);}, 0);});
});
window.onunload = function(){};
</script>



The highlighted can be removed. It doesn't really hurt anything though. I had been using it in an earlier version of the code.


*I remember why keydown is preferable. If you need to cancel the default action, you have to use keydown. If the page were to have a horizontal scrollbar, the arrow keys would still move it left and right with keyup. And your code is more responsive with keydown, rather than waiting for keyup. So it's worth doing the flag thing to prevent repeats and to 'listen' for both events.

This seems to work:


<script>
jQuery(function($){
var $steps = $("#steplist2 li a").removeClass("CurrentSelection").click(function(e){
$steps.removeClass("CurrentSelection");
$(this).addClass("CurrentSelection");
var $targ = $(this.hash);
$('.activemap').removeClass('activemap');
$targ.addClass('activemap');
$('html, body').animate({scrollTop: $targ.offset().top}, 'slow');
e.preventDefault();
}), total = $steps.length, curindex, $current, newindex, action, flag;
$(document.documentElement).bind('keydown keyup', function (event) {
if(event.type === 'keyup'){flag = false; return;}
action = event.keyCode - 38;
if (Math.abs(action) === 1) {
if(flag){event.preventDefault(); return;}
flag = true;
$current = $('.CurrentSelection');
curindex = $current.length === 1? $current.parent().index() : -action;
newindex = (curindex + action + total) % total;
$steps.eq(newindex).click();
event.preventDefault();
}
});
$(window).load(function(){setTimeout(function(){$('html, body').scrollTop(0);}, 0);});
});
</script>

GSimon
09-25-2013, 07:26 PM
Ahh that makes sense, I think the people who coded Imgur ran into that exact problem with horizontal scrolling:

http://imgur.userecho.com/topic/28367-arrow-key-navigation-in-gallery/

I'll look into setting a callback also (implemented the new code, though holding down an arrow key won't jump to the next one until keyup still). I think the logic behind using keydown also is that in some cases the user might not think they've registered a keystoke (when using keyup) until they release the key, or just that with keydown the event happens sooner than keyup (sooner=better).

A feature that would be cool to add on later, though seems a bit too complicated to focus on it at the moment, would be:

If the page could detect where the user has scrolled to on the page, so that when the user hits the right arrow keystroke it would jump to the next element (the next step), rather than starting from the beginning at step 1. For instance, if you were looking at step 6 (by scrolling to the step, rather than using the jump list or arrow keys to navigate there), then you hit the right arrow key and it would jump to step 7.

The downside to the above feature is that the easiest way to implement it (though would still be complicated..) would be to have it so that the 2 classes (CurrentSelection and activemap) are being added/removed while you move up and down the page. The problem with that is I wouldn't want the containers to highlight as you are scrolling, I would only want that to happen when you hit the keystroke.

jscheuer1
09-25-2013, 10:03 PM
Imgur is actually having the opposite problem. When the arrow keys are needed (or at least would be nice) in a comment section's on page editor (like the posting on page editor here), they're still being commandeered by the Imgur script. That's actually a good reason not to use keys for anything in javascript, they might be needed for something else and not be available at that point for their native purpose. They should be able to solve their particular problem by checking the target element, if it's a textarea, the part of the script that usually uses the arrow keys can return before it cancels the default behavior of the key(s) and before it does any navigation. But you cannot always anticipate all of the possible uses the key(s) you want to commandeer might be put to. So generally it's better to find another way. With your page, since it has no other features that might need those keys, it should be OK in most cases. But it would be better to have all of the images be shown in one spot in turn (a slider) with a next and previous button that can be clicked or focused on and hit enter to activate. The jump to buttons could also be used to navigate this slider. That's for javascript capable browsers. For others, what you have is good. Both could exist on the same page with the same markup. Javascript can take the vertical list of images and compress them into a single viewing area that acts like a slider. Non-javascript users would see what you have now.

jscheuer1
09-27-2013, 06:29 AM
Anyways, I played around with your idea about detecting the scroll of the page. Not changing the active map color is easy (that class isn't required in order to keep track of the current image), some other parts of it were tricky. I also added some styles to get the rounded corners in IE 9+, as well as modified others to get the griffin icon to offset better. And I changed things so that when animating, you're brought to the top of the HR, not the top of the image, looks better I think. Finally, I changed when the color of an active map changes, waiting until after it had finished scrolling. Here's a demo (paste the URL into your browser's address bar and hit enter):

home.comcast.net/~jscheuer1/side/demos/tidbits/hashimage/hashimage.htm

Any questions, just let me know.

GSimon
09-27-2013, 06:25 PM
Very Cool! Works great. Appreciate you touching up things for IE also, that's never fun heh. I've been meaning to re-work the layout/theme a bit and never got around to much browser testing aside from Chrome/Firefox. Sent a tip.

It works just like I had hoped! Although there's one, hopefully kind of minor, change that would be nice to implement. I incorrectly worded my vision of what I was shooting for when I wrote


if you were looking at step 6 (by scrolling to the step, rather than using the jump list or arrow keys to navigate there), then you hit the right arrow key and it would jump to step 7.

I think it would be better if it highlighted the current step first, before jumping to the next step. So, if you were looking at step 6 (navigating there using page scroll) and hit an arrow key, it would highlight step 6 before moving on to step 7 (or step 5, if they hit the left arrow key).

Aside from that it works great to my liking. The hr offset I agree with, had a similar idea in mind when modifying the code before (offset it 10px from the top of page, rather than hr). I hadn't focused on that just yet as I may include a feature soon where on page scroll the jump list at the top would float to the right or left of the container, so it that it wouldn't be fixed at the top of the page at all times.

EDIT: I think really what I'm shooting for is for the left/right arrow navigation on page scroll to be as similar to the Imgur ex here: http://imgur.com/a/sArwl . They seem to using an approach that's slightly different from my amended suggestion, where using the left arrow key will navigate backwards, and using the right arrow key focuses on the current element and then navigates forward. Really though, I'm just trying to get it to be as intuitive as possible, which is the end goal.

jscheuer1
09-28-2013, 12:05 PM
Well, in this case IE actually uses the standard border-radius property. All others do now too, but older version of Mozilla/Firefox and Webkit/Safari/Chrome use only one or more of those now deprecated leading hyphen proprietary border radius properties. In Opera and current versions of those just mentioned, the deprecated versions are still supported.

While I'm on the subject, I just updated the demo to include more of those for IE 9+, for the steplist1 and the large and medium link elements.

The browser cache may need to be cleared and/or the page refreshed to see changes.

As for the behavior when scrolling with the mouse, or other methods besides the jump to buttons and left/right arrow keys, and then using the left/right arrow keys, I see no material difference between the current:

home.comcast.net/~jscheuer1/side/demos/tidbits/hashimage/hashimage.htm

and the imgur demo you linked to, except that the imgur one does no highlighting of the active panel's description. There might also be some slight difference in the sensitivity as to where exactly the cutoff is visa vis whether we've advanced or moved back a panel via these non-jump to left/right arrows methods. I'm having trouble pinpointing that, if it exists, due to the differences between the sizes of your page's panels and the imgur demo's.

To make it more intuitive, I think we could either drop the highlighting of the active description entirely, or make it so that navigating without jump to and left/right arrow keys also highlights the active description, something that at first you said you didn't want. I went ahead and did that though, you can see if you like the effect here:

home.comcast.net/~jscheuer1/side/demos/tidbits/hashimage/hashimageexthlght.htm

jscheuer1
09-28-2013, 07:39 PM
Update, I'm still playing around with this. I recently updated:

home.comcast.net/~jscheuer1/side/demos/tidbits/hashimage/hashimageexthlght.htm

to deal with a glitch they all seem to have had where if you hit the home key, under some circumstances it remembers where the last active one was and navigates from there if the arrow keys are then used. And to make it so that if the current one wasn't fully visible, the arrow keys would navigate to it in most cases (except when it doesn't make sense, like if the image and description are taller than the window).

I also played with the griffin a little more, moving it to the right to center it over the images instead of the box, that's a judgment call. Whichever you prefer:


hr {
overflow: visible;
height: 55px !important;
margin-bottom: 0;
background-image: url(http://classfind.com/guelph/images/griffin.png);
background-repeat: no-repeat;
background-position: 330px 9px;
}

That was center instead of 330px.



And I made a new demo with all that and reverting to only highlighting the active map when the buttons or arrows are not used:

home.comcast.net/~jscheuer1/side/demos/tidbits/hashimage/hashimagenew.htm

It's my current favorite.

GSimon
09-28-2013, 10:59 PM
Thanks for the added help!

The highlight affect on page scroll is neat, I had tried it out before but the result wasn't as good. The main issue with the highlighting on page scroll is that a lot of people view the site on a mobile device (retina screen) and a few steps are displayed at once, so the effect doesn't really work as well as it does on the desktop unfortunately.

The home key glitch is interesting, haven't been able to replicate it yet with the example provided here: home.comcast.net/~jscheuer1/side/demos/tidbits/hashimage/hashimage.htm although as you mentioned it probably requires a certain set of circumstances in order for it to happen. It's not too big of an issue really though.

The newest example I would adapt because it fixes the glitch (home.comcast.net/~jscheuer1/side/demos/tidbits/hashimage/hashimagenew.htm) although if you hit the right arrow key on page load (or after refreshing the page, same thing) it jumps to the last step, unlike the previous demo.

I'm actually quite pleased with the results of this demo: home.comcast.net/~jscheuer1/side/demos/tidbits/hashimage/hashimage.htm , the difference between the imgur page is really minor, so I'm not too phased by it. The griffin hr I'll look into more, appreciate you pointing out a different option to try out.

Thanks again :D

jscheuer1
09-29-2013, 02:21 AM
Turns out there are a number of glitches that can happen under the right circumstances, the key one of which is window height. The glitch I was mentioning would be common on a laptop with a wide screen like mine (1600 x 900), where unless you're viewing full screen, the first item isn't completely visible when the page is all the way at the top. In order to duplicate the problem you mentioned, I had to go full screen to have enough height for that to happen. I also discovered that if the current content is taller than the window and touches it top and bottom, one or the other or both of the left or right arrow keys will do nothing.

I think I got all those bases covered and have updated both the:

home.comcast.net/~jscheuer1/side/demos/tidbits/hashimage/hashimagenew.htm

and the:

home.comcast.net/~jscheuer1/side/demos/tidbits/hashimage/hashimageexthlght.htm

demos with the fixes.

The browser cache may need to be cleared and/or the pages refreshed to see changes.

Other than the highlight on non-button / left/right arrow scroll, the two demos are I think identical now.

I had tried to make the highlight on page scroll when not using buttons or left/right keys one (home.comcast.net/~jscheuer1/side/demos/tidbits/hashimage/hashimageexthlght.htm) highlight the lowest completely seen content, or in the absence of such, the content that predominates the screen. I don't have a screen tall enough to see if that works as intended if more than one content is completely visible at a time. But I could probably test that by zooming out. Just did, seems to work. Try it on one of those devices you mentioned, you might like it.

GSimon
09-29-2013, 03:15 AM
Awesome! Works great.

Glad you were able to fix the page height bugs. My current resolution is 1650 x 1050 so those extra pixels I guess were able to detect the initial page-height glitch heh.

I tested the highlighted version on the iPhone 5. It does work well, but unless I modify the layout with some media queries it's not quite ideal. For example:

http://oi42.tinypic.com/2iie334.jpg.http://oi41.tinypic.com/2pzwsx3.jpg

1st image: User might expect the step 8 to be highlighted since it is closest to the center of the screen. In this example I was scrolling up from step 10.
2nd image: When returning to the top of the page step 1 doesn't highlight since step 2 is still in view.

I will save the highlighted script for later when I've added in some media queries which could improve the functionality. Currently the images are not the full width of the screen, since it would require a larger image size or from them to be set a larger width that their current max-width of 650px.

GSimon
09-29-2013, 06:27 AM
I have another question actually...

I'll be using this script on another school site that uses Google maps for step 1. The CSS I can take care of (looks sloppy now, but should be no biggie) although the arrow keys are latching onto (focusing on) the Google Maps iFrame and thus ruining the arrow key feature.

ex: classfind.com/western/room/AH101new

Is there a way to use JQuery/Javascript to focus on the Body element of the page, rather than the iFrame, on page load?

Any insight is appreciated, could always replace Google maps with a static image, although...that would be a pain lol.

EDIT: Found a solution, but it feels sloppy

I added in the highlighted code
<body id="westernbackground" onblur="window.focus();">

Got the solution from here: http://stackoverflow.com/questions/7208064/prevent-an-iframe-from-stealing-focus

and apparently


This has some not so nice side-effects like not being able to focus the location bar in Firefox or getting into endless loops if the frame also tries to fight for the focus. So if you want to do this (that's a big "if", I don't recommend it) you should at least limit it to the page loading phase and allow the focus to be changed after that.

EDIT 2: The solution I found actually doesn't work, at least not that well...

jscheuer1
09-29-2013, 11:14 AM
I see. You can get rid of that and put this in the head:


<script type="text/javascript">
setInterval(function(){window.focus();}, 300);
</script>



That should 'work' (might not in Safari mobile, maybe not in any Safari). And it will have the same problem as mentioned in Firefox, and will have it in IE as well.

Also I see that in Chrome, the street map is replaced by a street level view interactive image. This could possibly happen in other browsers as well, but probably is a more or less exclusive 'feature' of Chrome.

You really don't want that happening though in any browser because it's really the same image as seen in step 2, just a bit darker and without the superimposed bright green arrow. And there's no obvious way to get to the street map view.

So, considering those two drawbacks, I'd say a static image would be best.

Or, if you're targeting mobiles, iPhone/Pad in particular, we could do a test for touch capability and/or OS and/or device and/or browser to decide whether to set the interval or not (example testing for the device only, executing just for iPhone/Pad):


if(/ipad|iphone/i.test(navigator.userAgent)){
setInterval(function(){window.focus();}, 300);
}

This is still much less desirable than a static image.

On another front. I think I just about have the logic worked out to target the middle visible content for highlighting, or at least the first next fully visible, when scrolling without the arrow keys.

After I test that a bit more, I'll let you know if it's viable.

EDIT: It does work in Safari Win, and Safari Win does the same thing Chrome does, replacing the street map with an interactive street view image.

GSimon
09-29-2013, 06:26 PM
The script works! Tested it in Chrome/Firefox/IE. Glad there's an easy to implement solution.

You mention a few good points about the Google Street view feature. I still kind of like the street view/iFrame map, it's not actually a quirk that's exclusive to Chrome or anything, more a conscious decision to use street view that rather than the map only.
(using this: http://www.google.ca/earth/outreach/images/tutorials_embedmaps1.jpg (not my image))

Perhaps changing the map to look like this would be preferable:

http://oi40.tinypic.com/n6yuxl.jpg

I think the benefit of it is for the user to be able to use the street view if they would like to detect landmarks/etc near the building entrance.

Thanks for all the help, if you can figure out how to detect when the user is looking at the centered image that would be cool/helpful, however I may be adapting all the pages to display differently on a mobile/retina device in the near feature, which could fix the issue anyhow by limiting the screen's viewport to only 2 images at a time, rather than current view of 3 (at least on the iPhone 5).

jscheuer1
09-30-2013, 12:46 AM
I'm still playing around with the code to reliably detect in all circumstances which is the optimal item to highlight.

In the meantime I wanted to comment on what's being done visa vis the Google map. Using the interval will disable the user's ability to edit the address bar in IE and Firefox. Similarly in those browsers, if the user has a search bar, they will likely be unable to use that.

One other more important effect perhaps is that the browser itself will demand attention whenever it's not in the foreground. This will occur in many browser/OS combinations. It's not limited to Firefox and IE. But, at least in Windows, all this amounts to is that the browser's icon in the system tray perhaps flashes/glows and/or when minimizing the browser, having it redisplay itself on its own.

Fortunately all of these side effects last only as long as the map page is loaded in the browser.

One other important effect I know of is that the keyboard is disabled for the Google map. The reason it grabbed the keys in the first place is that it uses them for panning and other commands. These actions can be accomplished with the mouse however, and probably with gestures in touch devices. But for those used to using the keyboard on Google maps, they will be at least a little lost not being able to.

This effect is not limited in any way and applies to all browser/OS combinations.


I would also add that, as far as how the map should look, I favor the second image in your previous post because, although I see the wisdom in being able to pan around for landmarks, I also think that for finding the initial starting point, an actual map will be more helpful for many folks.

Providing both, as the second image in your post suggests is possible, would be in my opinion, ideal.

Oh, and I just looked at the source code and saw:


<script type="text/javascript">
setInterval(function(){window.focus();}, 300);
if(/ipad|iphone/i.test(navigator.userAgent)){
setInterval(function(){window.focus();}, 300);
}
</script>

That's not exactly what I meant. If you want to target only iPad/Phone, do:


<script type="text/javascript">
if(/ipad|iphone/i.test(navigator.userAgent)){
setInterval(function(){window.focus();}, 300);
}
</script>

If you want to target all, do:


<script type="text/javascript">
setInterval(function(){window.focus();}, 300);
</script>

There's no reason to do both. If you want to target a different subset (perhaps including all touch devices, not just Apple ones) of browsers/OS's, a different test of the navigator.userAgent string and/or of other properties can be worked out for that.

GSimon
09-30-2013, 04:31 AM
I'm still playing around with the code to reliably detect in all circumstances which is the optimal item to highlight.

Awesome! well I'll stay tuned for any updates if they come about.

It looks like however I'll need to switch to static images, the issue mentioned with the address bar is unfortunate, and how IE (and other browsers) can't minimize the window without re-opening it.

Would be interesting to see if any of the scripts on this page could solve the issue somewhat, by setting a count timer so that it doesn't continuously focus on the page endlessly.
http://stackoverflow.com/questions/1831152/how-to-stop-setinterval

Even still the above wouldn't quite solve the problem entirely, though it could be enough of an improvement for it to be acceptable enough solution to implement, depending on the outcome.

jscheuer1
09-30-2013, 07:38 AM
OK, got it I think. I've replaced the current scroll highlighting demo:

home.comcast.net/~jscheuer1/side/demos/tidbits/hashimage/hashimageexthlght.htm

The browser cache may need to be cleared and/or the page refreshed to see changes.

And since it employs a more efficient method for staying current with the scrolling action, I made a new2 version of the one that doesn't highlight on page scroll:

home.comcast.net/~jscheuer1/side/demos/tidbits/hashimage/hashimagenew2.htm


As to that setInterval information on Stack Overflow you linked to - It won't help because it relies upon detecting focus on the textarea (which in this case would be the iframe).

If we could detect focus on the iframe, we wouldn't need any interval. We could just change focus back to the window whenever focus was registered on the iframe. That would take care of all of the drawbacks except that the keyboard would still be unavailable for controlling the Google map.

But browsers will not allow cross domain scripting like that. Although in this case it's a harmless thing, the browser cannot tell. And if it were allowed, all other sorts of things between domains would have to be allowed as well, leading to a potentially huge security issue.

As I said before, when first commenting on this - a static image would be best. You can still have the link there for the map on Google if they want to click it. It could open in a new tab or perhaps even in an iframe within a popup div, as long as that iframe were created and destroyed each time the popup div was summoned and dismissed. Or a new window could be used and might be the best solution here.

EDIT:

Because I looked at the source code you currently have on the page, I wanted to comment:

We could set a timeout to clear the interval after a reasonable amount of time after the page has loaded. That would take care of all of the problems - sort of. But itself would have issues:


The amount of time to wait before clearing it would have to be a "best guess" as to how long after the page loads that it takes for the iframe to complete loading the street level view. That's because we cannot ask the iframe for that information - again a security violation.


Assuming we guess right (a fairly big "if" because the load time of that feature will vary by browser/OS/device and its connection speed as well as the network conditions), then once we cancel the interval, if the user clicks or gestures inside the iframe, it will regain control of the keyboard.


Another option would be to use the Google Maps Javascript API to place the map on the page using javascript instead of an iframe. This could cause more problems than it solves, but if not, the keyboard can easily be disabled. There might even be a URI parameter to disable the keyboard in the map in the iframe. That would be great if it exists and would probably solve the problem. But I cannot find any reference to such a parameter.

jscheuer1
09-30-2013, 01:18 PM
The map javascript API seems to work out well. You would want more options/methods (especially a way to include the ROADMAP view or a way to switch to it), but a proof of concept is here:

home.comcast.net/~jscheuer1/side/demos/tidbits/hashimage/hashimagegoomapapi.htm

Turns out no disabling of the keyboard is required because, when it's shown on a page, it doesn't take control of the keyboard from jQuery in the first place. It does grab the up and down arrows, pgup and pgdown keys though from the page but only when the map is focused. jQuery could grab those back too. But I'm not sure it has too. As soon as they gesture or click outside the map, those should return to the page.

EDIT:

I've got a newer version:

home.comcast.net/~jscheuer1/side/demos/tidbits/hashimage/hashimagegoomapapi2.htm

That gives a toggle between the views and captures the up and down arrows for their 'normal'* use by the page. The pgUp and pgDown keys are still available to the map in some browsers.


*To get them back I had to create jQuery keydown events that mimicked the default ones.

GSimon
10-01-2013, 12:05 AM
Amazing! I was a bit nervous about using the API method, thought it would be a too frustrating trying to debug what is and what's not working. Thanks a bunch.

The highlight feature works great also, just tested it on the iPhone again and both issues mentioned earlier are fixed :)

I like the toggle street view button also, nice touch. The Google map's API is nice, allows for a lot of customization.

I was wondering how you were able to determine the values here:


pov: {
heading: 135,
pitch: 0
},

Was it by trial and error? Would be nice if I could easily determine those numbers somehow. I tried 'inspect element' on the page I can't seem to find those values anywhere. Wouldn't be the biggest issue if I had to do it manually however. Also sent a tip.

jscheuer1
10-01-2013, 02:12 AM
The API is a bit strange. Not everything works as advertised and the examples are completely separate from the docs and don't cover everything. But I was able to find enough stuff that works to get an acceptable feature. The thing I was most concerned about was it possibly interfering with the page layout. I've seen that happen sometimes with other folks. But usually the page was already fairly tortured when they introduced the map. At least these pages are laid out in a pretty straightforward manner.

About the pov (point of view) values heading and pitch. You can almost always use 0 pitch. That's up and down and for the most part you want it straight on, which is what 0 is. The heading is a compass rotational value, 0 to 360. I don't think there's anywhere you can get it exactly. But if you look at the street view, you will see the little circle on the bigger circle in the upper left hand corner. That looks to me to be minus 135 degrees from the top of the big circle. So you can probably guesstimate it from that thing. Get it lined up the way you want it, then read that as closely as you can. I did use trial and error to get it though. It's only in hindsight that I noticed what looks like a correlation with that control. Which makes sense, it's the rotational control*. BTW, that little circle on the larger circle has an N on it, so that must be where North is, which should also give you another clue. Not so much as to the value, but - if you know where you want to be looking from, where to set that thing before guesstimating it's angular rotation.


*Yup, if I set it to 180, it's exactly at the bottom.

EDIT: You can actually read the value in Chrome off of the API generated one. Right click on the larger circle, inspect element, expand it, and you will see:


<svg version="1.1" overflow="hidden" width="78px" height="78px" viewBox="0 0 78 78" style="position: absolute; left: 0px; top: 0px;"><circle cx="39" cy="39" r="35" stroke-width="3" fill-opacity="0.2" fill="#f2f4f6" stroke="#f2f4f6"></circle>
<g transform="rotate(-135 39 39)"><rect x="33" y="0" rx="4" ry="4" width="12" height="11" stroke="#a6a6a6" stroke-width="1" fill="#f2f4f6"></rect><polyline points="36.5,8.5 36.5,2.5 41.5,8.5 41.5,2.5" stroke-linejoin="bevel" stroke-width="1.5" fill="#f2f4f6" stroke="#000"></polyline></g></svg>

So get that in the inspector, rotate it to where you want it, and read the value off of the inspector.

Or - from the iframe's src attribute:


&amp;cbp=12,133.49,,0,2.16

Apparently it's the cbp parameter's second value. Make that a negative number, and use that as the heading. I know because I changed it to 180 and again, the little circle was at the bottom.

GSimon
10-01-2013, 05:34 AM
Ah nice, thanks for spotting that. Turns out the first value is the pitch also


&amp;cbp=12,133.49,,0,2.16

Well lots to do now with these updates :) Going to go through about 1000 pages in the next few days and update the code. Going to clean some of it up, some junk code is still leftover, need to update the meta tags also.

Appreciate the help!

jscheuer1
10-01-2013, 08:56 AM
No, that's not the pitch because the pitch of the image in the iframe is clearly 0 or close to 0. Well, in Chrome at least. Other browsers vary. But if I pitch the API one at 12, it looks different than the iframe one, tilted toward the viewer. I think this is consistent across browsers as long as you compare the iframe to the API in the same browser. And the full heading in the iframe URL is 133.49. When you use that and 0 pitch, you get almost exactly the same image in the API. By experimenting, I see now that the pitch is the 2.16 and the 0 is the zoom. However, a zoom of 0 in the iframe = a zoom of 1 in the API, 1 = 2 and so on. The API's 0 is farther back. The iframe seems incapable of going that far back, -1 has no effect in the iframe. I played with the other values, the 12 and the ,, and I didn't notice any differences, but I may have missed something. They might be for the ROADMAP view.

BTW, if you're going to use this in production, you should get (Google would like you to anyway) an API key:

https://developers.google.com/maps/documentation/javascript/tutorial?hl=en#api_key

It goes in the external script tag for the map API, see:

https://developers.google.com/maps/documentation/javascript/tutorial?hl=en#Loading_the_Maps_API

They're free, but are used to monitor the usage. I'm not sure what happens if you don't use a key. Does that mean unlimited usage, or more limited? In any case Google really seems to want you to use one. And the limits for free use are very high. It's not unless:


If your site or application generates 25 000 map loads or more each day, for more than 90 consecutive days

happens that there's a problem. And then they will simply contact you to discuss the situation, not cut you off or anything. That's from:

https://developers.google.com/maps/documentation/javascript/usage#usage_limits

So I would think that even with every student using this every day, it would still not come close to that. If you have to go over that, then you can purchase additional usage at 50 cents per 1000 loads (that's per 1000 that are over the limit, the first 25000 per day are still free). Or you can get a business license.

Oh, and this is no different than the iframe. Google wants you to use a key with it too.

GSimon
10-11-2013, 05:31 PM
Updated one of the sites!

classfind.com/western

GSimon
10-15-2013, 11:07 PM
Hi John, if you're available I'm looking for a solution to an issue I'm having with the Google Maps API.

I am working on the CSS (media query) for mobile devices, and for some reason the Google Street view map is not rendering correctly on the iPhone (Safari & Chrome). It renders fine on the desktop browsers however.

Here's what the street view map looks like on the iPhone:

http://i39.tinypic.com/2hgwk6o.png

URL to page: classfind.com/western/room/EC2130new

Ideally, I would like to keep the street map and find some way to have it render correctly.

If there isn't a solution to the rendering problem, then I would prefer the map to be loaded (the non-street view one) first instead of the street view panorama. I tried modifying the code you provided to load the other map first but I wasn't successful, at most I was able to remove the panorama street view map altogether.

Thanks

Edit: figured out how to accomplish this


If there isn't a solution to the rendering problem, then I would prefer the map to be loaded (the non-street view one) first instead of the street view panorama. I tried modifying the code you provided to load the other map first but I wasn't successful, at most I was able to remove the panorama street view map altogether.

jscheuer1
10-16-2013, 01:47 AM
Well you know you can load the ROAD MAP for iPhone/Pad and the street view for others.

GSimon
10-16-2013, 02:00 AM
Well you know you can load the ROAD MAP for iPhone/Pad and the street view for others.

That's sort of what I was aiming for if I couldn't figure out how to get the map to render correctly.

The issue is detecting when a user is on their mobile device vs. desktop. There are some media queries specific to iPhone/iPad, but the best approach seems to be to create media queries based on page width, to avoid any need for browser sniffing altogether and having to detect each individual device on the market.

Anyhow I should be able to manage with changing the default map to the road map, thought that would have to be the default for all viewers, desktop and mobile.