问题
I am trying to develop a jQuery widget which can be embedded on any site. Following is the script code:
(function($) {
var jQuery;
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.6.2')
{
var script_tag = document.createElement('script');
script_tag.setAttribute("type","text/javascript");
script_tag.setAttribute("src","http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js");
script_tag.onload = scriptLoadHandler;
script_tag.onreadystatechange = function ()
{
if (this.readyState == 'complete' || this.readyState == 'loaded')
scriptLoadHandler();
};
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
}
else
{
jQuery = window.jQuery;
main();
}
function scriptLoadHandler()
{
jQuery = window.jQuery.noConflict(true);
main();
}
function main() {
jQuery(document).ready(function($) {
var css = $("<link>", { rel: "stylesheet", type: "text/css", href: "http://mysite.com/my_css_path.css" });
css.appendTo('head');
});
$.fn.fetchfeed = function(options) {
var defaults = {
//default params;
};
var opts = $.extend(defaults, options);
var myURL = "http://mysite.com/"+opts.user+".json?";
var params = "&callback=?"
var jsonp_url = myURL + encodeURIComponent(params);
$.getJSON(jsonp_url, function(data) {
//build widget html
})
.error(function() {
//show error
});
}
}
})(jQuery);
And following is the code which need to be placed on User's site:
<script id='mywidgetscript' src='http://my_site.com/javascripts/widget.js'></script>
<div id='my-widget-container'></div>
<script>$('#my-widget-container').fetchfeed({/*parameters*/});</script>
When I put this code on other site and try to load the widget it gives me the Uncaught TypeError: Can not set property 'fetchfeed' of undefined
error and fails to load the widget. What could be wrong?
Surprisingly this widget code is working on my site on localhost!!!
回答1:
If jQuery was undefined before your code execution, then you get TypeError
here:
$.fn.fetchfeed
because $
aren't jQuery object. Try to move this row and following code in the main()
into the jQuery(document).ready(function($){ ... });
construction above.
回答2:
Okay, after countless attempts I solved it and got to learn many things. Still I'm unclear about many things. Do correct me by editing this answer or please comment if you find anything wrong.
First $.fn
was null (or value being passed to it was null/undefined). Reason, the script was getting executed after <script>$('#my-widget-container').fetchfeed({/*parameters*/});</script>
being called. So .fetchfeed({...})
was undefined.
Then I moved the code in window.onload
it gave me error can not call method fetchfeed on null
. It must be because it was not getting the element (i.e. $('#my-widget-container')
) also script was not able to recognize $
.
Again after few tweaks making $.fn.fetchfeed
to function fetchfeed() {...}
gave me error undefined fetchfeed
. This was because function fetchfeed was inside another function.
Also encoding &callback=?
parameter gives Access-Control-Allow-Origin
error. This should be passed in url as is.
After some research I modified the code as below and now working correctly.
function fetchfeed(options) {
var o = options;
var jQuery;
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.6.2')
{
var script_tag = document.createElement('script');
script_tag.setAttribute("type","text/javascript");
script_tag.setAttribute("src","http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js");
script_tag.onload = scriptLoadHandler;
script_tag.onreadystatechange = function ()
{
if (this.readyState == 'complete' || this.readyState == 'loaded')
scriptLoadHandler();
};
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
}
else
{
jQuery = window.jQuery;
ff(jQuery, o);
}
function scriptLoadHandler()
{
jQuery = window.jQuery.noConflict(true);
ff(jQuery, o);
}
function ff($, options) {
var defaults = {
...
};
var opts = $.extend(defaults, options);
var jsonp_url = "http://mysite.com/?callback=?";
$.getJSON(jsonp_url, function(data) {
//success
})
.error(function() {
//fail
});
}
}
Code on user's site/blog will be
<div id='my-widget-container'></div>
<script id='my_widget_script' src='https://PATH_OF_SCRIPT/FILE_NAME.js'></script>
<script type='text/javascript'>
fetchfeed({/*params*/});
</script>
The function will be executed when page load completes.
来源:https://stackoverflow.com/questions/7817522/uncaught-typeerror-can-not-set-propery-function-name-of-undefined-for-widget