-
-
Notifications
You must be signed in to change notification settings - Fork 313
Strange problem in Drupal #13
Comments
Unfortunately, you can't split up the $LAB.script() calls and the $LAB.wait() call like that, because that will act as two independent LAB chains and won't get your desired effect. You could do it like this:
The difference here is we "continue" the original $LAB chain by saving the ultimate return value (technically the return value from the last .script() call) int However, I would say in general, it's not a good idea to split the chains up like this, as there's a possibility that you can create race conditions (not really a case I've tested extensively). So if you do it that way, be careful and test thoroughly. Another approach, which should be a little more solid, but is based on a very similar concept (simulated chaining) is found here: https://gist.github.com/704226 -OR- |
Thanks, Kyle, that works. About the queuing, I can't use it. Developers put inline JS everywhere. I can grab all JS files and put in one chain without side effect, but for inline JS blocks, it's more difficult. However, I'll do more test about merging all inline JS blocks. |
Anyway, is it better to have an event callback like this? |
Initially, it was an important design decision for LABjs to have each $LAB chain completely independent. This is still currently my philosophy and it precludes features which deliberately tie the chains together, even for a single callback. Syntactically, it introduces an API complexity/confusion that is undesirable. If $LAB.ready() fires when all current chains are done, what happens if you start another $LAB chain after it (or inside it)... will it clear out that event? Lots of issues arise in this line of questioning. Basically, I'm not convinced that the use-case for multiple chains is all that strong (except in a few scenarios), and so I encourage people to consolidate their code into as few chains as possible. Really, you shouldn't have any code in separate chains if that code has any relationship to code being loaded in another chain. There's "simulated chaining" (with a for-loop) if you have the need to build up parts of a chain in contextually separate blocks of code and run the chain all at once once the chains parts are all known. So, while I've thought about a $LAB.ready() thing before, I think it's counter to the philosophy, API design, and best-practices that are put forth from LABjs. I'm not aware of any use-case that would be a strong argument for such a thing... can you explain why you think it's necessary? |
When I think about $LAB.ready(), I suppose that there is no $LAB.script() inside it. I didn't thought about the case when there is a $LAB.script() after a $LAB.ready(). Indeed, I thought that the browser is fast enough (or there is a small delay before $LAB.ready()) so that all $LAB.script() are called (that mean LABjs knows all scripts in the page) before $LAB.ready(). When you ask about this case, I know that I'm wrong ;-) because your decision is "as fast as the browser will allow", then there is no delay... But I wonder if a few ms delay for $LAB.ready() could be enough so that all $LAB.script() are called before .ready()? In a page there are many JS: some is in header, some is in footer, some is in the content for inline ads (the availability of JS depends on content, not on page, not all content have ads). But in fact I can postprocess to consolidate all JS file in one call, reorder JS (normally ads JS does not depend on other JS, thus it is placed 1st). So, currently I don't have any use case for multiple chain, it's just for convenient. Thanks for your help. FYI I've created a new project page to enable LABjs in Drupal automatically http://drupal.org/project/labjs . Version for Drupal 7 was out, for Drupal 6 is coming soon. Maybe there will be more use cases. |
I saw the Drupal LABjs project! Thanks so much for doing that! I understand that it's common (especially in CMS's) for people to strewn their <script> tags (both inline script blocks and external script references) about the entire HTML. That's why I gave you the link on the "queuing"... basically, you could have the drupal find all the different script blocks (inline and external src) and replace that with the appropriate call to $LAB.queue() as shown, just like you do with $LAB.script() or $LAB.wait() right now. Then, in the master footer of the page, you have one call to $LAB.executeQueue() which causes the entire set of all scripts from across all the different snippets to start loading and executing, just like if you'd done a single $LAB chain at the end manually. In my opinion, this is the best of both worlds for CMS's, because plugins and content authors get to keep leaving their scripts inline strewn about their content as makes sense to them, and the CMS takes care of re-writing all <script>...</script> and <script src="..."></script> blocks to calls to the $LAB.queue() manager, and the content/plugin authors never know the difference. |
The following code doesnot work: |
yeah, like i said, it's not particularly a supported use-case to have significant delays in the middle of a chain's operation. That's why queuing up all your script and inline scripts (into .wait()) and then firing off the chain all at once at the end is the preferred route. The two links I've sent you above show exactly how to do that. |
I've reread the queuing code snipset, but sorry I can't figure how to use it in my case. I don't want (or it is impossible) to load all scripts with LABjs. There is an inline JS block that I can't put in .wait() because of document.write(). This inline block requires an external script. Thus I have to load this external script in the traditional way. |
i undersstand that you only want to load some scripts with LABjs. as far as i'm concerned, if you have to, that's fine. if there's a script that has a document.write in it, you should definitely only load that with a regular script tag. (hint: you shold also pressure the creator of that script to stop using document.write()... it's terrible for performance!) if you're wanting is to have a regular script block in the markup have some waiting affect on the code you're loading with LABjs, this is not possible. the definition of a dynamic script loader is that it makes script loading independent from the page's other resource loading (including manual script tags). if you're just wanting to sometimes use the queueing (for LABjs loadable scripts) and other times not, do something like this:
As for how, in your original markup, to distinguish what code should be queued for LABjs and what should be left alone, have it be something like this as the original markup before you alter it with your Drupal module:
So, your original markup just starts off with script blocks strewn throughout, like shown. For the script blocks where you want LABjs to attach and queue (either for an external I dunno if this helps or not, but that's how I'd approach a CMS module for LABjs. |
That helps much! I try with queuing and it works. The conclusion could be we shouldn't use The working code is as follow, I try to make it more comprehensive: Then when will the queuing functionality officially get in? ;-) |
At the moment, I don't have specific plans to include it "officially". It's not a lot of extra size, but it is only a functionality that's actually useful if people are using it inside CMS's like you are, and in that case, I think them adding in the little extra snippet is probably the best idea. Previously, before I released v1.1.12 (actually, v1.1.11), we didn't have "conditional chaining", and there was a lot more of a use-case for this queuing. But now that conditoinal chaining is directly supported, this queuing is only necessary if you need to spread out the building of your chain across the entire HTML block. I don't generally recommend that approach, but in the specific case of CMS's, it's the best (or only) option. |
queueing was added in 2.0 |
I'm integrating LABjs into Drupal 7. However I have a problem. Here are my code:
<script type="text/javascript" src="http://d7.ttcn/sites/all/libraries/labjs/LAB.min.js?lekatr"></script>
<script type="text/javascript">
</script>
However, the code in jQuery.extend(...) has some problem. I don't know why. That line looks like never executed. I put an "alert(0)" before that line, it pops up, after that line, it does not.
Is that the correct way to do? I have a few more inline script block, I use $LAB.wait(...) for all of them.
The text was updated successfully, but these errors were encountered: