首页 > 开发 > JS > 正文

javascript插件_飘窗,运用构造函数设计模式和坐标轴原理

2016-04-06 13:04:09  来源:极客头条

                                由于客户有这么一个需要再网页中嵌套一个飘窗,然后点击的时候可以链接到指定网站的这么一个需求,其实网上有很多类似的插件,js、jquery都能找到很多,后来想了一下,还是决定自己写一个,熟悉一下,其实写任何插件都应该先理清楚自己的需求,然后才能进行下去,这里我用到了构造函数设计模式和一些简单的实现逻辑(当然了也可以称之为算法),所谓的设计模式和算法,也就是生活中的一些例子和思想,只不过是有心人,总结并加以改进的结果。利于工厂模式,估计最开始也就是根据工厂的流程来的吧,观察者模式是不是有点像我之前写的村子的大喇叭,或者是哨兵的角色?至于算法,冒泡排序,可能也就是一群小孩总结的怎么快速排序的呢,像我下面的逻辑,我就是利用左边的原理,飘窗的四个方向,我一下理解成了坐标轴的四个方向,每次到达边界的时候改变一个x或者y就能满足需求,当然也可以定义四个坐标的点也未尝不可。
  建议如果大家看设计模式或者算法的时候,不要拘泥于设计模式和算法本身,结合实际更好,或者说你现在不知道,或者工作中没有用过,也没关系,可能在以后的工作中不知不觉的就用上了。
  代码:

/**
 * @author cangowu
 * @date 2016.04.06
 * @constructor
 * 在网页中实现飘窗的功能
 * 可以自定义:
 * 窗口的起始位置:posLeft,posTop
 * 飘窗的大小:width,height
 * 飘窗的图片url,文字text以及连接link的值
 */
function FloatWindow() {
    this.domDiv;
    this.nWidth;
    this.nHeight;
    this.oTimer;
    this.oDirection = {
        x: 1,
        y: -1
    };
};
FloatWindow.prototype = {
    init: function (option) {
        if (typeof option === 'undefined') {
            option = {};
        }
        var opt = option;

        var sPosLeft = opt.posLeft || '0px',
            sPosTop = opt.posTop || '0px',
            sWidth = opt.width || '100px',
            sHeight = opt.height || '100px',
            sHref = opt.href || '',
            sTarget = opt.target || '_blank',
            sUrl = opt.url || '',
            sText = opt.text || '';

        var domDiv = document.createElement('div');
        domDiv.style.position = 'absolute';
        domDiv.style.left = sPosLeft;
        domDiv.style.top = sPosTop;
        domDiv.style.width = sWidth;
        domDiv.style.height = sHeight;
        domDiv.style.backgroundColor = 'red';

        var that = this;
        if (window.attachEvent) {
            domDiv.attachEvent('onmouseenter', function () {
                clearInterval(that.oTimer);
            });
            domDiv.attachEvent('onmouseleave', function () {
                that.work();
            });
        }
        else {
            domDiv.addEventListener('mouseenter', function () {
                clearInterval(that.oTimer);
            });
            domDiv.addEventListener('mouseleave', function () {
                that.work();
            });
        }

        var domLink = document.createElement('a');
        domLink.target = sTarget;
        domLink.href = sHref || '';

        if (opt.hasOwnProperty('url') && sUrl != '') {
            var domImg = document.createElement('img');
            domImg.src = sUrl;
            domImg.style.width = sWidth;
            domImg.style.height = sHeight;

            domLink.appendChild(domImg);
        } else {
            var domText = document.createElement('div');
            domText.innerHTML = sText;

            domLink.appendChild(domText);
        }

        domDiv.appendChild(domLink);
        document.body.appendChild(domDiv);

        this.domDiv = domDiv;
        this.nWidth = parseInt(sWidth.replace('px', ''));
        this.nHeight = parseInt(sHeight.replace('px', ''));

    },
    work: function () {
        var domDiv = this.domDiv,
            nWidth = this.nWidth,
            nHeight = this.nHeight,
            oDirection = this.oDirection;

        this.oTimer = setInterval(function () {
            var nLeft = 10 * oDirection.x + parseInt(domDiv.style.left.replace('px', ''));
            var nTop = 10 * oDirection.y + parseInt(domDiv.style.top.replace('px', ''));

            var nClientWidth = document.documentElement.clientWidth - nWidth,
                nClientHeight = document.documentElement.clientHeight - nHeight;

            /**
             * 这里主要是实现了方向的转换,大家可以参照坐标轴来,我上面定义的oDirection,就是先向右上角,顺时针旋转
             * 1.当到达顶部,改变y向下运动
             * 2.当到达右边,改变x向左运动
             * 3.当到达底部,改变y向上运动
             * 4.当到达左边,改变x向右运动
             */
            if (nTop < 0) {
                nLeft = nLeft + nTop;
                nTop = 0;
                oDirection.y = 1;
            } else if (nLeft > nClientWidth) {
                nTop = nTop - (nLeft - nClientWidth);
                nLeft = nClientWidth;
                oDirection.x = -1;
            } else if (nTop > nClientHeight) {
                nLeft = nLeft - (nTop - nClientHeight);
                nTop = nClientHeight;
                oDirection.y = -1;
            } else if (nLeft < 0) {
                nTop = nTop + nLeft;
                nLeft = 0;
                oDirection.x = 1;
            }

            domDiv.style.left = nLeft + 'px';
            domDiv.style.top = nTop + 'px';
        }, 100);
    }
};


var floatWin = new FloatWindow();
var option = {
    posLeft: '100px',
    posTop: '100px',
    width: '100px',
    height: '200px',
    href: 'http://www.baidu.com',
    target: '_blank',
    url: 'wzg.jpg',
    text: '我是text'
};
floatWin.init(option);
floatWin.work();