1

我正在尝试创建一个 jQuery 插件,在里面我需要做一个 AJAX 调用来加载一个 xml。

jQuery.fn.imagetags = function(options) {

  s = jQuery.extend({
     height:null,
     width:null,
     url:false,
     callback:null,
     title:null,
  }, options);

  return this.each(function(){
    obj = $(this);

    //Initialising the placeholder  
    $holder = $('<div />')
    .width(s.width).height(s.height)
    .addClass('jimageholder')
    .css({
        position: 'relative',
    });
    obj.wrap($holder);

    $.ajax({
      type: "GET",
      url: s.url,
      dataType: "xml",
      success:function(data){ initGrids(obj,data,s.callback,s.title); } ,
      error: function(data) { alert("Error loading Grid data."); },
    });

    function initGrids(obj, data,callback,gridtitle){
    if (!data) {
      alert("Error loading Grid data");
    }

    $("gridlist gridset",data).each(function(){
      var gridsetname = $(this).children("setname").text();
      var gridsetcolor = "";
      if ($(this).children("color").text() != "") {
        gridsetcolor = $(this).children("color").text();
      }
      $(this).children("grid").each(function(){     
        var gridcolor = gridsetcolor;
        //This colour will override colour set for the grid set
        if ($(this).children("color").text() != "") {
          gridcolor = $(this).children("color").text();
        }

        //addGrid(gridsetname,id,x,y,height,width)
        addGrid(
            obj,
            gridsetname,
            $(this).children("id").text(),
            $(this).children("x").text(),
            $(this).children("y").text(),
            $(this).children("height").text(),
            $(this).children("width").text(),
            gridcolor,
            gridtitle
        );

      });
    });

    }

    function addGrid(obj,gridsetname,id,x,y,height,width,color,gridtitle){
      //To compensate for the 2px border
      height-=4;
      width-=4;

      $grid = $('<div />')
        .addClass(gridsetname)
        .attr("id",id)
        .addClass('gridtag')
        .imagetagsResetHighlight()
        .css({
        "bottom":y+"px",
        "left":x+"px",
        "height":height+"px",
        "width":width+"px",
         });
       if(gridtitle != null){
         $grid.attr("title",gridtitle);
       }

      if(color != ""){
        $grid.css({
        "border-color":color,
        });
      }
      obj.after($grid);
    }
  });
}

上面的插件我绑定了 2 个 DOM 对象并加载了两个单独的 XML 文件,但回调函数仅在使用两个加载的 XML 文件的最后一个 DOM 对象上运行。

我该如何解决这个问题,以便将回调应用于相应的 DOM。上面的ajax调用是否正确?

示例用法:

<script type="text/javascript">
        $(function(){
            $(".romeo img").imagetags({
              height:500,
              width:497,
              url: "sample-data.xml",
              title: "Testing...",
              callback:function(id){
                console.log(id);
              },
            });
        });
       </script>
       <div class="padding-10 min-item background-color-black">
         <div class="romeo"><img src="images/samplecontent/test_500x497.gif" alt="Image"> </div>
       </div>

<script type="text/javascript">
        $(function(){
            $(".romeo2 img").imagetags({
              height:500,
              width:497,
              url: "sample-data2.xml",
              title: "Testing...",
              callback:function(id){
                console.log(id);
              },
            });
        });
       </script>
       <div class="padding-10 min-item background-color-black">
         <div class="romeo2"><img src="images/samplecontent/test2_500x497.gif" alt="Image"> </div>
       </div>

这是示例 XML 数据:

<?xml version="1.0" encoding="utf-8"?>
<gridlist>
    <gridset>
      <setname>gridset4</setname>
      <color>#00FF00</color>
      <grid>
        <color>#FF77FF</color>
        <id>grid2-324</id>
        <x>300</x>
        <y>300</y>
        <height>60</height>
        <width>60</width>
     </grid>
    </gridset>
    <gridset>
      <setname>gridset3</setname>
      <color>#00FF00</color>
      <grid>
        <color>#FF77FF</color>
        <id>grid2-212</id>
        <x>300</x>
        <y>300</y>
        <height>100</height>
        <width>100</width>
     </grid>
     <grid>
        <color>#FF77FF</color>
        <id>grid2-1212</id>
        <x>200</x>
        <y>10</y>
        <height>200</height>
        <width>10</width>
     </grid>
   </gridset>
</gridlist>
4

2 回答 2

0

您可能会遇到问题,因为您在同一个 url 上调用 ajax 加载,因此第二次调用取消了第一次调用。

如果您为每个 div 读取相同的 url,为什么不调用一次 ajax,然后在它返回时循环元素。

jQuery.fn.imagetags = function(options) {

  s = jQuery.extend({
     height:null,
     width:null,
     url:false,
     callback:null,
     title:null,
  }, options);

  var elems = $(this);

  $.ajax({
      type: "GET",
      url: s.url,
      dataType: "xml",
      success:function(data){ 
        elems.each(function() {     
          obj = $(this);

          //Initialising the placeholder  
          $holder = $('&lt;div /&gt;')
          .width(s.width).height(s.height)
          .addClass('jimageholder')
          .css({
              position: 'relative',
          });
          obj.wrap($holder); 
          initGrids(obj,data,s.callback,s.title); 
        });
      },
      error: function(data) { alert("Error loading Grid data."); }
    });

  return $(this);
}

基本上,您在这里所做的是调用 ajax 函数然后立即返回集合。然后,当 ajax 回调被触发时,您循环元素并附加数据。

于 2009-03-30T18:19:44.277 回答
0

这可能是一个范围界定问题。在函数内声明变量时应该使用“var”语句。否则,变量将进入全局范围。

var s = jQuery.extend({
     height:null,
     width:null,
     url:false,
     callback:null,
     title:null,
  }, options);

elems.each(function() {     
      var obj = $(this);

      ....
}

由于变量存在于全局范围内,它们会被循环中的每次迭代覆盖,并最终导致最后一个 DOM 元素。

于 2009-12-15T16:02:29.227 回答