问题
I wanted paperjs
to load after a button is pressed to turn on animations but it seems the paperscript doesn't work if paper is loaded after page load.
If you comment out the setTimeout
and uncomment the direct $.getScript
- paperjs will fire the alert('hi')
. I don't get it.
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$(document).ready(function () {
var paperUrl = 'http://cdnjs.cloudflare.com/ajax/libs/paper.js/0.22/paper.js';
$("#jq").text("jQuery is now loaded.")
var lateLoad = function() {
$.getScript(paperUrl, function() {
$("#pp").text("Paperjs is now loaded.");
});
};
//setTimeout(lateLoad, 100);
$.getScript(paperUrl, function() {
$("#pp").text("Paperjs is now loaded.");
});
});
</script>
</head>
<body>
<script type="text/paperscript" canvas="myCanvas">
$('body').css({"background-color": "#999"});
alert('hi!');
</script>
<p id="jq">jQuery NOT loaded yet.</p>
<p id="pp">Paperjs NOT loaded yet.</p>
</body>
</html>
I'm using Chrome 23.0.1271.97 m on Windows 7 x64. Anybody have an idea what's going on here?
回答1:
I think I figured out a workaround as well - paper.PaperScript.load()
or to elaborate:
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$(document).ready(function () {
$("#jq").text("jQuery is now loaded.")
var paperUrl = 'http://cdnjs.cloudflare.com/ajax/libs/paper.js/0.22/paper.js';
var lateLoad = function() {
$.getScript(paper_url, function() {
$("#pp").text("Paperjs is now loaded.");
paper.PaperScript.load(); // <-- The fix!
});
};
setTimeout(lateLoad, 1000);
//$.getScript(paperUrl, function() {
// $("#pp").text("Paperjs is now loaded.");
//});
});
</script>
</head>
<body>
<script type="text/paperscript" canvas="myCanvas">
$('body').css({"background-color": "#999"});
alert('hi!');
</script>
<p id="jq">jQuery NOT loaded yet.</p>
<p id="pp">Paperjs NOT loaded yet.</p>
</body>
</html>
That causes paperscript to scan for all the paperscripts. I found it at https://github.com/paperjs/paper.js/blob/master/src/core/PaperScript.js#L270 while googling for "paperscript" in the github repo. Though it still doesn't explain why paper doesn't do the load() on its own when dynamically loaded.
EDIT - I understand what went wrong. It's related to https://github.com/jquery/jquery/blob/master/src/core.js#L768 because paperjs doesn't check if the window loaded event had already fired i.e document.readyState === "complete"
. I submitted a pull request to paperjs https://github.com/paperjs/paper.js/pull/156
回答2:
I think it is easier to load it via require.js. All you need is a require.config
object, defined in e.g. main.js:
requirejs.config({
paths : {
'jquery' : "path/to/jquery"
'paper' : "path/to/paper"
},
shim: {
'jquery' : {
exports: 'jQuery'
},
'paper' : {
exports: 'paper'
}
}
});
You will need to load require.js with the above config via the data-main
attribute:
<script data-main="scripts/main.js" src="scripts/require.js"></script>
Then you define a module (e.g. 'paperStuff') where your paper logic will be:
define(['jquery', 'paper'], function($, paper) {
// do some cool stuff
});
When you want to load your paperStuff, you just do
var paperStuff = require('paperStuff');
...
回答3:
Move your paperscript code into an external file (i.e. pstest.js) and modify your lateLoad to:
var lateLoad = function() {
$.getScript('http://cdnjs.cloudflare.com/ajax/libs/paper.js/0.22/paper.js',
function() {
$("#pp").text("Paperjs is now loaded.");
$.getScript("pstest.js");
} )
}
来源:https://stackoverflow.com/questions/14110205/dynamically-loading-a-script-changes-its-behaviour