零JS筆記 | 圖片放大镜

问题:

<div id="div1">
    <div id="div2"></div>
</div>
<script>
    var _div1 = document.getElementById('div1')
    var _div2 = document.getElementById('div2')
    _div1.onmouseover = function () {
        document.title += 1
    }
    _div1.onmouseout = function () {
        document.title += 2
    }
</script>
<style>
    #div1 { width: 200px; height: 200px; background: red; }
    #div2 { width: 100px; height: 100px; background: yellow; }
</style>

從紅---> 黃 2121212121
1、觸發本身元素的out事件,所以+2,當到黃上,冒泡,又觸發本身的over事件+1
2、所以会发生闪动;

解决:
1、js: onmouseenter onmouseleave (子級不會影響父級 )
2、全兼容作法;
3、css: 加層隔開父子級;

window.onload = function () {
    var oDiv1 = document.getElementById('div1');
    var oDiv2 = document.getElementById('div2');

    oDiv1.onmouseover = function (ev) {
        var ev = ev || window.event;

        var a = this, b = ev.relatedTarget; //相對目標,之前的目標,移入目標之前的元素
        if (!elContains(a, b) && a != b) {
            document.title += '1';
        }
    };
    oDiv1.onmouseout = function (ev) {
        var ev = ev || window.event;

        var a = this, b = ev.relatedTarget;
        if (!elContains(a, b) && a != b) {
            document.title += '2';
        }
    };
};

function elContains(a, b) {  //判断两个元素是否是嵌套关系 a是否包含b
    return a.contains ? a != b && a.contains(b) : !!(a.compareDocumentPosition(b) & 16);
}

简单放大镜:

window.onload = function () {
    var _div = document.getElementById('div1')
    var _span = document.getElementsByTagName('span')[0]
    var _div2 = document.getElementById('div2')
    var _img2 = _div2.getElementsByTagName('img')[0]
    _div.onmouseover = function () {
        _span.style.display = 'block'
    }
    _div.onmouseout = function () {
        _span.style.display = 'none'
    }
    _div.onmousemove = function (e) {
        var e = e || event;
        var L = e.clientX - _div.offsetLeft - _span.offsetWidth / 2
        var T = e.clientY - _div.offsetTop - _span.offsetHeight / 2
        if (L < 0) {
            L = 0
        }
        else if (L > _div.offsetWidth - _span.offsetWidth) {
            L = _div.offsetWidth - _span.offsetWidth
        }
        if (T < 0) { //注意這裏不能寫else if
            T = 0
        }
        else if (T > _div.offsetHeight - _span.offsetHeight) {
            T = _div.offsetHeight - _span.offsetHeight
        }
        _span.style.left = L + 'px'
        _span.style.top = T + 'px'
        var scaleX = L / (_div.offsetWidth - _span.offsetWidth) //比例; 0-1
        var scaleY = T / (_div.offsetHeight - _span.offsetHeight) //比例:0-1
//大圖能走的距離為本身距離 - 大圖外層可視區的距離 ;
//此距離  * 比例

        _img2.style.left = -scaleX * (_img2.offsetWidth - _div2.offsetWidth) + 'px'
        _img2.style.top = -scaleY * (_img2.offsetHeight - _div2.offsetHeight) + 'px'


    }
}

See the Pen jbgrXw by elmok (@elmok) on CodePen.


<script async src="//assets.codepen.io/assets/embed/ei.js"></script>

零JQ筆記 | 組件小例

架子:

$(function () {
        var t1 = new Tab();
        ti.init('div1', {})
    })

    function Tab() {
        this.settings = { //默認參數
            event: 'click'
        }
    }
    Tab.prototype.init = function (_parent, opt) {
        $.extend(this.settings, opt);


    }

主要分離3方面:


配置參數:opt:events , delay


方法:methos:nowSel(),getContent


事件:beforeClick,afterClick


注意的點:

1、jq中主動解發 $(_this).trigger('afterClick'),相當於 autoEvent(_this, 'afterClick') ;


2、特別留意this指向問題;


3、jq中$.extend(this.settings, opt),相當於 extend(this.settings, opt)


    $(function () {
        var t1 = new Tab();
        t1.init('div1', {})
        var t2 = new Tab();
        t2.init('div2', {
            event:'mouseover'
        })

        var t3 = new Tab();
        t3.init('div3', {
            event:'mouseover',
            delay:200
        })
        var t4 = new Tab();
        t4.init('div4', {})
        t4.nowSel(2)
        $('#inp1').click(function(){
            console.log(t4.getContent());
        })

        $(t4).on('beforeClick', function () {
            console.log(t4.getContent() + ' before');
        })
        $(t4).on('afterClick', function () {
            console.log(t4.getContent() + ' after');
        })

    })

    function Tab() {
        this._parent = null;
        this._inp = null;
        this._div = null;
        this.cur = 0;
        this.settings = { //默認參數
            event: 'click',
            delay:0
        }
    }
    Tab.prototype.init = function (_parent, opt) {
        $.extend(this.settings, opt);
        this._parent = $('#'+_parent);
        this._inp = this._parent.find('input');
        this._div = this._parent.find('div');
        this.change();
    }
    Tab.prototype.change = function () {
        var _this = this;
        var _t = null;
        this._inp.on(this.settings.event,function(){

            var This = this;
            if(_this.settings.event == 'mouseover' && _this.settings.delay){
                _t = setTimeout(function(){
                    show(This)
                },_this.settings.delay);
            }
            else{
                show(this)
            }
        }).mouseout(function () {
            clearTimeout(_t);
        })
        function show(obj){ //obj指按鈕;

            $(_this).trigger('beforeClick') ; //點擊前

            $(obj).attr('class','active').siblings().removeClass('active');
            _this._div.eq($(obj).index()).css('display','block').siblings('div').css('display','none')
            _this.cur = $(obj).index()  //千萬注意this指向,坑

            $(_this).trigger('afterClick') ; //點擊前
        }
    }
    Tab.prototype.nowSel = function(index){
        this._inp.eq(index).attr('class','active').siblings().removeClass('active');
        this._div.eq(index).css('display','block').siblings('div').css('display','none')
        this.cur = index;
    }
    Tab.prototype.getContent = function () {
        return this._div.eq(this.cur).html()
    }

http://tangram.baidu.com/magic/