I am trying to set the position of a contextMenu
and using Jquery jquery.ui.position
. For ContextMenu
I am using this libaray:-
https://swisnl.github.io/jQuery-contextMenu/demo
I am trying to position a ContextMenu
as follow:-
$(document).ready(function() {
$.contextMenu({
selector: 'td[id="tdMenu"]',
trigger: 'left',
position: function (opt, x, y) {
try {
opt.$menu.position({
my: 'right top',
at: 'right bottom',
of: $("#tdDiv")
});
} catch (e) {
}
},
items: {
"0": { name: "Hi" },
}
});
});
HTML is as follow:-
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td id="tdDiv" style="background-color: yellow;">
Menu Div
</td>
</tr>
<tr>
<td id="tdMenu">
Click Here
</td>
</tr>
</table>
In IE 11
once the page will load and once I click on td with id tdMenu
jquery.ui.position does not calculate the offset correctly. On second click it calcultes correctly.
What I have found is inside jquery.ui.position
its calculating a offset as follow:-
function getDimensions( elem ) {
var raw = elem[0];
return {
width: elem.outerWidth(),
height: elem.outerHeight(),
offset: elem.offset() // On first click its calculating wrong value and on second it calculates correctly.
};
}
I have also given margin to body as:-
<body style="margin: 0px;">
If I will remove this margin it calculates correctly on first click also.
I cannot remove body margin. What can be the work around for this ?
From what you've posted, it looks like a classic case of computing an offset
value before the page finished loading all styles and content, resulting in a wrong offset value at the time your contextMenu
is initialized.
Replacing
$(document).ready(function() {
// executes when DOM parser reaches </html> tag
$.contextMenu({/* your stuff here */})
});
with
$(window).on('load', function() {
// executes when all external resources/references (images, scripts,
// stylesheets, iframes, etc...) have finished loading
$.contextMenu({/* your stuff here */ })
});
is likely to solve your problem, but without a Minimal, Complete, and Verifiable example it's impossible to test and make sure it works for your case.
Note: The above solution will delay the initialization of $.contextMenu()
until the page has loaded. If your page takes a long time to load all its resources and you want to have $.contextMenu
initialized before that moment, a workaround is to init it on $(document).ready
and update it on $(window).load
:
function cMenu() {
$.contextMenu({
/* your stuff here */
});
}
$(document).ready(cMenu);
$(window).on('load', cMenu);
In reality, chances are there is only one item in the page which influences that offset (most likely a stylesheet). If you which one it is (by elimination, disabling stuff in your page), you don't even have to wait for the rest to load, you can simply bind the re-run of your function on that elements' onload
event.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With