【问题标题】:Wrapping content elements causes inline scripts to fire包装内容元素会导致内联脚本触发
【发布时间】:2012-11-03 07:51:31
【问题描述】:

我正在编写一个 jQuery 插件。在这个插件中,我将现有的 BODY 内容包装在 DIV 中并隐藏它们。

var $originalBodyContents = $('body').wrapInner('<div>').children('div').hide();

插件然后将它自己的覆盖DIV 附加到BODY 上,这就是插件的魔力。当用户退出插件时,它会移除其覆盖层DIV,并展开它们。

$originalBodyContents.children().unwrap();

效果很好,您可以在此演示中看到:
http://jsfiddle.net/vKddB/1/

但是,如果页面上有内容脚本,那么它们都会在发生换行时重新加载并再次运行它们的代码。这会导致很多意外行为,您可以在此演示中看到:
http://jsfiddle.net/vKddB/3/

在上面的演示中,您会看到“显示警报”按钮显示“你好!”的警报。点击时。如果您触发插件并关闭插件,您会注意到“显示警报”按钮现在有两个与之关联的单击处理程序,因此在单击时会显示两个警报。

我的插件将无法控制它正在运行的页面的内容。当我将正文内容包装在 DIV 中时,有没有办法可以防止内联脚本重新运行?

【问题讨论】:

    标签: javascript jquery html events dom


    【解决方案1】:

    $('script', $('body')).remove(); 在您的代码之前

    【讨论】:

    • 如果脚本块包含在该页面上被调用的函数怎么办?我会从页面中删除它们。那会很糟糕。我只关心那些只希望在初始页面加载时运行一次的代码。
    • 对.. 但是由于脚本块已经加载,即使它被删除也不会产生任何影响?或者我们可以将它们移至&lt;head /&gt;
    • 您说得对。我说天才。我很震惊这个工作:jsfiddle.net/vKddB/6
    • 哈哈,谢谢,虽然我在原生 javascript 方面还不是很出色.. 喜欢 jQuery
    • 我拍了一个小视频,谢谢@atif089! youtube.com/watch?v=wGG7ptRKaJs
    【解决方案2】:

    如果您希望您的插件在任意页面上工作,您可能需要考虑另一种方法,即您的叠加层仅覆盖原始内容。我相信这会比包装和隐藏、移动/删除脚本节点等技巧更可靠。

    【讨论】:

    • 为简洁起见,我省略了详细信息,但问题是我不能使用固定定位,因为我们的插件在移动浏览器上完全中断(如果您想知道,这是一个报告查看器插件)。绝对定位效果很好,但用户可以滚动到覆盖层之外并查看底层的正文内容。经过多次试验和错误,我开始意识到,如果我们的插件在打开时拥有自己的主体会更好。
    【解决方案3】:

    我只是想分享我构建叠加层的方法,也许它会对某人有所帮助。 有点不同,div是在页面上添加的,并没有隐藏已有的div元素。可能会快一点,因为脚本不会搜索所有 div dom 元素。

    第一

    //create the overlay with
    $('<div class="overlay" />').appendTo('body').show();
    
    //close the overlay with
    $('.overlay').remove();
    
    //css used for overlay
    .overlay
    {
        background-color: #363636;
        background-image: url('a_nice_bg_image.png');
        width: 100%;
        height: 100%;
        position: fixed;
        top: 0;
        left: 0;
        display: none;
        z-index: 1000;
        opacity: .55;
        filter:alpha(opacity=55);
        -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=55)";
    }
    

    【讨论】:

    • 这是我们最初采用的方法,但我们遇到了position: fixed 和移动浏览器的大量问题。这就是为什么我们需要隐藏原来的 body 元素。
    【解决方案4】:

    将 div 附加到正文,将其位置设置为绝对,设置高 z-index 并调整其大小以覆盖整个内容。

            var $overlay = $('<div>')
            .css({
                position: 'absolute',
                top: 0,
                left: 0,
                width: $(document).width() + 'px',
                height: $(document).height() + 'px',
                backgroundColor: '#f00',
                'z-index': 10000
            })
            .appendTo('body');
    

    像这样(您的原始代码经过最少的修改):http://jsfiddle.net/Ya3DG/4/ :)

    【讨论】:

    • 这样的问题是,如果由于底层页面内容而导致文档很长,那么您会在叠加层中看到一堆空白区域,用户可以滚动浏览。我们的报表查看器应该留在视口内。
    猜你喜欢
    • 2016-05-16
    • 1970-01-01
    • 1970-01-01
    • 2012-01-30
    • 2013-04-06
    • 1970-01-01
    • 2015-03-18
    • 2015-12-24
    • 2021-08-22
    相关资源
    最近更新 更多