javascript练习题(六)

本章节的JavaScript练习涉及浏览器对象模型(BOM)、DOM操作、事件处理和XMLHttpRequest对象。挑战包括创建地震效果的窗口,实现安全的DOM移除,构建事件工具集,以及实现基于键盘移动的div元素和AJAX请求。通过这些练习,读者可以加深对JavaScript在浏览器环境中的实际应用的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第7章 浏览器环境
在本章之前,我们的练习题都是可以在各自章节的正文中找到解决方案的。但这一次,您会发现有些练习题需要我们对本书意外的内容有更多的了解(或实践经验)。

1.BOM
作为BOM的练习来说,我们可以试着写出许多错误的、富有骚扰性的、对用户非常不友好的代码,以及所有非常Web1.0的东西。例如晃动的浏览器窗口。请试着令浏览器弹出一个200*200的窗口,然后将其大小渐变成400*400,接着将窗口上下左右不停移动,造成地震效果。为了实现这种效果,我们需要move*()函数,其中需要一次货多次调用setInterval(),最后可能还需要setTimeout()及clearInterval()来令其停止操作。或者我们可以更简单一些,将当前日期通过document.title实时显示在浏览器的标题栏中,并像钟表一样每秒更新一次。

参考答案:

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>

<script type="text/javascript">
    var winSize=200;
    var win=window.open("","","width=200,height=200,resizable=yes");
    var sizeTimer=setInterval(function(){
        winSize+=5;
        if(winSize>=400){
            winSize=400;
            clearInterval(sizeTimer);
            startShake();
        }
        win.resizeTo(winSize,winSize);
    },40);

    function startShake(){
        var distance=10;
        var shakeTimer=setInterval(function(){
            win.moveBy(distance,distance);
            distance*=-1;
        },40);
        setTimeout(function(){
            clearInterval(shakeTimer);
        },10000);
    }

    showTitleTime();
    function showTitleTime() {
        setInterval(function(){
            var date=new Date();
            document.title=date.getHours()+" : "+date.getMinutes()+ " : "+date.getSeconds();
        },1000);
    }
</script>
</body>
</html>

2.DOM
1)换一种方式来实现walkDom()方法,以回调函数参数的形式来代替console.log()硬编码。
2)使用innerHTML来移除相关内容确实很方便(即document.body.innerHTML=”“),但未必总是最好的选择。如果在其中有元素被设置了事件监听器,那么当该元素被移除时,IE并不会接触该元素与监听器之间的关联。这就有可能导致浏览器中内存泄漏,因为它们所引用的内容已经不存在了。因此,请你实现一个通用的移除DOM节点的函数,它会在移除节点的同事移除相关的事件监听器。你可以遍历目标节点的属性,检查这些属性值是否属于函数类型,如果是(例如最常见的onclick属性),你就需要在该元素节点被删除之前将该属性设置为null。
1)和2)共用的html内容

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        <div class="container">
            <h1>标题</h1>
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Debitis ipsum saepe hic et id voluptatum eligendi architecto cum molestias perferendis amet nesciunt asperiores sapiente ipsam error libero similique eveniet ex!</p>
            <form>
                <input type="text" id="input1" />
                <button onclick="clicked()" type="button" id="btn">按钮</button>
            </form>
        </div>
    </body>
</html>

1)参考答案

function walkDom(dom,callback){
    callback(dom);
    var i;
    var l=dom.childNodes.length;
    for(i=0;i<l;i++){
        if(dom.childNodes[i].hasChildNodes()){
            walkDom(dom.childNodes[i],callback);
        }
    }
}

function doWithElement(elm){
    console.log(elm.nodeName);
}

walkDom(document,doWithElement);

2)参考答案

//先给button加上一个事件
function clicked() {
    console.log("click");
}

//判断是不是函数
function isFunction(f) {
    return Object.prototype.toString.call(f) === "[object Function]";
}

function empty(dom){
    while(dom.firstChild){
        empty(dom.firstChild);
    }

    var i;
    var l=dom.attributes?dom.attributes.length:0;

    for(i=0;i<l;i++){
        attr=dom[dom.attributes[i].name];
        console.log(attr);
        if(isFunction(attr)){
            attr=null;
        }
    }
    dom.parentNode.removeChild(dom);
}

empty(document.body);

3)创建一个叫做include()的函数,该函数可以按需将外部脚本引入当前页面。你可以首先动态创建一个新的script标签,然后设置其src属性,再将它插入到head标签末端。该函数应通过如下测试:
include(“somescript.js”);
3)参考答案

function include(url) {
    var s = document.createElement('script');
    s.src = url;
    document.getElementsByTagName('head')[0].appendChild(s);
}

3.事件
创建一个叫做myevent的跨浏览器事件工具集(或对象集),其中应该包括以下方法。
1)addListener(element,event_name,callback)—其中element参数也可以是一个元素数组。
2)removeListener(element,event_name,callback)。
3)getEvent (event)—对于IE的早起版本,我们可以通过检查window.event属性来实现。
4)getTarget(event)。
5)stopPropagation(event)。
6)preventDefault(event)。
其用法如下:
function myCallback(e){
e=myevent.getEvent(e);
alert(myevent.getTarget(e).href);
myevent.stopPropagation(e);
myevent.preventDefault(e);
}
myevent.addListener(document.links,”click”,myCallback);
执行这段示例代码应该会使该文档中所有的连接失效,只不过,它们在被单击时会弹出一个alert()窗口,以显示其href属性。
创建一个以像素定位的div元素,坐标为x=100px,y=100px。然后编写代码使div元素能按照以下按键J(左)、K(右)、M(下)、I(上)或对应方向键的操作方式在页面中移动。并且,在编写过程中可以重用您刚刚实现的事件工具集。

答:下面就是这本书上原来的答案
工具集

var myevent = (function() {
    // wrap some private stuff in a closure
    var add, remove, toStr = Object.prototype.toString;
    // helper
    function toArray(a) {
        // already an array
        if (toStr.call(a) === '[object Array]') {
            return a;
        }

        // duck-typing HTML collections, arguments etc
        var result, i, len;
        if ('length' in a) {
            for (result = [], i = 0, len = a.length; i < len; i++) {
                result[i] = a[i];
            }
            return result;
        }
        // primitives and non-array-like objects
        // become the first and single array element
        return [a];
    }
    // define add() and remove() depending
    // on the browser's capabilities
    if (document.addEventListener) {
        add = function(node, ev, cb) {
            node.addEventListener(ev, cb, false);
        };
        remove = function(node, ev, cb) {
            node.removeEventListener(ev, cb, false);
        };
    } else if (document.attachEvent) {
        add = function(node, ev, cb) {
            node.attachEvent('on' + ev, cb);
        };
        remove = function(node, ev, cb) {
            node.detachEvent('on' + ev, cb);
        };
    } else {
        add = function(node, ev, cb) {
            node['on' + ev] = cb;
        };
        remove = function(node, ev) {
            node['on' + ev] = null;
        };
    }
    // public API
    return {
        addListener: function(element, event_name, callback) {
            // element could also be an array of elements
            element = toArray(element);
            for (var i = 0; i < element.length; i++) {
                add(element[i], event_name, callback);
            }
        },
        removeListener: function(element, event_name, callback) {
            // same as add(), only practicing a different loop
            var i = 0,
                els = toArray(element),
                len = els.length;
            for (; i < len; i++) {
                remove(els[i], event_name, callback);
            }
        },
        getEvent: function(event) {
            return event || window.event;
        },
        getTarget: function(event) {
            var e = this.getEvent(event);
            return e.target || e.srcElement;
        },
        stopPropagation: function(event) {
            var e = this.getEvent(event);
            if (e.stopPropagation) {
                e.stopPropagation();
            } else {
                e.cancelBubble = true;
            }
        },
        preventDefault: function(event) {
            var e = this.getEvent(event);
            if (e.preventDefault) {
                e.preventDefault();
            } else {
                e.returnValue = false;
            }
        }
    };
}());

移动div

// add a div to the bottom of the page
var div = document.createElement('div');
div.style.cssText = 'width: 100px; height: 100px; background: red; 
position: absolute;
';
document.body.appendChild(div);
// remember coordinates
var x = div.offsetLeft;
var y = div.offsetTop;
myevent.addListener(document.body, 'keydown', function(e) {
    // prevent scrolling
    myevent.preventDefault(e);
    switch (e.keyCode) {
        case 37: // left
            x--;
            break;
        case 38: // up
            y--;
            break;
        case 39: // right
            x++;
            break;
        case 40: // down
            y++;
            break;
        default:
            // not interested
    }
    // move
    div.style.left = x + 'px';
    div.style.top = y + 'px';
});

4.XMLHTTPRequest对象
创建一个名为ajax的XHR工具集(或对象集),其示例用法如下:
function myCallback(xhr){
alert(xhr.responseText);
}
ajax.request(“somefile.txt”,”get”,myCallback);
ajax.request(“script.php”,”post”,myCallback,”first=John&last=Smith”);
答: 书上自带答案

var ajax = {
    getXHR: function() {
        var ids = ['MSXML2.XMLHTTP.3.0',
            'MSXML2.XMLHTTP',
            'Microsoft.XMLHTTP'
        ];
        var xhr;
        if (typeof XMLHttpRequest === 'function') {
            xhr = new XMLHttpRequest();
        } else {
            // IE: try to find an ActiveX object to use
            for (var i = 0; i < ids.length; i++) {
                try {
                    xhr = new ActiveXObject(ids[i]);
                    break;
                } catch (e) {}
            }
        }
        return xhr;
    },
    request: function(url, method, cb, post_body) {
        var xhr = this.getXHR();
        xhr.onreadystatechange = (function(myxhr) {
            return function() {
                if (myxhr.readyState === 4 && myxhr.status === 200) {
                    cb(myxhr);
                }
            };
        }(xhr));
        xhr.open(method.toUpperCase(), url, true);
        xhr.send(post_body || '');
    }
};

以上就是javascript面向对象编程的所有练习题,最后附上本书自带的标注答案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值