Skip to content

Instantly share code, notes, and snippets.

@Integralist
Created June 26, 2012 10:19
Show Gist options
  • Save Integralist/2994844 to your computer and use it in GitHub Desktop.
Save Integralist/2994844 to your computer and use it in GitHub Desktop.
How to target close button

#How to target CSS generated content via JavaScript? ##The content was generated using :after pseudo-element

Here is the design...

'Popup Design'

Below is the JavaScript I'm using to access the 'X' close button which was generated by the CSS.

Note: I don't want an extra HTML element in the page, I'd rather CSS handle the generation.

Also, I will be replacing the hard coded values with values pulled from getComputedStyle, but this is my initial attempt...

/*
 * pageX/Y is position relative to Window
 * clientX/Y is for Internet Explorer which doesn't recognise pageX/Y
 *
 * BUT although clientX/Y is similar it has one small caveat!
 * The value changes depending on whether the user has scrolled the window
 * Which means we need to add on top of clientY any scroll amount (if any)
 */
var x = e.pageX || e.originalEvent.clientX;
var y = e.pageY || (document.documentElement.scrollTop + e.originalEvent.clientY);
var popup_width = popup.clientWidth;
var popup_height = popup.clientHeight;
var popup_offset = getOffset(popup);
var popup_x = popup_offset.left;
var popup_y = popup_offset.top;
var popup_xrange = (popup_x + popup_width) + 17;
var popup_yrange = popup_y - 10;
var popup_xclose = (popup_x + popup_width) - 13;
var popup_yclose = popup_y + 20;
var within_xrange = x <= popup_xrange && x >= popup_xclose;
var within_yrange = y <= popup_yclose && y >= popup_yrange;

if (within_xrange && within_yrange) {
    // DO SOMETHING NOW WE'VE FOUND THE CLOSE BUTTON
}

...note that the getOffset function used above looks like this...

/**
 * Following method determines the left/top position of the target element.
 *
 * @param elem { Node } the target element
 * @param end { String } id value for the top most element we want to check against
 * @return { Object } object containing x and y position for specified element
 */
var getOffset = function(elem, end) {
	var _x = 0,
		 _y = 0;
	
	while (elem && !isNaN(elem.offsetLeft) && !isNaN(elem.offsetTop)) {
		// Store the x and y co-ordinates of the current element
		_x += elem.offsetLeft - elem.scrollLeft;
		_y += elem.offsetTop - elem.scrollTop;
		
		// Then move onto the next element up (and we keep going all the way to the top of the document unless stopped)
		// We use offsetParent instead of parentNode because the offsetLeft/Top adds on extra un-needed dimensions!
		elem = elem.offsetParent;
		
		/*
			In the following conditional statement…
			
			- We need to avoid a situation where the <body> tag isn't considered an offsetParent and so the browser continues up until null is returned
			- We can specify an element's id as the top level element to top checking for
			- We can pass through '_now_' as the end value which means the check stops immediately
			- Failing the id or _now_ we can try and stop at the document.body element (which will only work if the body is considered an offsetParent)
		 */
		if (elem == null || elem.id === end || end === '_now_' || elem.tagName.toLowerCase() === 'body') {
			break;
		}
	}
	
	return { top: _y, left: _x };
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment