Resolving a JavaScript conflict - javascript

On a website, http://imgthis.com/blog/?p=34, I have two JavaScripts that load inside an iframe with an image gallery, one is lytebox which is a Light Box 2 slimmed down clone for image gallery pop ups and the other is a show only one div in a stack of divs. The lytebox script works until the show only one is invoked, from that point on it's broken in IE FF and Opera (Chrome and Safari do not throw an error) with this error:
Uncaught exception: TypeError: Cannot convert 'window.parent.frames[window.name]' to object Error thrown at line 223, column 1 in (imageLink, doSlide, doFrame) in [url to script]:
var anchors = (this.isFrame) ? window.parent.frames[window.name].document.getElementsByTagName('a') : document.getElementsByTagName('a');
called from line 204, column 56 in () in [url to script]:
myLytebox.start(this, false, false);
After it breaks you have to reload the page to get anything working again.
I'm assuming that it's a conflict, since it's only occurring after the other script has been invoked. Before the show only one is invoked it works perfectly.
This is the show only one code which is embedded into the page:
function showonlyone(thechosenone) {
var newboxes = document.getElementsByTagName('div');
for(var x=0; x<newboxes.length; x++) {
name = newboxes[x].getAttribute('name');
if (name == 'newboxes') {
if (newboxes[x].id == thechosenone) {
newboxes[x].style.display = 'block';
}
else {
newboxes[x].style.display = 'none';
}
}
}
}
I'm pretty lost as to how they could be conflicting since they are looking for different elements, though my JavaScript isn't that strong so maybe it makes all the difference in the world.

find line 223 of lytebox.js and make the following changes:
var anchors = (this.isFrame) ? window.parent.frames[window.name].document.getElementsByTagName('a') : document.getElementsByTagName('a');
to this:
var anchors = (this.isFrame && window.parent.frames[window.name].document) ? window.parent.frames[window.name].document.getElementsByTagName('a') : document.getElementsByTagName('a');

My lytebox.js had 2 occurrences
Suggestion: Find (this.isFrame) ? and replace with (this.isFrame && window.parent.frames[window.name].document) ?

Related

How to get Javascript's "getElementsByClassName()" to work?

When I do this, everything works just fine:
function openTab(tabName)
{
document.getElementById("divUsers").className = "invisible";
document.getElementById("divGroups").className = "invisible";
document.getElementById("divZFSPools").className = "invisible";
document.getElementById("divShares").className = "invisible";
document.getElementById(tabName).className = "visible";
}
But when I do this, nothing happens:
function openTab(tabName)
{
var targetTab, activeTab;
// Get the div:
targetTab = document.getElementById(tabName);
// If it is the active tab, return:
if(targetTab.style.display.className == "visible");
return;
// No, it is not the active tab:
document.getElementsByClassName("visible")[0].className = "invisible";
// Make the target tab visible:
document.getElementById(tabName).className = "visible";
}
FYI: "visible" and "invisible" are two CSS class names.
Does anyone have idea why? How can I achieve the desktop tab control behaviour using HTML and Javascript?
If I don't misunderstood you question just remove the ; after your if condition because a simple typo (;) can make huge difference to your code.
Assume,
if (0 === 1); { alert("Hello World") }
// equivalent to:
if (0 === 1) /*do nothing*/ ;
alert ("Hello World");
This code will alert "Hello World", but not because 0 equals 1, but
because of the semicolon. It makes JavaScript think that you have an
empty statement there, and everything to the right of it is treated as
no longer belonging to the if conditional and thus independent of it.
Source : https://www.codecademy.com/en/forum_questions/507f6dd09266b70200000d7e
So on your code it will be like this,
//If it is the active tab, return:
if(targetTab.style.display.className == "visible");
return; //^^ remove this semicolon

Javascript from file gives Uncaught ReferenceError

I am trying to dynamically adjust the height of an iFrame on a web page depending on the content within the iFrame via some JavaScript.
My problem is when I have the script directly on the page in a <script> tag it works fine. When I stuff the code in to a separate js file and link to it- it doesn't work!
<iframe id='StatusModule' onload='FrameManager.registerFrame(this)' src='http://randomdomain.dk/StatusModule.aspx'></iframe>
<script type='text/javascript' src='http://randomdomain.dk/FrameManager.js'></script>
It gives me the error:
Uncaught ReferenceError: FrameManager is not defined
Can this really be true? Has it something to do with the page life cycle?
Ps. I guess the JavaScript code is irrelevant, as we not it works.
UPDATE: I think this might have something to do with secure http (https) and the different browsers in some weird way. I noticed that the script actually worked in Firefox. Or rather I'm not sure if its the script, or just Firefox's functionality that resizes iframes automatically depending on the content. It doesn't give me any error though.
If I then add https to the script url reference, the scripts work in IE and Chrome - but not in Firefox. Function reference error! This just got weird!
UPDATE #2: Its not a Firefox function that resizes the iframe. Its the actual script that works (without https).
UPDATE #3: The JavaScript. Works fine if I put it directly into a script tag.
var FrameManager = {
currentFrameId: '',
currentFrameHeight: 0,
lastFrameId: '',
lastFrameHeight: 0,
resizeTimerId: null,
init: function () {
if (FrameManager.resizeTimerId == null) {
FrameManager.resizeTimerId = window.setInterval(FrameManager.resizeFrames, 0);
}
},
resizeFrames: function () {
FrameManager.retrieveFrameIdAndHeight();
if ((FrameManager.currentFrameId != FrameManager.lastFrameId) || (FrameManager.currentFrameHeight != FrameManager.lastFrameHeight)) {
var iframe = document.getElementById(FrameManager.currentFrameId.toString());
if (iframe == null) return;
iframe.style.height = FrameManager.currentFrameHeight.toString() + "px";
FrameManager.lastFrameId = FrameManager.currentFrameId;
FrameManager.lastFrameHeight = FrameManager.currentFrameHeight;
window.location.hash = '';
}
},
retrieveFrameIdAndHeight: function () {
if (window.location.hash.length == 0) return;
var hashValue = window.location.hash.substring(1);
if ((hashValue == null) || (hashValue.length == 0)) return;
var pairs = hashValue.split('&');
if ((pairs != null) && (pairs.length > 0)) {
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split('=');
if ((pair != null) && (pair.length > 0)) {
if (pair[0] == 'frameId') {
if ((pair[1] != null) && (pair[1].length > 0)) {
FrameManager.currentFrameId = pair[1];
}
} else if (pair[0] == 'height') {
var height = parseInt(pair[1]);
if (!isNaN(height)) {
FrameManager.currentFrameHeight = height;
//FrameManager.currentFrameHeight += 5;
}
}
}
}
}
},
registerFrame: function (frame) {
var currentLocation = location.href;
var hashIndex = currentLocation.indexOf('#');
if (hashIndex > -1) {
currentLocation = currentLocation.substring(0, hashIndex);
}
frame.contentWindow.location = frame.src + '&frameId=' + frame.id + '#' + currentLocation;
}
};
window.setTimeout(FrameManager.init, 0);
UPDATE #4: Alright I did as ShadowWizard and TheZuck suggested:
<script type="text/javascript">
var iframe = document.createElement("iframe");
iframe.src = "http://www.randomdomain.dk/StatusWebModule.aspx";
iframe.width = '100%';
iframe.id = 'StatusModule';
iframe.scrolling = 'no';
if (iframe.attachEvent) {
iframe.attachEvent("onload", function () {
FrameManager.registerFrame(iframe);
});
} else {
iframe.onload = function () {
FrameManager.registerFrame(iframe);
};
}
document.getElementById('framecontainer').appendChild(iframe);
</script>
With HTTP as URL its work on IE and Firefox - not Chrome. If I set it to HTTPS it works on Chrome and IE - Not Firefox. Same error:
"ReferenceError: FrameManager is not defined".
What is going on here?
a couple of things:
I would bet on a race condition when you have two independent
resources which are supposed to be loaded concurrently. You can
easily check this by writing to log (or to document, whichever works
for you) when both finish loading (i.e. add a little script in the
iframe to dynamically add the time to the content or write to log if
you're using chrome, do that in the external script file as well,
and see if they post the time in a specific order when this fails). In your case, if the script appears before the iframe, and you don't mark it as async, it should be loaded before the iframe is fetched, so it would seem strange for the iframe not to find it due to a race condition. I would bet on (3) in that case.
Assuming there is such an issue (and if there isn't now, when you go
out into the real world it will be), a better way to do this is to
make sure both behave well in case the other loads first. In your
case, I would tell the iframe to add itself to a local variable
independent of the script, and would tell the script to check if the
iframe registered when it loads, and after that in recurring
intervals until it finds the iframe.
If the page the script is loaded into is not in the same domain
as the iframe (note that it doesn't matter where the script comes
from, it only matters what the page's domain is), (or even the same
protocol as someone mentioned here), you will not be able to access
the content so you won't be able to resize according to what the
content is. I'm not sure about the onload method, if it's considered part of the wrapping page or part of the internal iframe.
Check out this question, it sounds relevant to your case:
There's also an interesting article here about this.
I think that your frame is loaded before the script, so "FrameManager" does not exist yet when the iframe has finished loading.

Javascript error: Object Required in ie6 & ie7

I have a javascript function (epoch calendar) which displays a calendar when focus is set on certain text boxes. this works fine in ie8, ff (all versions as far as I can test), opera etc but doesn't work in ie7 or previous.
If i have it set up in a blank html test page it will work so I'm fairly sure it's a conflict with my css (provided to me by a designer).
I've traced the error to these lines of code -
Epoch.prototype.getTop = function (element) //PRIVATE: returns the absolute Top value of element, in pixels
{
var oNode = element;
var iTop = 0;
while(oNode.tagName != 'BODY') {
iTop += oNode.offsetTop;
oNode = oNode.offsetParent;
}
return iTop;
};
Epoch.prototype.getLeft = function (element) //PRIVATE: returns the absolute Left value of element, in pixels
{
var oNode = element;
var iLeft = 0;
while(oNode.tagName != 'BODY') {
iLeft += oNode.offsetLeft;
oNode = oNode.offsetParent;
}
return iLeft;
};
More specifically, if i remove the actual while loops then the calendar will display OK, just that its positioning on the page is wrong?
EDIT
Code below which sets 'element'
<script type="text/javascript">
window.onload = function() {
var bas_cal, dp_cal, ms_cal;
dp_cal = new Epoch('epoch_popup', 'popup', document.getElementById('<%=txtDateOfDiag.ClientID%>'));
dp_cal = new Epoch('epoch_popup', 'popup', document.getElementById('<%=txtDOB.ClientID%>'));
};
</script>
Note: I am using asp.net Master pages which is why there is a need for the .ClientID
EDIT
A further update - I have recreated this without applying css (but including the .js file provided by the designer) the code still works fine which, there must be some sort of conflict between the CSS and my JavaScript?
That would lead me to believe that the tagName does not match, possibly because you have it in upper case. You might try while(!oNode.tagName.match(/body/i)) {
what happens if you add a line of debug code like this:
var oNode = element;
var iLeft = 0;
alert(oNode);
This might give different results in different browsers; I think it may be NULL for IE.
You may want to have a look at the code that provides the value of the 'element' parameter to see if there's a browser-dependant issue there.

"Permission denied to access property 'href' from a non-chrome context" in JavaScript and OpenLayers

This is really two questions one leading into the other. Firstly what does 'Permission denied to access property 'href' from a non-chrome context' actually mean?
Secondly I am using overlays in OpenLayers and wish to change the opacity of said layers, this is where this error is being thrown the code of which is here...
<input id='opacity' value="1.0" onChange="changeOpacity()">
Of which changeOpacity() is the following function...
function changeOpacity() {
var newOpacity = parseFloat(OpenLayers.Util.getElement('opacity').value);
newOpacity = Math.min(1.0, Math.max(0.1, newOpacity));
OpenLayers.Util.getElement('opacity').value = newOpacity;
for (var i=0; i<images.length; i++) {
layers[images[i]].setOpacity(newOpacity);
}
}
which throws the error at "var href = originalElement.href;" here...
function mD(e) {
//what is originalElement/srcElement/originalTarget?
var originalElement = e.srcElement || e.originalTarget;
var href = originalElement.href;
if (originalElement.nodeName == "A" && href.match("http://www.openstreetmap.org/browse/")) {
href = href.replace('http://www.openstreetmap.org/browse/','http://www.openstreetmap.org/api/0.6/');
if (gml) { map.removeLayer(gml); } //$("status").innerHTML = 'loading'; }
gml = new OpenLayers.Layer.GML("OSM", href, {format: OpenLayers.Format.OSM});
map.addLayer(gml);
gml.preFeatureInsert = style_osm_feature;
var sf = new OpenLayers.Control.SelectFeature(gml, {'onSelect': on_feature_hover});
map.addControl(sf);
sf.activate();
return false;
}
}
Any help/ideas is great appreciated! I am using firefox 3.5.9 and firebug 1.5.4
I've noticed the "Permission denied.." errors often only appear when FireBug is activated. If you disable FireBug these errors never occur.
For layer opacity consider using the GeoExtJS framework on top of OpenLayers. It has a opacity slider widget:
http://www.geoext.org/lib/GeoExt/widgets/LayerOpacitySlider.html

Get control properties with javascript in firefox

I'm trying to access control's properties and although it works great in IE6, in FF3, it fails. I'm doing:
alert(document.getElementById(gridViewCtlId).style.display);
alert(document.getElementById(gridViewCtlId).style);
And the first one shows a blank popup while the second shows 'undefined'.
I do
alert(document.getElementById(gridViewCtlId).id);
and I get the proper ID of the box along with:
alert(document.getElementById(gridViewCtlId));
and I get that in an HTML table.
This works perfectly in IE but not FF. What do I need to do to get this functioning?
Edit: gridViewCtlId is defined as:
var gridViewCtlId = '<%=GridView.ClientID%>';
Here is the full code:
var itemVisible= '<%=ItemVisible.ClientID%>';
function onGridViewRowSelected(rowIdx)
{
alert(document.getElementById(gridViewCtlId).style.display);
alert(document.getElementById(gridViewCtlId).style);
if (document.getElementById(gridViewCtlId).disabled == false)
{
alert("hi1");
var selRowCCA = getSelectedRow(rowIdx);
if (curSelRow != null)
{
alert("hi2");
var previousRow = getSelectedRow(previousRowIndx);
var CountIdx = previousRowIndx % 2;
if (document.getElementById(itemVisible) == null)
{
if (CountIdx == 0)
{
alert("hi");
previousRow.style.backgroundColor = 'Silver';
}
else
{
previousRow.style.backgroundColor = 'White';
}
}
}
if (null != selRow)
{
alert("new");
previousRowIndx = rowIdx;
curSelRow = selRow;
selRow.style.backgroundColor = 'Red';
}
}
}
It's pretty much an onClick where I have to call that function to turn it back to its original color (using alternating color rows). IE, this works fine. If i do the first alert
alert(document.getElementById(gridViewCtlId).disabled);
I would get either true or false.
The reason it's like this is because someone is going to enter something in a text box and the first gridview is going to populate depending on whats in that textbox. Then when someone selected something in the first gridview, that gridview is going to become disabled and then populate a second. So i'm having an issue checking for the disabled part of the gridview.
<div id="test">
</div>
<script type="text/javascript">
var gridViewCtlIdCCA = 'test';
alert(document.getElementById(gridViewCtlIdCCA).style);
</script>
Alerts [object CSSStyleDefintion] in Firefox 2 and 3.
If .style where undefined, .style.display would produce an error, not alert an empty dialog (unless you are capturing window.onerror).
Can you create an SSCCE that demonstrates the problem. More information about SSCCE available here.

Categories