如何从父元素触发href单击事件

时间:2017-09-24 09:46:16

标签: javascript jquery

使用以下代码,我尝试点击父a标记中的li代码点击事件。但它给了我这个错误:

为什么我要这样做:

当我点击 PHP PDO 链接时,我们需要将光标移入该文本而不是li标记。我试图用它修复它。但我知道我们可以通过获取href属性并将其设置为li,从a href点击事件中调用window.location.href。但是,当我点击a href代码时,仍然会尝试触发li点击事件。

HTML

<li class="tags" style="cursor: pointer;">
    <a class="link_em" href="?l=1" id="1">List1</a>
</li>

Jquery的:

$('li.tags').on('click', function (e) {
    $(this).children('a').click();
    return false;
});

错误:

当我使用上面的代码时出现此错误。

 Uncaught RangeError: Maximum call stack size exceeded

UI:

enter image description here

https://jsfiddle.net/k92dep45/

编辑:

  

我做了这个丑陋的事情,但我仍然在寻找合适的解决方案:

$('li.tags a').on('click', function (e) {
   e.stopPropagation();
});
$('li.tags').on('click', function (e) {
  window.location.href = $(this).children('a.link_em').attr('href');
  e.preventDefault();
});

4 个答案:

答案 0 :(得分:1)

您可以使用以下版本获取上述代码

$('li.tags').on('click', 'a', function (e) {
// Do your stuff.
e.preventDefault();
   window.location.href= thishref;
});

这里的第二个论点是孩子们&#39; a&#39;在jQuery的click事件中。

问题是你一直在调用导致Maximum call stack size exceeded的相同元素。

请看下面的例子。

function foo(){
   foo();
}

foo();

在上面的代码中,我们一次又一次地调用foo(),它也会产生相同的结果。

答案 1 :(得分:1)

您可以通过将href的{​​{1}}更改为window标记中存储的href,然后使用此说明获取,来执行此操作:

a

尝试实施或运行以下代码段以确认其是否可以解决您的问题&amp;得到预期的渲染:

$(this).children('a').attr("href");
$('li.tags').on('click', function (e) {
    window.location.href= $(this).children('a').attr("href");
    return false;
});

答案 2 :(得分:1)

您需要在event.stopPropagation()元素上添加a并防止事件“冒泡”,否则您会创建无限循环,这就是您收到该错误的原因。

$('li.tags').on('click', function() {
  $(this).children('a').click();
});


$('li.tags a').click(function(e) {
  e.stopPropagation()
  e.preventDefault() // This is just for demo
  console.log($(this).text())
})
a {
  border: 1px solid black;
}
li {
  padding: 50px;
  border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
  <li class="tags" style="cursor: pointer;">
    <a class="link_em" href="?l=1" id="1">List1</a>
  </li>
</ul>

答案 3 :(得分:1)

修改

在重新阅读这个问题后,我认为OP已经过了复杂的事情(显然我也是如此)。添加了一个简单版本的Demo 1,标记为Demo 2.并添加了Demo 3,这是一种不使用JavaScript / jQuery的解决方案。

捕获阶段

当您需要对事件链进行细粒度控制时.addEventListener()更适合处理特定方面,例如在捕获阶段而不是冒泡阶段触发事件。原因是因为li.tag将在事件链的第一阶段(即捕获阶段)之前a.link之前。我们通过为第三个参数指定适当的布尔值来指定捕获或冒泡阶段:

document.addEventListener('click', function(e) {...}, false);

这是默认值,对于冒泡阶段设置为false

document.addEventListener('click', function(e) {...}, true);

这将使注册对象(例如本例中的document)监听并执行捕获阶段。 以下演示 - 在捕获阶段 - 将:

  1. 将点击的li.tag指定为event.target ...
  2. ...然后调用e.stopPropagation(),以便嵌套在a.link中的li.tag不会包含在事件链中。冒泡阶段也被跳过。
  3. 相反,此a.link在新事件链上变为e.target,因为在其上调用了触发器方法.click()
  4. <小时/>

    测试

    List0的第3个链接测试a.link是否确实由.click()触发或在捕获或冒泡阶段触发,还是event.target。因为List0中的每个a.link都有pointer-events:none,这使a.link无视用户的任何鼠标或点击事件,我们可以得出结论:

    1. 所述a.link的任何激活完全取决于用户点击其父li.tag

    2. 在捕获阶段,由于a.linke.stopPropagation() pointer-events:none不能点击e.target,因此a.link无法点击事件。

    3. 由于e.stopPropagation()

    4. 冒泡阶段甚至不适用于.click()

    5. 当事件链死亡a.link被解雇,Target: LI像第二阶段火箭一样消失

    6. 点击第3个列表项的任意位置时,我们会得到以下结果:

      • 日志:LinkID: {0-1 or 0-2}
      • 不跳转到List2

      单击List0的第一个或第二个列表项时,我们得到以下结果:

      • 日志:Target: A
      • 日志:Target: LI
      • 日志:<ui>
      • 跳转到List1或List2

      <小时/>

      错误

      在小提琴中,有2个无效HTML实例:

      错误1:<ul>

      正确:<a>

      错误2:所有 <a class="link_em" href="?l=1" id="1">List1</a> <a class="link_em" href="?l=2" id="1">List2</a> 具有相同的ID,所有ID必须是唯一的

         <a href='#l1-1' class='link' id='0-1'></a>
      
         <a href='#l1-2' class='link' id='0-2'></a>
      

      正确:

      document.addEventListener('click', function(e) {
        if (e.target.className === 'tag') {
          e.stopPropagation();
          var link = e.target.querySelector('a');
          console.log('ID: ' + link.id);
          link.click();
          console.log('Target: ' + e.target.tagName);
          return false;
        } else {
          console.log('Target: ' + e.target.tagName);
          return false;
        }
      }, true);

      您会注意到HTML中的类和ID略有不同,但只要您注意上述错误,就可以更改回自己的类。

      <小时/>

      演示1

      &#13;
      &#13;
      ul {
        height: 90px;
        outline: 1px solid red;
      }
      
      li {
        height: 30px;
        outline: 1px solid blue;
        cursor: pointer
      }
      
      .link {
        display: block;
        width: 10px;
        height: 10px;
        background: red;
        pointer-events: none;
        cursor: default;
        position: relative;
        z-index: 1;
      }
      
      b {
        float: left;
      }
      
      hr {
        margin-bottom: 1500px
      }
      
      .as-console {
        position: fixed;
        bottom: 30px;
        right: 0;
        max-width: 150px;
        color: blue;
      }
      
      .top {
        width: 100px;
        pointer-events: auto;
      }
      &#13;
      <h1>Capture Phase Demo</h1>
      <details>
        <summary>Test</summary>
        <p>Third list item is not a .tag.</p>
        <dl>
          <dt>Results:</dt>
          <dd>Logged: "Target: LI"(or "Target: "B")</dd>
          <dd>Did not log: "ID:0-2"</dd>
          <dd>Did not jump to List2</dd>
      
          <dt>Conclusion:</dt>
          <dd>Links on List0 do not respond to mouse or click events from user. Therefore in order to jump from List0 the link must be triggered programmatically.</dd>
        </dl>
      </details>
      
      <h2 id='l1-0'>List0</h2>
      <ul>
        <li class='tag'>
          <a href='#l1-1' class='link' id='0-1'>List1</a>
        </li>
        <li class='tag'>
          <a href='#l1-2' class='link' id='0-2'>List2</a>
        </li>
        <li>
          <a href='#l1-2' class='link' id='0-2'>Test</a>
        </li>
      </ul>
      <b>1500px to List1 </b>
      <hr>
      <h2 id='l1-1'>List1</h2>
      <ul>
        <li><a class='top' href='#l1-0'>Back to Top</a></li>
        <li>Item</li>
      </ul>
      
      <b>1500px to List2 </b>
      <hr>
      <h2 id='l1-2'>List2</h2>
      <ul>
        <li>
          <a class='top' href='#l1-0'>Back to Top</a>
        </li>
        <li>Item</li>
      </ul>
      &#13;
      document.addEventListener('click', function(e) {
        if (e.target.className === 'tag') {
          e.stopPropagation();
          e.target.querySelector('a').click();
        }
      }, true);
      &#13;
      &#13;
      &#13;

      演示2

      &#13;
      &#13;
      ul {
        height: 100px;
        outline: 1px solid red
      }
      
      li {
        height: 100%;
        cursor:pointer;
      }
      &#13;
      <h1 id='list0'>List0</h1>
      <ul>
        <li class='tag'>
          <a href='#list1'>List1</a>
        </li>
      </ul>
      <hr>
      <h1 id='list1'>List1</h1>
      <ul>
        <li class='tag'>
          <a href='#list0'>List0</a>
        </li>
      &#13;
      ul {
        height: 100px;
        outline: 1px solid blue
      }
      
      li {
        height: 100%;
        padding: 0
      }
      
      a {
        display: block;
        height: 100%;
        width: 100%;
      }
      &#13;
      &#13;
      &#13;

      演示3

      &#13;
      &#13;
      <h1 id='list0'>List0
        <h1>
          <ul>
            <li>
              <a href='#list1'>List1</a>
            </li>
          </ul>
          <hr>
          <h1 id='list1'>List1
            <h1>
              <ul>
                <li>
                  <a href='#list0'>List0</a>
                </li>
              </ul>
      &#13;
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "C:\Anaconda\lib\site-packages\wmi.py", line 88, in <module>
          from win32com.client import GetObject, Dispatch
        File "C:\Anaconda\lib\site-packages\win32com\client\__init__.py", line 11, in <module>
          from . import gencache
        File "C:\Anaconda\lib\site-packages\win32com\client\gencache.py", line 666, in <module>
          __init__()
        File "C:\Anaconda\lib\site-packages\win32com\client\gencache.py", line 62, in __init__
          Rebuild()
        File "C:\Anaconda\lib\site-packages\win32com\client\gencache.py", line 653, in Rebuild
          _SaveDicts()
        File "C:\Anaconda\lib\site-packages\win32com\client\gencache.py", line 69, in _SaveDicts
          f = open(os.path.join(GetGeneratePath(), "dicts.dat"), "wb")
        File "C:\Anaconda\lib\site-packages\win32com\client\gencache.py", line 145, in GetGeneratePath
          f = open(fname,"w")
      FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\KEVINE~1\\AppData\\Local\\Temp\\gen_py\\3.6\\__init__.py'
      
      &#13;
      &#13;
      &#13;