问题
I'm trying to create somewhat of a highlighting/selecting tool [using jQuery] in my web app that watches what elements you hover over inside an iFrame, selects the hovered-over element, and uses that element's styling to create on overlaying div
. Think of the element selection tool in your web inspector.
Here's a demo that selects all visible elements (except html
and body
). Hover over one: http://jsfiddle.net/PrAfG/3/
The problem I'm having is that if you move really quickly across the frame you can get at the inner elements and highlight them, but if you move slowly or at a regular speed across the frame the first outer div
that the cursor touches gets highlighted, and is henceforth stuck highlighting it because the overlaying div
blocks the cursor from touch other elements in the page.
I've considered setting pointer-events
to none
in the CSS of the overlaying div element, but I don't want that because I want the highlighted element to become inactive when it's highlighted (ie a link can't be clicked).
Anyone know how I can highlight all of the elements (individually of course) in the frame? Without getting stuck on the outermost elements?
回答1:
The problem with your approach is, you only have one highlight
element.
So just like the scenario you are having issues with, you don't have a way to fire a mouseout
event while staying inside the area.
My suggested approach would be to actually scan through all visible elements first.
For each visible element, make a dummy <div>
which has the exact same top, left,
outerWidth
, outerHeight
, offset and z-index
.
In other words, make a very shallow copy of the entire structure, the extreme opposite of a deep clone.
Also, if you think my suggestion fits as an answer, I have one more minor suggestion. Search for the smartresize plugin, and on resize of your iframe that has percentage/flexible widths, recalculate the div dimensions and positions. I'll leave that to you.
DEMO: http://jsfiddle.net/terryyounghk/Mh6Hf/
var $viewFrame = $('div.viewport-container iframe.output-frame').contents(),
$visibles = $viewFrame.find('*:not(html body)').filter(':visible'),
$viewContainer = $('div.viewport-container'),
$overlayElements = $visibles.map(function (i, el) {
var $el = $(el),
$overlayEl = $('<div>');
$overlayEl.addClass('overlay') // this is our identifier
// we need { width:.., height:.., left:.., top:.., z-index:...}
.css($.extend({
position: 'absolute',
width: $el.outerWidth(),
height: $el.outerHeight(),
'z-index': $el.css('z-index')
}, $el.offset()));
$el.data('overlay', $overlayEl); // now the actual object has reference to the overlay
$overlayEl.data('element', $el); // vice versa, now the overlay has reference to the actual object
// you can do more stuff here...
return $overlayEl.get();
});
$overlayElements.appendTo($viewContainer)
.hover(
function () { $(this).addClass('highlight'); },
function () { $(this).removeClass('highlight'); }
);
And I made one change in the CSS
...
/*div.element-highlight removed*/ div.highlight {
/*display: hidden;*/ /* <---- removed */
position: absolute;
background-color: yellow;
opacity: 0.5;
cursor: default;
pointer-events: auto;
}
And one change to the HTML (inner DIV removed)
<div class=element-highlight></div>
来源:https://stackoverflow.com/questions/16228317/using-jquery-to-highlight-elements-cant-get-to-inner-elements