<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    關注技術,關注生活

    任何事情只要開始去做,永遠不會太遲。
    posts - 5, comments - 23, trackbacks - 0, articles - 18
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    [原創]prototype對于標簽定位的一些BUG

    Posted on 2006-12-09 14:47 errorfun 閱讀(1500) 評論(2)  編輯  收藏 所屬分類: JavaScript

    問題起因:
    在原來產品中實現的 ajax tree上面添加拖拽效果,為了方便,使用了prototype來簡化開發。代碼中使用了Poistion.absolutize來改變拖動標簽時改變它的坐標為絕對坐標顯示,拖動結束后再使用Poistion.relativize變回相對坐標。

    解決過程:
    其實一開始測試時都挺好的,但后來在tree上面使用時就發生問題了,在拖動過程,標簽跟著鼠標的移動而改變,沒有問題,但在鼠標釋放后,標簽并沒有放置在鼠標釋放的位置,而是向左和向上偏移了,而這偏移的距離剛好就是tree顯示位置的left和top。在對拖動結束后的位置計算的代碼,拖動過程坐標計算的代碼debug了一天沒有收獲后,突然想到把樣式中的滾動條設置(overflow-x : "auto", overflow-y: "scroll",)刪掉試下,沒想到就可以了。

    經過反復驗證,終于證實是滾動條惹的禍,接著就跟蹤了prototype中的相關代碼,在實現Position.absolutize方法時是這樣寫的:

    Position.absolutize? = ? function (element)? {
    ????element?
    = ?$(element);
    ????
    if ?(element.style.position? == ?'absolute')? return ;
    ????Position.prepare();

    var ?offsets? = ?Position.positionedOffset(element);

    ????
    var ?top????? = ?offsets[ 1 ];
    ????
    var ?left???? = ?offsets[ 0 ];
    ????
    var ?width??? = ?element.clientWidth;
    ????
    var ?height?? = ?element.clientHeight;

    ????element._originalLeft???
    = ?left? - ?parseFloat(element.style.left?? || ? 0 );
    ????element._originalTop????
    = ?top?? - ?parseFloat(element.style.top? || ? 0 );
    ????element._originalWidth??
    = ?element.style.width;
    ????element._originalHeight?
    = ?element.style.height;

    ????element.style.position?
    = ?'absolute';
    ????element.style.top????
    = ?top? + ?'px';
    ????element.style.left???
    = ?left? + ?'px';
    ????element.style.width??
    = ?width? + ?'px';
    ????element.style.height?
    = ?height? + ?'px';
    }
    ;

    其中Position.positionedOffset就是取當前標簽到body的偏移量,然后將信息存入_original*的相關屬性中,等到調用Position.relativize時,再從這些_original*屬性中從新計算出當前標簽的相對位置。
    再看一下Position.relativize的實現:

    Position.relativize?
    =?function(element)?{
    ????element?
    =?$(element);
    ????
    if?(element.style.position?==?'relative')?{
    ????????
    return;????
    ????}

    ????
    ????Position.prepare();
    ????
    ????element.style.position?
    =?'relative';
    ????
    var?top??=?parseFloat(element.style.top??||?0)?-?(element._originalTop??||?0);
    ????
    var?left?=?parseFloat(element.style.left?||?0)?-?(element._originalLeft?||?0);
    ????element.style.left???
    =?left?+?'px';
    ????element.style.top????
    =?top??+?'px';
    ????element.style.height?
    =?element._originalHeight;
    ????element.style.width??
    =?element._originalWidth;
    }
    ;

    嗯,處理得非常漂亮,沒有存在什么問題,以下是用來測試有html,試下會有什么效果
    <div?style="height:50px"></div>
    <div?style="width:500px;overflow-y:auto;height:300px">
    <div?style="height:200px"></div>
    <div?style="height:300px">
    <div?id="test"?style="height:20px">test</div>
    ????
    <input?type="button"?value="abs"?onclick="Position.absolutize('test');">
    ????
    <input?type="button"?value="rel"?onclick="Position.relativize('test');">
    ????
    </div>
    </div>

    沒錯,按下abs按鈕后,test向下移了50px左右(第二個div的offsetTop),也向右移了一點(第二個div的offsetLeft)。(如果把overflow-y:aut去掉,則沒有此情況出現)而再按下rel按鈕后,test能回復正常的位置,這就表示它在算法上沒有什么問題,問題出在了absolutize后的位置上了,而與位置相關的信息有 _originalTop 和_originalLeft,而它們的值是與Position.positionedOffset直接相關的,再查看了Position.positionedOffset的代碼:

    Position.positionedOffset?
    =?function?(element)?{????
    ????
    var?node?=?element.parentElement;????
    ????
    var?valueT?=?0,?valueL?=?0;
    ????
    ????
    do?{
    ????????valueT?
    +=?element.offsetTop?||?0;
    ????????valueL?
    +=?element.offsetLeft?||?0;
    ????????element?
    =?element.offsetParent;
    ????????
    if?(element)?{????????
    ????????????p?
    =?Element.getStyle(element,?"position");
    ????????????
    if?(p?==?"relative"?||?p?==?"absolute"?){
    ????????????????
    break;
    ????????????}

    ????????}

    ????}
    ?while?(element);????????
    ????
    ????
    return?[valueL,?valueT];
    }
    ;

    看起來似乎也無法從中找出什么毛病來。可是,查了一下html的相關文檔后,發現這段代碼存在著相當嚴重的bug。html文檔里,當樣式position取絕對坐標"absolute "時,其內容如下:
    absolute :Object is positioned relative to parent element's position—or to the body object if its parent element is not positioned—using the top and left properties.
    結合文檔內容,經過測試,如果標簽的所有祖先節點中,有任何一個是可滾動的(overflow,overflow-y,overflow-x其中一個屬性的值為auto或scroll),那標簽的絕對定位就是在此標簽中的坐標位置,而不是對于BODY的。
    所以positionedOffset方法沒有考慮到這種情況而處理,當然在一般情況下行得通了,所以代碼更改如下:


    Position.positionedOffset?
    =?function?(element)?{????
    ????
    ????
    ????
    /*
    ?????*?經過測試,如果標簽的所有祖先節點中,有任何一個是可滾動的(overflow,overflow-y,overflow-x其中一個屬性的值為auto或scroll),
    ?????*?那標簽的絕對定位就是在此標簽中的坐標位置,而不是對于BODY的。所以在返回時應該將此祖先節點對于body的偏移量減掉.
    ?????
    */

    ????????
    ????
    var?valueT?=?0,?valueL?=?0;
    ????
    ????
    do?{
    ????????valueT?
    +=?element.offsetTop?||?0;
    ????????valueL?
    +=?element.offsetLeft?||?0;
    ????????element?
    =?element.offsetParent;
    ????????
    if?(element)?{
    ????????????
    var?scrollable?=?[element.style.overflow,?element.style.overflowX,?element.style.overflowY];
    ????????????p?
    =?Element.getStyle(element,?"position");
    ????????????
    if?(p?==?"relative"?||?p?==?"absolute"?||?scrollable.include(?"auto"?)?||?scrollable.include(?"scroll"?))?{
    ????????????????
    break;
    ????????????}

    ????????}

    ????}
    ?while?(element);????????
    ????
    ????
    return?[valueL,?valueT];
    }
    ;

    至此,拖動后的標簽定位問題終于解決,看來有時候人應該相信自己多一點,多懷疑一下別人的代碼,正所謂,讀書要善疑,更何況讀別人的程序。

    評論

    # re: [原創]prototype對于標簽定位的一些BUG  回復  更多評論   

    2006-12-10 20:50 by Web 2.0 技術資源
    Object is positioned relative to parent element's position—or to the body object if its parent element is not positioned—using the top and left properties.

    查文檔才是王道!~

    # re: [原創]prototype對于標簽定位的一些BUG  回復  更多評論   

    2006-12-11 19:41 by errorfun
    蛤查文檔也是得在知道哪里問題才能查啊,呵呵

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲人成无码网站久久99热国产| 免费人成视频在线| 亚洲免费日韩无码系列| 免费人成动漫在线播放r18| 国产免费观看黄AV片| 日本亚洲中午字幕乱码| 国产一区在线观看免费| 特级aaaaaaaaa毛片免费视频| 亚洲国产成人乱码精品女人久久久不卡| 亚洲av无码一区二区三区天堂 | 老司机午夜性生免费福利| 国产成人免费福利网站| 搜日本一区二区三区免费高清视频| www国产亚洲精品久久久日本| 一级一片免费视频播放| 在线A亚洲老鸭窝天堂| 国产精品99久久免费观看| 亚洲女人影院想要爱| 免费看少妇作爱视频| 免费精品国自产拍在线播放| 伊人亚洲综合青草青草久热| 四虎影视成人永久免费观看视频| 亚洲国产中文在线二区三区免| 成人在线视频免费| 成人免费夜片在线观看| 亚洲AV成人无码久久精品老人| 国产精品久久久久久久久免费| 亚洲国产aⅴ成人精品无吗| 亚洲精品成人片在线观看| 午夜视频在线免费观看| 亚洲精品第一国产综合亚AV| 国产亚洲精aa成人网站| 亚洲一区在线免费观看| 男男gay做爽爽免费视频| 亚洲av无码成h人动漫无遮挡 | 免费黄色网址入口| xvideos永久免费入口| 亚洲av成人一区二区三区| 亚洲精品成a人在线观看| 2021免费日韩视频网| xxxx日本在线播放免费不卡|