• ie6下a标签的void(0)引发的诡异问题 带来的思考


    既然是诡异问题,那么就先上代码,什么都不说。 

     1 <HTML>
     2
      <HEAD>
     3   <TITLE>1.html </TITLE>
     4  </HEAD>
     5 
     6  <BODY>
     7   <href="javascript:void(0)" onclick="loadiframe()">点我咯</a>
     8   <script>
     9       var loadiframe = function(){
    10            var myi=document.createElement("iframe");
    11            myi.src="2.html";
    12            document.body.appendChild(myi);
    13       }
    14 
    15   </script>
    16  </BODY>
    17 </HTML>

    上面代码保存为1.html   

     1 <HTML>
     2    <HEAD>
     3   <TITLE> 2.html </TITLE>
     4  </HEAD>
     5 
     6  <BODY>
     7     这里是第2.html
     8     <script>
     9         window.location.href="http://litao229.cnblogs.com"
    10     </script>
    11  </BODY>
    12 </HTML>
    13 

     上面 代码保存为2.html

      好了,你看,这代码写的多漂亮,看不到有任何的诡异之处,别纳闷了,打开你的ie6,记的,是ie6,然后运行1.html,点里面的莲接,点开等待你的诡异之门

      看到了么,除了在1.html里面动态加载了一个空白的iframe 之外, 什么都没有。首先,单从语法和词法角度上来看这两个简单的要命的page和这几行简单的要命的代码,理论上来说是应该没什么问题的。那么为什么会有如此诡异的事情发生 ?????

      ps:当然,该诡异现象仅出现在ie6上,其他标准浏览器和ie7,ie8等都没有,ie6真是个妖孽!!!!!!!!!!

      我开始是一直不得其解,然后,在一同事的点破下 定位发现是 href  中的 代码  和 window.location.href 的一些相干的冲突导致问题 

      解决方案: 
      1,1.html中 把href 去掉

      2,1.html 中修改为 href="#"

      3,  1.html 中修改为  onclick="loadiframe();return false"

      最后的解决方案,替换标签,把1.html 中的<a>换为 <span>  <div> 等语意不是很强的标签

      

      问题成因深度分析 :

      为什么会发生这个问题呢?我们来看看javascript:void(0) :

    JavaScript中void是一个操作符,该操作符指定要计算一个表达式但是不返回值。

    void 操作符用法格式如下:
        1. javascript:void (expression)
        2. javascript:void expression

    expression 是一个要计算的 JavaScript 标准的表达式。表达式外侧的圆括号是可选的,但是写上去是一个好习惯。 (实现版本 Navigator 3.0 )

    你可以使用 void 操作符指定超级链接。表达式会被计算但是不会在当前文档处装入任何内容。

    下面的代码创建了一个超级链接,当用户点击以后不会发生任何事。当用户点击链接时,void(0) 计算为 0,但在 JavaScript 上没有任何效果。

        <A HREF=”javascript:void(0)”>单击此处什么也不会发生</A>

    下面的代码创建了一个超级链接,用户单击时会提交表单。

        <A HREF=”javascript:void(document.form.submit())”>单击此处提交表单</A>

        于是我们知道了,产生这样的结果是因为,IE6,会在执行完onclick代码再执行href里的内容,而在href里使用javascript:void(0);或javascript:;将使得执行跳转的那段代码失效。 

       

      此问题引申的思考 

    首先, 我们知道了是javascript:void(0)搞的鬼,而javascript:void(0)  可以不写么。不行,因为要屏蔽a的href的跳转默认事件,因为这是个ajax的操作。

    于是,我想到了另外个问题,就是这里一定要用a标签么。做页面的时候,很多的时候都用a标签display:block后来代替button等,这么做是否合适??

    同样在在javaeye.com看见这个话题,讨论挺有意思 

    下面的讨论源自 “射雕” 的blog,大致如下 

    a标签语义思考

    首先,链接a和按钮button是有语义的,不能因为使用上的方便而替换。a是anchor的缩写,是一个锚点,用来导航或定位。典型用法为:

    <a href="http://www.w3c.org/">W3C Web Site</a>
    <a name="anchor-one">This is the location of anchor one.</a>
    <a href="#anchor-one">Link to anchor one</a>

    还可以同时指定name和href属性,这是基础知识,若有疑问请参考HTML 4.01规范

    再说按钮(包括 button 和 <input type=”button/submit” />)。从语义上讲,按钮是表单的一部分,触发的动作和表单是有关联的。如果根本就没有表单操作,就不应该使用按钮。举些例子:

    上图是一些链接,虽然长得像button,但语义上是a.

    上图中的显示和排序按钮,是操作表单。从语义上讲,用button或input更合适。(注意:淘宝搜索结果页目前采用的是a, 这是出于渐进增强的考虑,下面会提及)

    总之链接和按钮有各自的语义和使用场景,不能随意替换使用。 

    写法分析

    世界永远没那么简单,在当今JavaScript如日中天的Web世界里,链接a经常用来触发js事件:

    <a href="" onclick="something()">test 1</a>
    <a href="#" onclick="something();return false">>test 2</a>
    <a href="javascript: void(0)" onclick="something()">>test 3</a>
    <a href="javascript: void something()">test 4</a>

    首先,第一种写法在ie下是有问题的,原因是 ie下会自动补全href.

    第二种写法直接在onclick事件中阻止掉默认事件,因此href="#"中的#实际上可以为任意值。用#,是考虑没有js时,点击后停留在本页(注意:当a在一屏以下时,这种写法会导致页面回滚到顶部)。

    第三种写法,href值是一个javascript伪协议,void是javascript的一个一元操作符(比如!, typeof)。void操作符的作用是,只执行后面的表达式,不返回任何值。看起来好像是void(0)阻止了默认事件,实际上,下面这些写法都没问题:

    <a href="javascript: void(1)" onclick="something()">>test 3</a>
    <a href="javascript:;" onclick="something()">>test 3</a>
    <a href="javascript:" onclick="something()">>test 3</a>
    <a href="javascript: return true" onclick="something()">>test 3</a>

    因为a的默认操作就是javascript伪协议的内容,里面加不加void都不会触发其它事件。(注意:Opera下,当伪协议里有返回值时,会改变href, 因此我们一般写void(0)或空语句)

    理解了第三种写法,第四种写法也就明白了:href="javascript: void something()". 这种写法有一个“好处”是,鼠标悬浮时,用户可以通过状态栏看到将要执行的函数。对开发者来说,这或许是个好处,但对普通用户来说,这真的会增加信赖感吗?抑或是恐惧感?没有数据,无法下结论。

    除了上面的写法,还有一种推荐的写法是,通过class或id给a增加一个hook,然后在js里通过hook来添加事件。 

    反思

    我不想去讨论上面的各种写法中哪一个是最好的。让我们思考本源问题:为什么我们会用a来触发js事件?我能想到的理由有:

    1. 这样自动就拥有鼠标的悬浮样式了
    2. 大家都这么写
    3. 还真想不出啥理由,这不是很自然的事嘛
    4. 因为IE6只支持css样式的a:hover,而且href还不能为空

    可以看出,除了悬浮样式,找不到啥实质性的理由了。我们暂时抛开样式问题,来看一个例子:

    上面是Google Reader的操作栏,感兴趣的不妨firebug一下,采用的标记是:

    鼠标的悬浮样式,也根本不是问题:

    css里,加上cursor: pointer就行。

    从上面的例子中,我们可以得到一个结论:如果仅仅是触发js动作,没有任何导航或定位的语义,采用span或其它合适的标签即可,没必要错误的使用a(用a反而惹麻烦:一是要去除默认事件,二是状态栏的信息会让普通用户迷惑甚至恐惧)。

    当然,如果本身就是一个链接,仅仅想在导航前增加一些js逻辑,或者是表单排序等应用,从渐进增强角度考虑,最好的实践是将href值写全,以使得在不支持js的浏览器下,也能保证可用性。

    最后  我的观点:

  • 用链接a,还是用按钮button,根据具体使用场景来定,button是和表单相关的元素
  • 不要滥用a,当你都想不明白href值是什么时(不要出现javascript伪协议,不要孤独寂寞的#),请选用其它标签,通过hook在js中添加事件
  • 如果确实是一个链接,同时又有onclick事件,请想想渐进增强,保证href值的完整性
  • 相关阅读:
    通过精灵图片序列单元制作Html+CSS3 动画
    App开发三种模式
    Matrix
    MySQL SQL
    Git和GitHub
    Web前端入门了解
    LayoutInflater和inflate()
    使用XML文件和Java代码控制UI界面
    Android Handler
    Android Gradle的使用
  • 原文地址:https://www.cnblogs.com/litao229/p/1509379.html
  • Copyright © 2020-2023  润新知