Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine HTML element position change

EDIT: See update!

I have the following html:

<body>
  <span id="milestone1">
  </span>   
  <img id="image1" src="blabla.jpeg" style="width:400px;height:200px;" />
  <div id="divOverlayOverImage1" style="position:absolute; top:100px; left:40px; width:400px;height:200px;" onclick="DoFunkyStuff();"><div>
</body>

At first the divOverlayOverImage1 is positioned over Image1, covering it, but if I run the code below, the #divOverlayOverImage1 element will no longer covering the #image1 element.

$("#milestone1").after('<div style="width:500px; height:500px; background-color:blue;">');

I want to have an event that notifies me when #image1 changes its position, so I can update the position of #divOverlayOverImage1.

NOTE: I do not have full control over the dom. the $("#milestone1").after('<div style="width:500px; height:500px; background-color:blue;">'); command is run by a third party.

UPDATE: I do not have full control of the DOM, so I cannt put a callback to the element add function, as it is not me making this call. Also, I cannot modify HTML like crazy. I just come to a set of websites, append and overlay to a specific image throung JavaScript and that's it. There are other competitiors that change the HTML as well.

like image 280
Dragos Durlut Avatar asked Aug 05 '13 09:08

Dragos Durlut


3 Answers

If you have full control over the DOM, and I assume you have, you can add a call to every change you make in the DOM that will affect that <span>.

function yourFunction() {
    $("#milestone1").after('<div style="width:500px; height:500px; background-color:blue;">');
    updateMyOverlayPosition();
}

if that doesnt work, you might try this one here: Detect changes in the DOM

edit

if you want events:

$('#image').on('adjustOverlay',function(e) {
    // adjust the position of the overlay
}

$("#milestone1").after('<div style="width:500px; height:500px; background-color:blue;">');
$('#image').trigger('adjustOverlay', {extra: "info", some: "parameters"});

edit2

Since you don't have full control over changes in the DOM and you can get surprised you can either go with the link I already provided above or check in an interval if the overlay is still where it needs to be. This doesn't solve the problem in the way you want it, but there is no native event on DOM-changes, so you have to stick with some sort of work-around.

var checkTime = 100; //100 ms interval
var check = setInterval(function() {
    // adjust overlay position
}, checkTime);

edit3

next possible solution: if you know how affecting code is inserted in the DOM, you can try to change that method so that it always runs your adjustOverlayPosition() or fires an event, if you like events. Example: if it is inserted with jQuery's .after() you can modify that function:

jQuery.fn.extend({
    // since the .after() function already exists, this will
    // actually overwrite the original function. Therefore you need
    // the exact code that was originally used to recreate it.
    after: function() {
        return this.domManip( arguments, function( elem ) {
        if ( this.parentNode ) {
            this.parentNode.insertBefore( elem, this.nextSibling );
        }
        // call the function directly
        adjustOverlayPosition();
        // or call an event
        $('#image').trigger('adjustOverlay', {extra: "info", some: "parameters"});
    }
});

Drawback: this solution can be risky and works only if you know the code that is used originally. So it would also depend on the jQuery version.

like image 70
Zim84 Avatar answered Oct 21 '22 13:10

Zim84


One workaround is to reorganize your layout. Wrap your image and overlay into a div. That way they will always remain that way.

<div id="wrap">
    <img id="i1" src="..." />
    <div id="overlay" />
</div>

#wrap {
    position: relative;
    width: 400px;
    height: 200px;
}

#overlay {
    position: absolute;
    top: 100px; 
    left: 40px; 
    width: 400px;
    height: 200px;
}
like image 22
Abhitalks Avatar answered Oct 21 '22 13:10

Abhitalks


If wrapping the img with a ovelay is only your requirement, I think you can go with a pure css Solution:

Try the demo

HTML

<p id="milestone1">
First Overlay
</p>   
<div class="img-overlay-container" style="width:400px;height:200px;">
 <img id="image1" src="blabla.jpeg"/>
 <div id="overlay1" onclick="alert('clicked');">
 </div>
</div>  
<p id="milestone2">
Second Overlay
</p>       
<div class="img-overlay-container" style="width:100px;height:400px;">
 <img id="image2" src="blabla.jpeg"/>
 <div id="overlay2" onclick="alert('clicked');">
 </div>
</div>  

CSS

.img-overlay-container{
  position: relative;
  display:inline-block;
}
.img-overlay-container > img{

}

.img-overlay-container > div{
  position:absolute; 
  top:0px; 
  left:0px; 
  width:100%;
  height:100%; 
  background: rgba(3,3,3,.1);
}
like image 40
Akhil Sekharan Avatar answered Oct 21 '22 14:10

Akhil Sekharan