Bryan Scott

RSS

Passing Mouse Events to Covered Elements

Situation:
I have an element that flies in from the side of an article promoting the next post. It is fixed to the lower right corner of the screen and potentially covers right sidebar content. This wouldn’t be a problem except that it has a large PNG dropshadow on it that can cover up links and stop the user from interacting with them.

What I want to do is tell the browser to ignore the dropshadow area and pass mouse events onto the element behind it at any given time. Unfortunately, this isn’t as easy as I thought it would be.

Simple Solution:
The CSS property pointer-events:none works perfectly in Firefox and Webkit browsers but not in Opera or Internet Explorer (see: When can I use pointer-events?), the browser used most by the target audience.

Javascript Solution:
So I wrote a simple script to pass clicks through to the elements covered by the background.

I wanted to pass all mouse events so I could get hover effects etc (without adding classes to the elements underneath), but I found that :hover states can’t be controlled via Javascript. That seems to be conventional wisdom on the Internet, anyway.

I cut it down so it only passes click events through. Altogether, this resolves the issue of users not being able to click on links, but it’s a little awkward because rollovers, cursor changes, and other effects don’t happen. For the time being, I’m going to cut my losses. I’m putting this whole thing in an IE conditional statement and using pointer-events for other browsers. Opera doesn’t occur enough that it’s worth stressing over. If it becomes an issue, I’ll do the browser detection in Javascript instead.

It also gave me difficulty on assigning focus to form fields, but I found that I could do a check on the type of element I had clicked on and trigger its focus event instead.

—————————

CODE ON PAGE
<script type="text/javascript" src="{{ static_url }}js/jquery.forward-clicks.js">
<script type="text/javascript">
$(document).ready(function() {
$(".flyin-container").forwardEvents(".flyin .label, .flyin .headline, .flyin .meta");
});
</script>

CODE IN jquery.forward-clicks.js
(function($) {
$.fn.forwardEvents = function(excludedSelector) {
var $mainElement = this;
var onElement = null;
var pauseForwarding = false;
this.click(function(event) {
// Ignore if click is in the excluded elements
var $targetElement = $(event.target);
if (($targetElement.is(excludedSelector) > 0) || ($targetElement.parents().is(excludedSelector) > 0))
return true;
// Temporarily hide main element to reveal elements behind it
$mainElement.hide();
// Get element behind
var element = $.elementFromPoint(event.clientX, event.clientY);
// Trigger focus if covered element is a form field
if (element.is("input") || element.is("select")) {
element.focus();
}
// Trigger event on covered element
element[0].click();
// Restore main element
$mainElement.show();
return false;
});
};
})(jQuery);
// http://www.zehnet.de/2010/11/19/document-elementfrompoint-a-jquery-solution/
(function ($) {
var check=false, isRelative=true;
$.elementFromPoint = function(x,y) {
if(!document.elementFromPoint) return null;
if(!check) {
var sl;
if((sl = $(document).scrollTop()) >0) {
isRelative = (document.elementFromPoint(0, sl + $(window).height() -1) == null);
} else if((sl = $(document).scrollLeft()) > 0) {
isRelative = (document.elementFromPoint(sl + $(window).width() -1, 0) == null);
}
check = (sl>0);
}
if(!isRelative) {
x += $(document).scrollLeft();
y += $(document).scrollTop();
}
return $(document.elementFromPoint(x,y));
};
})(jQuery);

When others play Scrabble, David (@smrvl) does this.

When others play Scrabble, David (@smrvl) does this.

Jun 4

My LimeJS Solar System

Here’s the result of my time with LimeJS. As previously posted, I decided to switch to native Android for this game, but I think the resulting Javascript was still fun. I plan on coming back to this and expanding on it when I get the chance.

Note: Feel free to drag the solar system around with your mouse to scroll, but be careful to do the Mouse Up within the box, otherwise it will continue to scroll until you click back in the box. Also, in general, I make no promises on browser compatibility (IE 8 comes to mind) because I did not get around to straightening out those kinds of issues.

Space Game Reboot

I recently started a game intended for mobile devices using LimeJS.  The goal was to create a very basic space strategy game that would be platform independent, so we could release for iOS shortly after an Android release.

I ran into a couple of issues that made this solution less desirable:

First, I didn’t like that there isn’t any line drawing in LimeJS.  One has to create a 1px tall Rectangle and then angle it a certain way.  That was fine for straight lines, but it would be nice to be able to draw curved lines and such as well.

Second, I would often open my partially completed project with the browser on a random Android device and see that even the compiled (I use this word loosely.  LimeJS has a process that optimizes the includes etc.) version of my Javascript app was moving very slowly.  This is in part due to the phones having too much in memory etc, but it still doesn’t bode well that the most basic elements of my application were lagging badly.

Third, when I went to start using touch events, I noticed that there doesn’t appear to be any special handling for things like “pinch” and “double tap.”  Since users will expect certain things out of using these gestures, I really wanted to include them into my app, and I would much rather implementation was seemless.

That last part annoyed me enough that I decided to reboot the whole project in native Android code.  I hate to leave out iOS, especially given the number of my friends with iPhones, but I want this game to be good.  I feel like the best way to do that is to write it as a native app.  If it is successful on Android, I will happily try to port it over to iOS.

Note on progress: after I got home from the Memorial Day festivities of the day and put my son to bed, I built a “Hello…circle” app to get myself started on this project.  I have a good enough idea of the framework of the app going forward, that I should be able to quickly catch up to where I was before the switch.