首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JavaScript 簡易庫 bind 方法中 $(this) 指向修復:getNodes 擴展支持 window 對象

     編輯:程式設計綜合問答

問題現象

$("#kk").bind("mouseover", function() {
    $(this).html("...").css({...});  // 報錯:$(this) 非預期對象
});

根因分析

自定義 `$` 函數的 getNodes 方法未處理 this 為 window 或 DOM 元素對象的情況,導致選擇器解析失敗。

核心修復:擴展 getNodes 支持 DOM 元素與 window

$.fn.prototype.getNodes = function(selector) {
    // 1. 支持 window 對象直接傳入
    if (selector == window) {
        this.elements = selector;  // 直接賦值,不做查找
        return this;
    }
    
    // 2. 支持 DOM 元素對象直接傳入
    if (selector instanceof HTMLElement || selector instanceof Node) {
        this.elements = selector;
        return this;
    }
    
    // 3. 原有字符串選擇器邏輯
    var a = selector.substring(0, 1);
    if (a == "#") {
        this.elements = document.getElementById(selector.replace(/#/gi, ""));
    }
    // 可擴展 .class、tag 等選擇器
    
    return this;
};

bind 方法正確綁定上下文

"bind": function(mouse, fn) {
    var self = this;  // 保存當前 $ 對象實例
    $.addHandler(this.elements, mouse, function(e) {
        // 關鍵:調用 fn 時將 this 綁定為 DOM 元素
        fn.call(self.elements, e);  
        // 或創建新 $ 實例包裝
        // fn.call($(self.elements), e);
    });
}

完整可運行示例

<!DOCTYPE html>
<html>
<body>
<div id="kk">kk</div>
<script>
// 簡易 $ 庫實現
var $ = function(selector) {
    return new $.fn(selector);
};

$.fn = function(selector) {
    return $.fn.prototype.getNodes(selector);
};

$.fn.prototype.getNodes = function(selector) {
    if (selector == window || selector instanceof Node) {
        this.elements = selector;
        return this;
    }
    var a = selector.substring(0, 1);
    if (a == "#") {
        this.elements = document.getElementById(selector.replace(/#/gi, ""));
    }
    return this;
};

$.extend = function(fn) {
    for (var item in fn) {
        $.fn.prototype[item] = fn[item];
    }
};

$.addHandler = function(element, type, handler) {
    if (element.addEventListener) {
        element.addEventListener(type, handler, false);
    } else if (element.attachEvent) {
        element.attachEvent("on" + type, handler);
    }
};

$.extend({
    "html": function(a) {
        if (this.elements) this.elements.innerHTML = a;
        return this;
    },
    "css": function(css) {
        if (this.elements) {
            var str = "";
            for (var item in css) str += item + ":" + css[item] + ";";
            this.elements.style.cssText = str;
        }
        return this;
    },
    "bind": function(mouse, fn) {
        var self = this;
        $.addHandler(this.elements, mouse, function(e) {
            fn.call(self.elements, e);  // 關鍵:綁定上下文
        });
        return this;
    }
});

// 測試
$("#kk").bind("mouseover", function() {
    $(this).html("啦聖誕節弗拉聖誕")
         .css({"color":"red","font-weight":"bold"});
});
</script>
</body>
</html>

關鍵點總結

  1. getNodes 支持 window/DOM 元素直接傳入
  2. bind 使用 fn.call(element, e) 確保回調內 this 指向 DOM 元素
  3. 3. 回調中 $(this) 會重新調用 getNodes,此時 this 為 DOM 元素,滿足條件 1 正常工作 4. 返回 this 支持鏈式調用
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved