JavaScript removeAttribute在IE中不适用于href和onclick值

时间:2014-11-25 20:15:13

标签: javascript html internet-explorer dom

我正在制作一个在线降临日历,你只能打开当天的大门。所有的门都使用JavaScript onclick来显示报价,例如'door10'......

<a href="javascript:void(0)" onclick = "document.getElementById('door10').style.display='block';document.getElementById('fade10').style.display='block'" id="door-10-link">

它们都是通过这个onclick创建的,然后在HTML的末尾运行以下JavaScript函数,它删除了今天没有的门的href和onclick属性,从而删除了打开它们的能力。

function disableDoor(num) {
var today = new Date();
var day = today.getDate();
var calendar_day = num;
if (calendar_day == day) {          
} else {
    var string = "door-" + num + "-link";
    var d = document.getElementById(string);
    d.removeAttribute("href");
    d.removeAttribute("onclick");
}

除了Internet Explorer之外,这一切都可以正常工作,即使它们不应该是可以点击的。光标不会更改为悬停光标,如果您检查元素的href和onclick值已被正确删除,但即使没有声明href,您仍然可以“打开门”。 HTML现在看起来像这样,正确删除了属性......

<a id="door-10-link">

在IE检查器中,如果我'编辑为HTML',请不要更改任何内容,单击外部完成编辑并刷新页面一切正常,我无法点击我不应该的门。 href元素已从页面中正确删除。

在JavaScript运行之后,似乎页面上的元素需要刷新。我猜这可能与DOM有关,但我对这个领域很新。

任何帮助都会很精彩,因为它让我感到难过。

提前致谢

3 个答案:

答案 0 :(得分:1)

这似乎是Internet Explorer 11中的回归;我检查了Internet Explorer 9和10,这两个都不会重现问题。我已在内部提交了一个错误,让我们的团队尽快解决问题。如果您愿意,可以查看前进http://remote.modern.ie。我构建了a small fiddle来证明问题。

通过这个特定的项目,我实际上鼓励你采取替代路线并站出一个事件监听器,而不是有条不紊地拆除几十个已有的听众。作为我的意思的一个简单示例,请考虑以下内容:

(function () {

    "use strict";

    var day = (new Date).getDate(),
        doors = document.querySelectorAll( "div" );

    doors.item( --day ).addEventListener( "click", function openDoor () {
        this.classList.toggle( "open" );
    });

}());

在上面,只有今天的门将被解锁 - 所有其他门将保持锁定状态。您可以在http://jsfiddle.net/jonathansampson/n4ed6uw5/在线查看实际演示。

我希望这种解决方法有所帮助;与此同时,我将与我的团队一起解决回归问题。

答案 1 :(得分:0)

尝试设置d.onclick = null以禁用onclick处理程序。

答案 2 :(得分:0)

你可以用jQuery做到这一点。您可以将单击处理程序附加到元素,每个单击处理程序都会检查是否允许打开它。

我正在使用JSON时间服务器,因为如果你使用客户端时间,它可以很容易地修改,每扇门都可以打开。

请检查以下代码。如果你更喜欢jsFiddle,你可以找到相同的代码here。它正在做你打算做的事情。只需添加一个popover而不是警告来显示优惠并应用您的样式。

我使用MetroUI CSS来做瓷砖样式。

要添加商品,您必须修改以下JSON

var offers = [
    {
        'day': 1,
        'offer': 'something for day'
    },
    {
        'day': 2,
        'offer': 'A 2GB USB Stick'
    }, 
    ...
];

并添加所有24天,并在评论&#39;深度复制提示后删除这三行。然后,您可以使用商品JSON的索引将数据附加到DOM元素。

还有一点需要改进。如果时间服务器花费的时间太长,您可以单击另一个元素,两个元素都会弹出。 阻止其他点击和/或加载进度条会有所帮助。

&#13;
&#13;
var adventCalendar = (function () {
    var MONTH = 10; //10 = November / 11 = December --> set to November for testing
    var LAST_DAY = 30; // later 24 --> 30 just for testing
    
    function Calendar() {
        //console.log('constructor called');
        this.init();
    };
    var offers = [{
        'day': 1,
            'offer': 'something for day'
    }];
    // later you would have for each day a different offer.

    Calendar.prototype.init = function () {
        var offers24days;
        var $calendar = $('#adventCalendar');

        for (var i = 1; i <= LAST_DAY; i++) {
            // console.log(i);
            // deep copy of offer
            var newObject = jQuery.extend(true, {}, offers[0]);
            newObject.day = i;
            newObject.offer += ' ' + i;
            
            $door = $('<div class="tile rounded"/>')
                .text(i)
                .data(newObject)
                .appendTo($calendar);

            var that = this; // store reference to this Calendar
            $door.on('click', function () {
                var today = new Date();
                var $this = $(this);
                that.getTime('GMT', function (date) {
                    // This is where you do whatever you want with the time:
                    //console.log(date.getDate());
                    var data = $this.data(); // today from time server
                    
                    if ((data.day <= date.getDate()) && (date.getMonth() == MONTH)) {
                        // Attention! Date month starts at 0 --> 0 = Januar & 10 = November
                        // open allowed
                        alert(data.offer); // later you can use a popover instead of an alert. This is just for the demo.
                    } else {
                        //alert('not allowed'); // just for testing
                    }
                });
            });
        }
    }

    // get time from this SO question http://stackoverflow.com/questions/9486293/does-anyone-know-of-a-good-json-time-server
    // zone not used because time server doesn't support it
    Calendar.prototype.getTime = function (zone, success) {
        //var url = 'http://json-time.appspot.com/time.json?tz=' + zone,
        var url = 'http://time.jsontest.com/?', // no zone support other link is broken
            ud = 'json' + (+new Date());
        window[ud] = function (o) {
            success && success(new Date(o.milliseconds_since_epoch)); //o.datetime));
        };
        document.getElementsByTagName('head')[0].appendChild((function () {
            var s = document.createElement('script');
            s.type = 'text/javascript';
            s.src = url + 'callback=' + ud;
            return s;
        })());
    }

    return {
        Calendar: Calendar
    };
})();

$(function () {
    var advent = new adventCalendar.Calendar();
});
&#13;
.tile {
    font-family: sans-serif;
    font-size: 4em;
    color: #E2E1E6;
}
&#13;
<script src="http://cdn.jsdelivr.net/metro-ui-css/2.0.23/min/metro.min.js"></script>
<link href="http://cdn.jsdelivr.net/metro-ui-css/2.0.23/min/metro-responsive.min.css" rel="stylesheet"/>
<link href="http://cdn.jsdelivr.net/metro-ui-css/2.0.23/min/metro-bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
    <div id="adventCalendar" class="metro grid fluid"></div>
</div>
&#13;
&#13;
&#13;