Javascript inside script tag in an Angularjs templ

2019-07-19 15:46发布

问题:

I have a simple directive that displays three images. On mouse hover, it should switch from black and white to normal image. Below given is the code inside the directive.

<div class="container">

<div class="row">
        <div class="col-md-4">
            <h3>
                Example 1</h3>
            <div class="fd-fade1 fd-effect">
                <img src="http://i.imgur.com/yxAxCaK.jpg" class="fd-img1" alt="">
            </div>
            <!-- /.fd-fade -->
        </div>
        <!-- /.col-md-4 -->
        <div class="col-md-4">
            <h3>
                Example 2</h3>
            <div class="fd-fade2 fd-effect">
                <img src="http://i.imgur.com/jlattvQ.jpg" class="fd-img2" alt="">
            </div>
            <!-- /. fd-fade -->
        </div>
        <!-- /.col-md-4 -->
        <div class="col-md-4">
            <h3>
                Example 3</h3>
            <div class="fd-fade3 fd-effect">
                <img src="http://i.imgur.com/XqtS5WA.jpg" class="fd-img3" alt="">
            </div>
            <!-- /. fd-fade -->
        </div>
        <!-- /.col-md-4 -->
    </div>
<script type="text/javascript">
 $(document).ready(function () {
           debugger;
            $('.fd-effect').hover(function () {
                    $(this).children("img").stop().fadeIn('slow');
                   // add .stop() to prevent event chaining
            }, function () {
                    $(this).children("img").stop().fadeOut("slow");
            });  // end .fd-effect
        });     // end document.ready function
</script>

</div>

The jQuery script for the hover is shown above (embedded inside the template).

My problem!!!

This code does not run inside an angularjs directive.Event the debugger does not get hit. Could someone please help me understand why it does not run?

P.S The code does run if not inside a directive.

--edit..

Since the question is way too vague for many, let me clarify.

I have a simple angular directive , that uses a template . This template contains html and inline javascript to render out 3 images .

The directive :

var app = angular.module('albumApp', []);
app.directive('album', function ($log) {
    return {
        restrict: 'E',
        templateUrl: 'templates/default.htm',
        replace: true
};
}

This is all that I have .The html is the one present in the default.htm

In the main html page,

I just write and I expect the html to be rendered and jQuery to perform like normal.

<html ng-app="albumApp">
   <head>
     <title>Test</title>
   <head>
   <body>
      <album />
   </body>
</html>

Do note: The the directive works and the template gets rendered. But the script inside the template is not functioning. My doubt is why!

回答1:

At the point the jQuery code runs and binds the hover event to the elements returned by the .fd-effect, there most likely aren't any elements that match in your document. Without seeing the context of where that markup is my guess is it is in a template rendered by Angular so your order of events is...

  1. document is ready
  2. jQuery binds hover to .fd-effect elements (there are none)
  3. Angular does some rendering
  4. sometime later you have rendered elements with class fd-effect but no bound event handlers

The solution is to write a directive that handles the DOM manipulation (i.e. the jQuery bits)

angular.module('myModule')
    .directive('fadeOut', {
        restrict: 'A',
        link: function(scope, el, attr) {
            $(el).hover(function () {
                $(el).children("img").stop().fadeIn('slow');
            }, function () {
                $(el).children("img").stop().fadeOut("slow");
            });
        }
    })

and to use in markup:

<div fade-out>
    <!-- img markup goes here -->
</div>

see:

  • https://docs.angularjs.org/guide/directive
  • http://www.sitepoint.com/practical-guide-angularjs-directives/
  • http://www.ng-newsletter.com/posts/directives.html
  • http://www.befundoo.com/university/tutorials/angularjs-directives-tutorial/
  • https://github.com/angular/angular.js/wiki/Understanding-Directives

— EDIT —

ok after a totally revised question I see that the <script> tag is in the template you are rendering. Don't do this. Use a directive for your DOM manipulations.

I haven't confirmed but I suspect that the script tag is being interpreted as the script directive

see: https://docs.angularjs.org/api/ng/directive/script



回答2:

I know this is old, but if anyone is building a very modular application where templates need particular scripts that are not needed anywhere else the accepted answer here might not suit them.

I have been digging and found that Angular uses JQlite that doesn't permit <script> tags inside templates.

However you can include JQuery just before you load Angular on your main page, Angular will then use JQuery instead of JQlite and you will be able to run your custom <script> tags that are inside each one of your templates.

This is a solution to do exactly what the question asks and is not compromising !

References :

Google group discussion on why it was not working https://groups.google.com/forum/#!topic/angular/H4haaMePJU0/discussion

Where I found a useful answer (see comment from @TheSharpieOne) : Dynamically loading AngularJS modules from within Templates (Views)



回答3:

Short answer:

Angular does not perform compilation of Javascript in HTML templates i.e. the does not get recognized by the browser even though you may see the DOM showing it.