1

一些元素位置设置的通用方法

/**
 * 查找元素的左端位置,
 * 代码依赖:getStyle来自 https://gist.github.com/hehongwei44/9abf63536accd0f2eeb7
 * */

function posX(elem) {
    return parseInt(getStyle(elem, "left"));
}
/**
 * 查找元素的顶端位置
 * */

function posY(elem) {
    return parseInt(getStyle(elem, "top"));
}

/*设置元素x和y位置(与当前位置无关)的一对函数*/
/**
 * 设置元素水平的函数
 * */
function setX(elem, pos) {
    elem.style.left = pos + "px";
}

/**
 * 设置元素垂直位置的函数
 * */
function setY(elem, pos) {
    elem.style.top = pos + "px";
}

/**
 * 在元素的水平位置上增加像素距离的函数
 * */
function addX(elem, pos) {
    setX(posX(elem) + pos);
}
/**
 * 在元素的垂直位置上增加像素距离的函数
 * */
function addY(elem, pos) {
    setY(posY(elem) + pos);
}

代码来源:https://gist.github.com/hehongwei44/7f0eca7c0a0ae19adc9f

元素相对于整个父亲节点的left和top的辅助函数

/**
 * 元素elem相对于父亲元素的左端和顶端的位置
 * 依赖脚本:https://gist.github.com/hehongwei44/8d33a6e35ee045722e75
 * */

/**
 * 获取元素相对于父亲元素的水平位置
 * */
function parentX(elem) {
    /**
     * 如果offsetParent是元素的父亲,那么提前提出
     * 否则,我们需要找到元素和元素的父亲相对于整个页面位置,并计算他们之间的差
     * */
    return elem.parentNode == elem.offsetParent ? elem.offsetLeft : pageX(elem) - pageX(elem.parentNode);
}

/**
 * 获取元素相对于父亲元素的顶端位置
 *
 * */
function parentY(elem) {
    /**
     * 如果offsetParent是元素的父亲,那么提前提出
     * 否则,我们需要找到元素和元素的父亲相对于整个页面位置,并计算他们之间的差
     * */
    return elem.parentNode == elem.offsetParent ? elem.offsetTop : pageY(elem) - pageY(elem.parentNode);
}

代码来源:https://gist.github.com/hehongwei44/d8530ae974b1aabbab55

元素相对于整个文档的left和top的辅助函数

/*元素elem相对于整个文档的左端和顶端的位置*/

/**
 * 获取元素的水平位置
 * */
function pageX(elem) {
    /**
     * 参看我们是否位于根元素
     * 如果我们能继续得到上一个元素,增加当前偏移量并继续向下递归.
     * 否则,获取当前的偏移量.
     * */
    return elem.offsetParent ? elem.offsetLeft + pageX(elem.offsetParent) : elem.offsetLeft;
}

/**
 * 获取元素的顶端位置
 *
 * */
function pageY(elem) {
    /**
     * 参看我们是否位于根元素
     * 如果我们能继续得到上一个元素,增加当前偏移量并继续向下递归.
     * 否则,获取当前的偏移量.
     */
    return elem.offsetParent ? elem.offsetTop + pageY(elem.offsetParent) : elem.offsetTop;
}

代码来源:https://gist.github.com/hehongwei44/8d33a6e35ee045722e75

事件模型的封装

/**
 *
 * @author Dean Edwards
 * @date 2005/10
 * @link http://dean.edwards.name/weblog/2005/10/add-event/
 * @transform  https://github.com/hehongwei44
 * @compatibility IE6+ ,FF, chrome
 *
 * */

 //调用方式->addEvent(window, "load", function(){})
function addEvent(element, type, handler) {
    //如果浏览器原生支持W3C的标准行为addEventListener函数,则直接绑定函数句柄.
    if (element.addEventListener) {
        //flase表示不支持事件捕捉,主流浏览器都支持该标准,IE9+
        element.addEventListener(type, handler, false);
    } else {
        // 为每一个事件句柄赋值一个独立的ID,addEvent.guid的初始值为1.
        if (!handler.$$guid) handler.$$guid = addEvent.guid++;
        // 为元素建立一个事件类型的散列表
        if (!element.events) element.events = {};
        // 为每对元素/事件建立一个事件处理函数的散列表
        var handlers = element.events[type];

        if (!handlers) {

            handlers = element.events[type] = {};
            // 存储已有的事件处理函数(如果已存在一个),ps:用来特殊处理"on+type"的类型事件.
            if (element["on" + type]) {
                handlers[0] = element["on" + type];
            }
        }
        // 在散列表中存储该事件的处理函数.
        handlers[handler.$$guid] = handler;
        // 赋以一个全局事件处理函数来处理所有的工作
        element["on" + type] = handleEvent;
    }
}
// 创建独立ID的计数器
addEvent.guid = 1;

function removeEvent(element, type, handler) {
    if (element.removeEventListener) {
        element.removeEventListener(type, handler, false);
    } else {
        // 从散列表中删除事件处理函数
        if (element.events && element.events[type]) {
            delete element.events[type][handler.$$guid];
        }
    }
}
//事件处理函数
function handleEvent(event) {
    var returnValue = true;
    // 获取事件对象(IE使用全局事件对象)
    event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
    // 获取事件处理函数散列表的引用.
    var handlers = this.events[event.type];
    // 依次执行每个事件处理函数
    for (var i in handlers) {
        this.$$handleEvent = handlers[i];
        //执行回调函数
        if (this.$$handleEvent(event) === false) {
            returnValue = false;
        }
    }
    return returnValue;
}

//重新包装event对象,使其兼容IE和W3C标准.
function fixEvent(event) {
    // 增加W3C标准事件方法.
    event.preventDefault = fixEvent.preventDefault;
    event.stopPropagation = fixEvent.stopPropagation;
    return event;
}
//IE浏览器阻止默认行为的方式
fixEvent.preventDefault = function () {
    //this指向event对象
    this.returnValue = false;
}
//IE浏览器阻止冒泡的方式
fixEvent.stopPropagation = function () {
    //this指向event对象
    this.cancelBubble = true;
};

代码来源:https://gist.github.com/hehongwei44/3c9ec099751f8f2e197e

阻止事件冒泡和默认行为的通用函数

/**
 * 阻止事件冒泡的通用函数
 * */
function stopBubble(e) {
    if (e && e.stopPropagation) {
        e.stopPropagation();
    } else {
        window.event.cancelBubble = true;
    }
}

/**
 * 防止发生默认浏览器行为的通用函数
 * */
function stopDefault(e) {
    if (e && e.preventDefault) {
        e.preventDefault();
    } else {
        window.event.returnValue = false;
    }
    return false;
}

代码来源:https://gist.github.com/hehongwei44/5fb2134a70ab8379849e


两仪
9.6k 声望729 粉丝

向上努力、不卑不亢、两仪相生