2008-12-16 3 views
7

तक पहुंचने पर IE 6/7 "निर्दिष्ट त्रुटि" बग के लिए कोई कामकाज है, मैं अवधारणा अनुप्रयोग के एक साधारण एएसपी.NET प्रमाण में jQuery UI के ड्रैगगेबल और ड्रॉपपेबल लाइब्रेरी का उपयोग कर रहा हूं। यह पृष्ठ आंशिक पृष्ठ अपडेट करने के लिए ASP.NET AJAX UpdatePanel का उपयोग करता है। यह पृष्ठ किसी उपयोगकर्ता को एक आइटम को ट्रैशकेन div में छोड़ने की अनुमति देता है, जो डेटाबेस से रिकॉर्ड हटाए जाने वाले पोस्टबैक का आह्वान करेगा, फिर सूची (और अन्य नियंत्रण) को पुनर्निर्मित करता है, जिस पर आइटम दवा थी। इन सभी तत्वों (ड्रैग करने योग्य आइटम और ट्रैशकेन div) एक एएसपी.NET अपडेट पैनेल के अंदर हैं।ऑफसेट माता-पिता

function initDragging() 
    { 
     $(".person").draggable({helper:'clone'}); 
     $("#trashcan").droppable({ 
      accept: '.person', 
      tolerance: 'pointer', 
      hoverClass: 'trashcan-hover', 
      activeClass: 'trashcan-active', 
      drop: onTrashCanned 
     }); 
    } 

    $(document).ready(function(){ 
     initDragging(); 

     var prm = Sys.WebForms.PageRequestManager.getInstance(); 
     prm.add_endRequest(function() 
     { 
      initDragging(); 
     }); 
    }); 

    function onTrashCanned(e,ui) 
    { 
     var id = $('input[id$=hidID]', ui.draggable).val(); 
     if (id != undefined) 
     { 
      $('#hidTrashcanID').val(id); 
      __doPostBack('btnTrashcan',''); 
     } 

    } 

पृष्ठ पोस्ट वापस, आंशिक रूप से UpdatePanel की सामग्री को अद्यतन करने, मैं draggables और droppables rebind जब:

यहाँ खींचने और छोड़ने आरंभीकरण स्क्रिप्ट है। जब मैं अपने कर्सर के साथ एक ड्रैगगेबल लेता हूं, तो मुझे एक "htmlfile: निर्दिष्ट त्रुटि" मिलती है। अपवाद। मैं इस समारोह है कि मैंने लिखा करने के लिए कॉल के साथ elem.offsetParent की जगह jQuery पुस्तकालय में इस समस्या को हल कर सकते हैं:

function IESafeOffsetParent(elem) 
{ 
    try 
    { 
     return elem.offsetParent; 
    } 
    catch(e) 
    {   
     return document.body; 
    } 
} 

मैं भी रूप में यह एक ही त्रुटि फेंकता elem.getBoundingClientRect() के लिए कॉल से बचने के लिए किया है। रुचि रखने वालों के लिए, मुझे केवल Dimensions Plugin में jQuery.fn.offset फ़ंक्शन में इन परिवर्तनों को करना पड़ा।

मेरे प्रश्न हैं:

  • हालांकि यह काम करता है, वहाँ बेहतर तरीके हैं (क्लीनर, बेहतर प्रदर्शन, jQuery पुस्तकालय को संशोधित करने के बिना) इस समस्या को हल करने के लिए?
  • यदि नहीं, तो भविष्य में jQuery लाइब्रेरी अपडेट करते समय मेरे परिवर्तनों को सिंक में रखने का प्रबंधन करने का सबसे अच्छा तरीका क्या है? उदाहरण के लिए, उदाहरण के लिए मैं jQuery वेबसाइट से डाउनलोड की गई फ़ाइलों में इनलाइन की तुलना में कहीं और लाइब्रेरी का विस्तार कर सकता हूं।

अद्यतन:

@some यह सार्वजनिक रूप से सुलभ नहीं है, लेकिन यदि ऐसा है तो मुझे इस जवाब में प्रासंगिक कोड पोस्ट करने देगा मैं देखेंगे। बस एक एएसपी.नेट वेब एप्लिकेशन बनाएं (इसे ड्रैग एंडड्रॉप नाम दें) और इन फ़ाइलों को बनाएं। Complex.aspx को अपने प्रारंभ पृष्ठ के रूप में सेट करना न भूलें। तुम भी jQuery UI drag and drop plug in डाउनलोड करने के लिए के रूप में अच्छी jQuery core

रूप Complex.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Complex.aspx.cs" Inherits="DragAndDrop.Complex" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml" > 
<head runat="server"> 
    <title>Untitled Page</title> 
    <script src="jquery-1.2.6.min.js" type="text/javascript"></script> 
    <script src="jquery-ui-personalized-1.5.3.min.js" type="text/javascript"></script> 
    <script type="text/javascript"> 
     function initDragging() 
     { 
      $(".person").draggable({helper:'clone'}); 
      $("#trashcan").droppable({ 
       accept: '.person', 
       tolerance: 'pointer', 
       hoverClass: 'trashcan-hover', 
       activeClass: 'trashcan-active', 
       drop: onTrashCanned 
      }); 
     } 

     $(document).ready(function(){ 
      initDragging(); 

      var prm = Sys.WebForms.PageRequestManager.getInstance(); 
      prm.add_endRequest(function() 
      { 
       initDragging(); 
      }); 
     }); 

     function onTrashCanned(e,ui) 
     { 
      var id = $('input[id$=hidID]', ui.draggable).val(); 
      if (id != undefined) 
      { 
       $('#hidTrashcanID').val(id); 
       __doPostBack('btnTrashcan',''); 
      } 

     } 
    </script> 
</head> 
<body> 
    <form id="form1" runat="server"> 
    <asp:ScriptManager ID="ScriptManager1" runat="server"> 
    </asp:ScriptManager> 
    <div> 
     <asp:UpdatePanel ID="updContent" runat="server" UpdateMode="Always"> 
    <ContentTemplate> 
     <asp:LinkButton ID="btnTrashcan" Text="trashcan" runat="server" CommandName="trashcan" 
      onclick="btnTrashcan_Click" style="display:none;"></asp:LinkButton> 
     <input type="hidden" id="hidTrashcanID" runat="server" /> 
     <asp:Button ID="Button1" runat="server" Text="Save" onclick="Button1_Click" /> 
     <table> 
      <tr> 
       <td style="width: 300px;"> 
        <asp:DataList ID="lstAllPeople" runat="server" DataSourceID="odsAllPeople" 
         DataKeyField="ID"> 
         <ItemTemplate> 
          <div class="person"> 
           <asp:HiddenField ID="hidID" runat="server" Value='<%# Eval("ID") %>' /> 
           Name: 
           <asp:Label ID="lblName" runat="server" Text='<%# Eval("Name") %>' /> 
           <br /> 
           <br /> 
          </div> 
         </ItemTemplate> 
        </asp:DataList> 
        <asp:ObjectDataSource ID="odsAllPeople" runat="server" SelectMethod="SelectAllPeople" 
         TypeName="DragAndDrop.Complex+DataAccess" 
         onselecting="odsAllPeople_Selecting"> 
         <SelectParameters> 
          <asp:Parameter Name="filter" Type="Object" /> 
         </SelectParameters> 
        </asp:ObjectDataSource> 
       </td> 
       <td style="width: 300px;vertical-align:top;"> 
        <div id="trashcan"> 
         drop here to delete 
        </div> 
        <asp:DataList ID="lstPeopleToDelete" runat="server" 
         DataSourceID="odsPeopleToDelete"> 
         <ItemTemplate> 
          ID: 
          <asp:Label ID="IDLabel" runat="server" Text='<%# Eval("ID") %>' /> 
          <br /> 
          Name: 
          <asp:Label ID="NameLabel" runat="server" Text='<%# Eval("Name") %>' /> 
          <br /> 
          <br /> 
         </ItemTemplate> 
        </asp:DataList> 
        <asp:ObjectDataSource ID="odsPeopleToDelete" runat="server" 
         onselecting="odsPeopleToDelete_Selecting" SelectMethod="GetDeleteList" 
         TypeName="DragAndDrop.Complex+DataAccess"> 
         <SelectParameters> 
          <asp:Parameter Name="list" Type="Object" /> 
         </SelectParameters> 
        </asp:ObjectDataSource> 
       </td> 
      </tr> 
     </table>  
    </ContentTemplate> 
    </asp:UpdatePanel> 
    </div> 
    </form> 
</body> 
</html> 

Complex.aspx.cs की आवश्यकता होगी

namespace DragAndDrop 
{ 
    public partial class Complex : System.Web.UI.Page 
    { 
     protected void Page_Load(object sender, EventArgs e) 
     { 
     } 

     protected List<int> DeleteList 
     { 
      get 
      { 
       if (ViewState["dl"] == null) 
       { 
        List<int> dl = new List<int>(); 
        ViewState["dl"] = dl; 

        return dl; 
       } 
       else 
       { 
        return (List<int>)ViewState["dl"]; 
       } 
      } 
     } 

     public class DataAccess 
     { 
      public IEnumerable<Person> SelectAllPeople(IEnumerable<int> filter) 
      { 
       return Database.SelectAll().Where(p => !filter.Contains(p.ID)); 
      } 

      public IEnumerable<Person> GetDeleteList(IEnumerable<int> list) 
      { 
       return Database.SelectAll().Where(p => list.Contains(p.ID)); 
      } 
     } 

     protected void odsAllPeople_Selecting(object sender, ObjectDataSourceSelectingEventArgs e) 
     { 
      e.InputParameters["filter"] = this.DeleteList; 
     } 

     protected void odsPeopleToDelete_Selecting(object sender, ObjectDataSourceSelectingEventArgs e) 
     { 
      e.InputParameters["list"] = this.DeleteList; 
     } 

     protected void Button1_Click(object sender, EventArgs e) 
     { 
      foreach (int id in DeleteList) 
      { 
       Database.DeletePerson(id); 
      } 

      DeleteList.Clear(); 
      lstAllPeople.DataBind(); 
      lstPeopleToDelete.DataBind(); 
     } 

     protected void btnTrashcan_Click(object sender, EventArgs e) 
     { 
      int id = int.Parse(hidTrashcanID.Value); 
      DeleteList.Add(id); 
      lstAllPeople.DataBind(); 
      lstPeopleToDelete.DataBind(); 
     } 
    } 
} 

Database.cs

namespace DragAndDrop 
{ 
    public static class Database 
    { 
     private static Dictionary<int, Person> _people = new Dictionary<int,Person>(); 
     static Database() 
     { 
      Person[] people = new Person[] 
      { 
       new Person("Chad") 
       , new Person("Carrie") 
       , new Person("Richard") 
       , new Person("Ron") 
      }; 
      foreach (Person p in people) 
      { 
       _people.Add(p.ID, p); 
      } 
     } 

     public static IEnumerable<Person> SelectAll() 
     { 
      return _people.Values; 
     } 

     public static void DeletePerson(int id) 
     { 
      if (_people.ContainsKey(id)) 
      { 
       _people.Remove(id); 
      } 
     } 

     public static Person CreatePerson(string name) 
     { 
      Person p = new Person(name); 
      _people.Add(p.ID, p); 

      return p; 
     } 
    } 

    public class Person 
    { 
     private static int _curID = 1; 
     public int ID { get; set; } 
     public string Name { get; set; } 
     public Person() 
     { 
      ID = _curID++; 
     } 

     public Person(string name) 
      : this() 
     { 
      Name = name; 
     } 
    } 
} 
+0

आप न्यूनतम के साथ एक परीक्षण पृष्ठ पर एक लिंक प्रदान कर सकता है? – some

उत्तर

6

@arilanto - मैं अपनी jquery स्क्रिप्ट के बाद इस स्क्रिप्ट को शामिल करता हूं। प्रदर्शन के अनुसार, यह सबसे अच्छा समाधान नहीं है, लेकिन यह एक त्वरित आसान काम है।

function IESafeOffsetParent(elem) 
{ 
    try 
    { 
     return elem.offsetParent; 
    } 
    catch(e) 
    {   
     return document.body; 
    } 
} 

// The Offset Method 
// Originally By Brandon Aaron, part of the Dimension Plugin 
// http://jquery.com/plugins/project/dimensions 
jQuery.fn.offset = function() { 
/// <summary> 
///  Gets the current offset of the first matched element relative to the viewport. 
/// </summary> 
/// <returns type="Object">An object with two Integer properties, 'top' and 'left'.</returns> 

var left = 0, top = 0, elem = this[0], results; 

if (elem) with (jQuery.browser) { 
    var parent  = elem.parentNode, 
     offsetChild = elem, 
     offsetParent = IESafeOffsetParent(elem), 
     doc  = elem.ownerDocument, 
     safari2 = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent), 
     css  = jQuery.curCSS, 
     fixed  = css(elem, "position") == "fixed"; 

    // Use getBoundingClientRect if available 
    if (false && elem.getBoundingClientRect) { 
     var box = elem.getBoundingClientRect(); 

     // Add the document scroll offsets 
     add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft), 
      box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)); 

     // IE adds the HTML element's border, by default it is medium which is 2px 
     // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; } 
     // IE 7 standards mode, the border is always 2px 
     // This border/offset is typically represented by the clientLeft and clientTop properties 
     // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS 
     // Therefore this method will be off by 2px in IE while in quirksmode 
     add(-doc.documentElement.clientLeft, -doc.documentElement.clientTop); 

    // Otherwise loop through the offsetParents and parentNodes 
    } else { 

     // Initial element offsets 
     add(elem.offsetLeft, elem.offsetTop); 

     // Get parent offsets 
     while (offsetParent) { 
      // Add offsetParent offsets 
      add(offsetParent.offsetLeft, offsetParent.offsetTop); 

      // Mozilla and Safari > 2 does not include the border on offset parents 
      // However Mozilla adds the border for table or table cells 
      if (mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2) 
       border(offsetParent); 

      // Add the document scroll offsets if position is fixed on any offsetParent 
      if (!fixed && css(offsetParent, "position") == "fixed") 
       fixed = true; 

      // Set offsetChild to previous offsetParent unless it is the body element 
      offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent; 
      // Get next offsetParent 
      offsetParent = offsetParent.offsetParent; 
     } 

     // Get parent scroll offsets 
     while (parent && parent.tagName && !/^body|html$/i.test(parent.tagName)) { 
      // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug 
      if (!/^inline|table.*$/i.test(css(parent, "display"))) 
       // Subtract parent scroll offsets 
       add(-parent.scrollLeft, -parent.scrollTop); 

      // Mozilla does not add the border for a parent that has overflow != visible 
      if (mozilla && css(parent, "overflow") != "visible") 
       border(parent); 

      // Get next parent 
      parent = parent.parentNode; 
     } 

     // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild 
     // Mozilla doubles body offsets with a non-absolutely positioned offsetChild 
     if ((safari2 && (fixed || css(offsetChild, "position") == "absolute")) || 
      (mozilla && css(offsetChild, "position") != "absolute")) 
       add(-doc.body.offsetLeft, -doc.body.offsetTop); 

     // Add the document scroll offsets if position is fixed 
     if (fixed) 
      add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft), 
       Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)); 
    } 

    // Return an object with top and left properties 
    results = { top: top, left: left }; 
} 

function border(elem) { 
    /// <summary> 
    ///  This method is internal. 
    /// </summary> 
    /// <private /> 
    add(jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true)); 
} 

function add(l, t) { 
    /// <summary> 
    ///  This method is internal. 
    /// </summary> 
    /// <private /> 
    left += parseInt(l, 10) || 0; 
    top += parseInt(t, 10) || 0; 
} 

return results; 
}; 
+4

मुझे लाइन में 'सफारी अपरिभाषित' त्रुटि मिल रही है - "safari2 = safari && parseInt (संस्करण) <522 &&! /adobeair/i.test (userAgent)"। कोई विचार? – NLV

1

मैं जबकि खींचें n ड्रॉप getBoundingClientRect() अनिर्दिष्ट निम्नलिखित वैकल्पिक हल करने की कोशिश की, और यह ठीक काम करता है।

jquery.1.4.2.js में

(यानी आधार jQuery फ़ाइल, जहां त्रुटि फेंक दिया जाता है वास्तव में)

elem.getBoundingClientRect() js फ़ाइल में समारोह कॉल की जगह

// लाइन जो अनिर्दिष्ट

var box = elem.getBoundingClientRect(),

इस के साथ

फेंकता है ..

012,

var box = null; try { box = elem.getBoundingClientRect(); } catch(e) { box = { top : elem.offsetTop, left : elem.offsetLeft } ; }

यह हल करती मुद्दा और खींचें n ड्रॉप इस बिट के लिए अद्यतन पैनल के माध्यम से वापस पोस्ट के बाद भी quitely काम करेंगे

सादर

रघु

1

@Raghu

धन्यवाद कोड का! मुझे आईई में एक ही समस्या थी और यह ठीक हो गया।

var box = null; 
try { 
    box = elem.getBoundingClientRect(); 
} catch(e) { 
    box = { 
     top : elem.offsetTop, 
     left : elem.offsetLeft 
    }; 
} 
+0

यह मेरे लिए पूरी तरह से काम किया। धन्यवाद! –

2

आप jQuery संस्करण 1.4.2 के लिए न्यूनतम किया गया/संकुचित .js फ़ाइल को ठीक करने के लिए चाहते हैं, तो बदलें:

var d=b.getBoundingClientRect(), 

var d = null; 
try { d = b.getBoundingClientRect(); } 
catch(e) { d = { top : b.offsetTop, left : b.offsetLeft } ; } 

साथ (ध्यान दें कि कोई समापन ब्रेस के बाद अल्पविराम)

+0

यह मेरे लिए ठीक काम करता है ... शेयर के लिए धन्यवाद ... – Naveen

1

मेरा संस्करण है:

  1. जोड़ें समारोह:

    function getOffsetSum(elem) { 
        var top = 0, left = 0 
        while (elem) { 
         top = top + parseInt(elem.offsetTop) 
         left = left + parseInt(elem.offsetLeft) 
         try { 
          elem = elem.offsetParent 
         } 
         catch (e) { 
          return { top: top, left: left } 
         } 
        } 
        return { top: top, left: left } 
    }; 
    
  2. साथ

    var box = getOffsetSum(this[0]) 
    

पी एस की जगह

var box = this[0].getBoundingClientRect() 

: jQuery-1.3.2।

1

यह सिर्फ एक jQuery त्रुटि नहीं है। आईई 8 पर एक्सटीजेएस 4.0.2 ए का उपयोग करके मुझे इसका सामना करना पड़ा। ऐसा लगता है कि यदि तत्व डीओएम में बदल दिया गया है तो IE लगभग हमेशा element.getBoundingClientRect() पर ठोकर खाएगा। आपका प्रयास/पकड़ हैक इस के आसपास जाने का एकमात्र तरीका है। मुझे लगता है कि वास्तविक समाधान अंततः आईई < 9 समर्थन ड्रॉप होगा।

एक्स्टजेस v4.0 जारी करें।2 ए स्रोत कोड (लाइनों 11,861-11,869):

... 
if(el != bd){ 
    hasAbsolute = fly(el).isStyle("position", "absolute"); 

    if (el.getBoundingClientRect) { 
     b = el.getBoundingClientRect(); 
     scroll = fly(document).getScroll(); 
     ret = [Math.round(b.left + scroll.left), Math.round(b.top + scroll.top)]; 
    } else { 
... 

आज़माएं/कैच ठीक साथ :

... 
if(el != bd){ 
    hasAbsolute = fly(el).isStyle("position", "absolute"); 

    if (el.getBoundingClientRect) { 
     try { 
      b = el.getBoundingClientRect(); 
      scroll = fly(document).getScroll(); 
      ret = [Math.round(b.left + scroll.left), Math.round(b.top + scroll.top)]; 
     } catch(e) { 
      ret = [0,0]; 
     } 
    } else { 
...