代码之家  ›  专栏  ›  技术社区  ›  AlexV

在某些浏览器中,会忽略“return false”,以便使用javascript将链接动态添加到DOM中。

  •  5
  • AlexV  · 技术社区  · 15 年前

    我动态地将<A>(链接)标记添加到DOM,方法是:

    var link = document.createElement('a');
    link.href = 'http://www.google.com/';
    link.onclick = function () { window.open(this.href); return false; };
    link.appendChild(document.createTextNode('Google'));
    //someDomNode.appendChild(link);
    

    我希望链接在新窗口中打开(我知道这很糟糕,但这是必需的)。我还尝试使用“target”属性,但是我在这个解决方案中也有错误的行为。

    我的代码在IE和火狐中运行良好,但是 返回假 不要在狩猎、铬合金和歌剧中工作。我说的“不工作”是指在新窗口打开后,链接被跟踪。

    我想我可能是因为谷歌地图v3环境…

    编辑: 要查看实际页面上的行为:

    1. http://tinyurl.com/29q6nw6
    2. 单击地图上的任何标记,将显示一个气球。
    3. 单击气球中的标题,链接将在新窗口中打开(在IE和FF中工作,但在Safari、Chrome和Opera中不工作)。

    欢迎任何帮助!

    编辑2: 问题出在函数“makeinfoWindowContent”中,该函数位于“gmaps3.js”中。我不使用dom来创建元素(我使用string),因为这个html字符串必须传递给google maps(对于信息窗口-气球)。实际上,相同的链接是在两个不同的地方创建的。左边的一个是用dom函数创建的(如本问题所示),它在所有浏览器中都有效,气球中的一个是用html字符串创建的,这个函数在Safari、Chrome和Opera中都不起作用(新窗口打开后,即使返回false,也会跟踪链接)。

    编辑3: 仍然不知道为什么会这样…如果有人有主意,告诉我!

    11 回复  |  直到 15 年前
        1
  •  3
  •   nikc.org    15 年前

    是否可以阻止事件的默认操作?不确定gmap是否以其他方式处理信息窗口中的链接,如果不是,它应该可以工作。

    更新:第一个示例不起作用。使用“inline”onclick分配事件时未传递事件。这是 tested and found to be working .

    function bindEvent(target, event, handler) {
        if (typeof target.addEventListener != 'undefined') {      
            target.addEventListener(event, handler, false);
        } else if (typeof target.attachEvent != 'undefined') {
            target.attachEvent('on' + event, handler); 
        } 
    }
    
    var link = document.createElement('a');
    link.href = 'http://www.google.com/';
    link.appendChild(document.createTextNode('Google'));
    
    bindEvent(link, 'click', function (e) { 
        if (typeof e.preventDefault != 'undefined') {
            // Common/W3C events
            e.preventDefault();
        } 
    
        // (Old) IE specific events
        e.returnValue = false; 
    
        var target = e.target || e.srcElement;
        window.open(target.href); 
    
        return false; 
    });
    
    document.getElementsByTagName('body')[0].appendChild(link);
    
        2
  •  3
  •   Josh Stodola    15 年前

    设置 href 'javascript:void(0);' 而不是引用 this.href 在onclick处理程序中,改为在那里硬编码URL。

        3
  •  1
  •   Morfildur    15 年前

    问题可能是在返回false之前取消javascript执行的脚本错误。在这种情况下,通常遵循链接。检查是否使用特定于浏览器的方法/属性,并检查是否存在javascript错误。

    我不能检查你的脚本,因为它似乎没有可用的ATM。

        4
  •  1
  •   petraszd    15 年前

    很少想法

    • Google地图在打开弹出窗口之前以某种方式重新复制(只是猜测)HTML内容,并留下JS事件。打开gmap弹出窗口后,可以尝试附加事件侦听器。

    • 在里面 function MakeInfoWindowContent() 代码通过具体化字符串来构造事件——也许您也应该尝试一下。

    • 最后(和愚蠢的)建议:尝试使用 addEventListener 而不是直接附加事件。

        5
  •  0
  •   Tim Down    15 年前

    如何避免使用脚本打开窗口?

    var link = document.createElement('a');
    link.href = 'http://www.google.com/';
    link.target = '_blank';
    link.appendChild(document.createTextNode('Google'));
    
        6
  •  0
  •   artlung    15 年前
    var link = document.createElement('A');
    link.setAttribute('href', 'http://www.google.com/');
    link.setAttribute('onclick', 'window.open(this.href, "_blank");return false;');
    link.appendChild(document.createTextNode('Google'));
    
        7
  •  0
  •   Codekie    15 年前

    试试这个:

    link.onclick = function(event) {
        window.open(this.href);
        if (event.stopPropagation)
            event.stopPropagation();
        return false;
    };
    

    我通过chrome开发工具直接修改了DOM,它对我很有用。

        8
  •  0
  •   Casey Chu    15 年前

    实际上,您并不是“动态地向DOM添加链接标记”。您的代码只是连接HTML字符串。取代你 MakeInfoWindowContent 函数(在gmaps3.js中),使用本机DOM方法。

    function MakeInfoWindowContent(name, institutionName, description, address, url) {
        var result = document.createElement('div');
        result.className = 'infoBulle';
        // etc.
        return result;
    }
    
        9
  •  0
  •   David Murdoch    15 年前

    尝试使用jquery的事件委托:

    function initialize(){
        // ... code ...
    
            $("#resultMap").delegate("a.myLink").click(function(){
                window.open(this.href, "myWindow");
                return false;
            });
            Search();
    
        // ... more code ...
     }
    
    
    function MakeInfoWindowContent(name, instituteName, description, address, url)
    {
        var result = '<div class="infoBulle">';
        if (url != '')
            result += '    <h3><a href="' + url + '" class="myLink">' + instituteName + '</a></h3>';
        else
            result += '    <h3>' + instituteName + '</h3>';
        if (Trim(description) != '')
            result += '    <p>' + description + '</p>';
        result += '    <p>' + address + '</p>';
        result += '</div>';
        return result;
    }
    
        10
  •  0
  •   Andrew    15 年前

    @你必须保持在线onclick事件原子化。有两个简单的解决方案:将整个操作包装在一个自执行函数中,或者移动 window.open() return false 其自身功能:

    选择之一

    使用自执行匿名函数。

    result += '    <h3><a href="' + url + '" onclick="(function(){window.open(' + url + '); return false;})()">' + instituteName + '</a></h3>' + "\n";
    

    选择二

    将代码移动到它自己的函数中:

    function openCustomWindow(url) {
        window.open(url);
        return false;
    }
    

    …并改为调用该函数:

    result += '    <h3><a href="' + url + '" onclick="openCustomWindow(' + url + ')">' + instituteName + '</a></h3>' + "\n";
    

    [编辑]很抱歉。我完全错过了这个。您仍然应该执行上面两个方法中的一个(只有函数可以 返回假 ,不是声明)。这里的问题实际上是 this 从函数更改为实际的onclick。在onclick中执行时, window 不是事件。因为没有 window.href ,指示 window.open(undefined) 失败。因为失败了, <a> 标签开始了。我想指定URL两次(在 <a href> 又一次在 打开() 应该修复它。

        11
  •  0
  •   Andrea Zilio    15 年前

    我已经测试过这个解决方案,它工作了!

    我建议你采取一种不同的方法,但在我看来,更简单更干净:使用jquery.live事件(我看到你已经使用了jquery,所以这样做应该没有问题)!

    您只需要两个小改动:

    第一次改变 :

    更改第3行 MakeInfoWindowContent 函数以这种方式创建链接(它只删除onclick属性并添加一个类以清晰显示):

    result += '<h3><a class="marker_link" href="' + url + '">' + instituteName + '</a></h3>' + "\n";
    

    二次变化 :

    无论您想在何处(例如在dom加载或创建映射之前)执行此操作:

    $('div#resultMap a.marker_link').live('click', function(e) {
        window.open(this.href);
        e.preventDefault();
    });
    

    终点 :)

    这可以在文档的冒泡阶段拦截单击事件。我已经尝试过了,它甚至可以和谷歌Chrome一起使用。