jQuery and Prototype - collision causes broken functionality - prototypejs

I'm restructuring a page for a client, and I'm having some issues with the jQuery code I implemented on the page.
There's a pop-up lightbox that uses Prototype which appears when the page loads, and then there's marquee/scrollers on the top and right that I put there that use jQuery. I'm really unsure about what's causing the error.
I'm familiar with jQuery's noConflict, but I've tried pretty much every variation of it on this page and I still get an error - after a few seconds the marquees stop - and IE displays that "Errors on page" dialog, referencing line 464 ("Array length must be assigned a finite positive number").
Here is the page: -link removed by author-
Here is prototype.js: -link removed by author-
I have absolutely no idea what is causing this error and JavaScript isn't my strongest side.

When I first started seeing this error, I was Googling around for more general "Prototype + jQuery" errors, when I should have been looking for a solution specific to the exact problem I was dealing with.
Adding the terms "array length" and "line 464" actually led me to the solution to this specific problem, and here it is:
Updated from prototype v1.4 to v1.5.1.2 (v1.7, the latest release,
didn't work right and even produced a stack overflow error).
Changed around the order of the scripts, and changed noConflict:
<script src="/scripts/jquery-1.5.2.js" type="text/javascript"></script>
<script src="/scripts/jquery.Scroller-1.0.src_4.js" type="text/javascript"></script><!-- all _$_'s replaced with _jQuery_ -->
<script type="text/javascript">
<!--
// more jquery, all $'s replaced with jQuery
-->
</script>
<script type="text/javascript">
<!--
jQuery.noConflict();
-->
</script>
<script src="scripts/prototype-1.5.1.2.js" type="text/javascript"></script>
<script type="text/javascript">
<!--
// everything else, including prototype scripts
-->
</script>
And that's it! Now I don't get the "Line 464" error and all scripts work fine.
Thank you #Ken and #Diodeus for leading me to the solution.

You may need to go through the plugins and replace $( with jQuery(, since you need to use "jQuery..." instead of "$..." in no-conflict mode.

Surround the code that uses jQuery with
(function ($) {
... // Your code
})(jQuery)
This way it uses local $ which is bound to jQuery and and jQuery only.
Also it is considered a bad idea to use both frameworks on the same website. You can find jQuery replacements for pretty much all of Prototype plugins.

I would find plugins in the same library. jQuery has all the plugins you mentioned, so there's no need to try using both. These two libraries can be difficult to get working together.
If you're set on using both libraries, try this ordering:
1) other lib
2) jquery
3) noconflict call
4) all plugins
<script src="scripts/prototype.js" type="text/javascript"></script>
<script src="/scripts/jquery-1.5.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
<!--
$.noConflict();
-->
</script>
<script src="/scripts/jquery.Scroller-1.0.src_3.js" type="text/javascript"></script>
<script src="scripts/lightbox.js" type="text/javascript"></script>

Related

cycle is not a function

I have the following page http://link.org/ (tested and is valid W3 HTML), where I am using the jquery cycle slideshow function (old version).
But even though the cycle function file is definitely being called, I am still getting an error: $(...).cycle is not a function
Would someone be able to look and see what the issue might be?
Thanks!
For some weird reason jQuery tools are invoking ready event before page is completely loaded, change order of scripts from:
<script type="text/javascript" src="includes/jquery.cycle.all.min.js"></script>
<script type="text/javascript" src="includes/jquery.tools.min.js"></script>
to
<script type="text/javascript" src="includes/jquery.tools.min.js"></script>
<script type="text/javascript" src="includes/jquery.cycle.all.min.js"></script>
and your error will be gone.

Jqgrid subGridRowExpanded error object doesnt support jqgrid

I have a master grid and sub grid. On click of row expand , I was able to fetch the result and display. It was working fine in IE and chrome. Now I am getting Error: Object doesn't support property or method 'jqGrid' in IE10 but it works fine in chrome.
I am loading grid.locale before jqgrid src . List of scripts:
<script src="Scripts/jquery-1.9.1.js" type="text/javascript"></script>
<script src="Scripts/jquery-1.6.1.min.js" type="text/javascript"></script>
<script src="Scripts/jquery.carouFredSel-6.2.1.js" type="text/javascript"></script>
<script src="Scripts/jquery.qtip-1.0.0-rc3.min.js" type="text/javascript"></script>
<script src="Scripts/grid.locale-en.js" type="text/javascript"></script>
<script src="Scripts/jquery.jqGrid.src.js" type="text/javascript"></script>
I am able to show the result in master grid. When I expand the sub grid , I am getting the error.The following is the code where I am getting the error.
subGrid: true,
subGridRowExpanded: function (subgrid_id, row_id) {
var orderid= jQuery('#tblJQGrid').jqGrid('getCell', row_id, 'OrderID');
Line: 291
Error: Object doesn't support property or method 'jqGrid'
You should include more full list of JavaScript files which you use and it's order. .
One of the possible reasons could be the usage of jQuery version which has bug in IE10. For example if you would use jQuery 2.0.2 you could have the described problem. Usage of jQuery 2.0.3 or 1.10.2 will solve the problem.

Google code prettify thinks css #id's are line comment. What am I doing wrong?

Example CSS
#wrap{margin:20px}
Code prettify wraps the whole line in .com
<span class="com">#wrap{margin:20px}</span>
Somebody has a similar issue here.
Where someone answers "Are you loading lang-css.js?".
Here's what I'm loading in the footer.
<script src="/js/google-code-prettify/lang-css.js"></script>
<script src="/js/google-code-prettify/prettify.js"></script>
I can see both of them with web inspector. I tried changing the order and loading them from the header. I'm using the latest version.
All help is greatly appreciated :)
Thanks!
The order you link to the javascript files matters. You need to call the base code (prettify.js) first followed by the css specific code (lang-css.js). You can place the script tags either in the head section or at the end of the document... both work but placing at the end of the document will speed up the page load.
<script src="/js/google-code-prettify/prettify.js"></script>
<script src="/js/google-code-prettify/lang-css.js"></script>
You will also need to ensure that you are linking the stylesheet in the head of your document.
<link rel="stylesheet" type="text/css" href="/css/prettify.css">
You also need to add the correct classes your pre tag(s). The syntax-highlighting functions contained in lang-css.js will not be called without adding the class "lang-css" to the <pre> tag.
<pre class="prettyprint lang-css linenums">
Finally, make sure you call the "prettyPrint()" function on page load.
<body onload="prettyPrint()">

Partially block embedded JavaScript in Firefox

Is there a Firefox extension capable of blocking a single function from embedded javascript in a page?
<html>
<head>
<script type='text/javascript'>
function onLoad(){
setTimeout(annoying, 1800000);
}
function annoying(){
//do something annoying
}
function useful(){
//do something useful
}
</script>
</HEAD>
<BODY onload="onLoad()">
<!--rest of page goes here-->
</BODY>
</HTML>
Perhaps Greasemonkey is the way to go.
The answer below is quite detailed technical, sorry if I went too far ;)
It depends a bit on how the function annoying() is used by the scripts. I am not yet an expert in JavaScript, some more experienced person's voice could be useful.
If annoying() is used by functions like window.setInterval(), window.setTimeout(), you probably can't overwrite the function directly, because of JavaScript quirks with scoping (closures). When the code window.setTimeout(annoying, 600) is executed, a reference to the "old" annoying is stored and that "old" version is executed. You might then try to get rid of the code that is invoking window.setTimeout on annoying instead.
In other cases, you can add a function with the same name and de facto overwrite the function with the following Greasemonkey userscript:
function addScript(sourceCode)
{
var script = document.createElement('script');
script.innerHTML = sourceCode;
var head = document.getElementsByTagName("head")[0];
head.insertBefore(script, head.firstChild); // insert the script as a first child of <HEAD>
}
addScript('function annoying(){alert("overwritten")}');
If you have code like below (I am unable to provide live demo, because it works differently on JSFiddle perhaps because its sandboxing), and the userscript above is launched for that domain, then after 600 milliseconds after page loads, you will have "Nasty alert" alert, but then any time you click the text, you will have "overwritten" alert.
<html>
<head>
<script type='text/javascript'>
function annoying(){
alert("Nasty alert");
}
function useful(){
//do something useful
}
window.setTimeout(annoying, 600); // closure; binds to the function as it is at the moment of execution
</script>
</head>
<body>
<a onclick="annoying()">Click me</a>
</body>
</html>
I know how to block it per page... I have a script here that is bugging me:
<script type="text/JavaScript">
<!--
function timedRefresh(timeoutPeriod) {
setTimeout("location.reload(true);",timeoutPeriod);
}
// -->
</script>
</head>
<body onload="JavaScript:timedRefresh(300000);">
What these idiots refuse to consider is that if I'm looking around for solutions, I could wind up with 10+ of these page open and 90% of my CPU time is then dedicated to refreshing their pages in the background! grr
I have firebug handy for web development and I just enter this JS command into the console
timedRefresh = function(value){alert(value);}
smile, click ok, and go on my way.
I've posted a solution here: https://stackoverflow.com/a/9699686/6355
Since it's little more than a link here it goes again: http://userscripts.org/scripts/show/125936
This does not help but instead exacerbates the problem.
The following are particularly pernicious and ugly if javascript is enabled:
<script>
setInterval("alert('irritate')",10)
</script>
or
<script>
(function(){(function r(){alert('irritate');setTimeout(r,10)})()})()
</script>
though this can be stopped (and all future TimeOuts) by:
javascript:setTimeout=function(){}
perhaps as the URI of a bookmark, provided it can be clicked fast enough.
However,
setInterval("alert('irritate')",10)
can only be stopped by
javascript:setInterval=function(){}
BEFORE the script is run.
Good luck with:
<script>
(function(){(function r(){alert('irritate');r()})()})()
</script>
or even simpler
<script>
( function r(){alert('irritate');r()} ) ()
</script>
Setting alert=function(){} will stop all messages but the script and its recursion of r will not stop until SO or system time out. Also, r is not in the global environment so r=function(){} is ineffective.
Some FF versions need an interesting solution, found on SO, if the alert response is mandatory, to kill the annoying page w/o killing the browser and other open tabs, by using ctrl-F4 to close the tab of the offending page. To aid the manual reflex and dexterity required to do this fast enough, ctrl-Enter is used to respond to the prompt and while ctrl-Enter is pressed F4 is typed.

Jquery and Protoype Conflict

<blink>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/prototype/1.6.1/prototype.js'></script>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.2/scriptaculous.js'></script>
<script type='text/javascript' src='/lightview.js'></script>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'></script>
<script type="text/javascript" src="/photography/js/scrollable.js"></script>
<script>
// Use jQuery via jQuery(...)
jQuery(document).ready(function(){
jQuery("div.scrollable").hide();
});
// Use Prototype with $(...), etc.
$('div.box').hide();
</script>
</blink>
My code isnt working im not sure why?
any advice?
You need to use jQuery.noConflict() to release $ back to prototype, like this:
jQuery.noConflict(); //restore $ to prototype
jQuery(document).ready(function(){
jQuery("div.scrollable").hide();
});
$('div.box').hide();
Though jQuery can do show/hide, so you may not need both libraries, depending on what you're doing (for example, there are lightbox plugins for jQuery and scrollable plugins for prototype, so you could go either way with using a single library for everything).
You can also give it an alias from the $ restoring call, it returns a reference to jQuery, so you can do this:
var $j = jQuery.noConflict(); //restore $ to prototype
$j(function(){
$j("div.scrollable").hide();
});
$('div.box').hide();
Once I had the same problem, using Prototype and jQuery on the same page, and specifying the jQuery.noConflict() function, but my stuff didn't fade in/out right (stuff were jumping weird and sometimes only worked on the first animation). When I disabled Prototype, my jQuery code did exactly what it was supposed to do. I came to the conclusion the jQuery and Prototype have the same function names and these cause conflict in some way.
Disable Prototype temporarily and see if your jQuery code performs as expected.

Resources