简体   繁体   English

在加载jQuery之前防止链接

[英]Preventing Links before jQuery is Loaded


How can i prevent links on click event before jQuery is loaded? 如何在加载jQuery之前阻止点击事件上的链接?
The reason is i have few links that make AJAX calls through jQuery ajax functions and if user click them before jQuery framework is loaded the browser cant trigger jQuery ajax function and will follow links href="..." Thanks. 原因是我有很少的链接通过jQuery ajax函数调用AJAX,如果用户在加载jQuery框架之前单击它们,浏览器无法触发jQuery ajax函数并将跟随链接href =“...”谢谢。

Edit: Can i use this? 编辑:我可以用这个吗?

<head>
...
  <script type="text/javascript">
   window.onload = prevCl();
   function prevCl() {
    var links = document.links[];
    links.onclick = check();
   }
   function check() {
    if (typeof jQuery == 'undefined') { 
     return false;
    }
   }
  </script>
</head>

Four options for you: 四种选择:

Option 0 选项0

Go read Sean Hogan's answer , he pointed out that this can be done with delegation ( doh! ) and I put together an example implementation. 去读Sean Hogan的答案 ,他指出这可以通过委托( doh! )完成,并且我将一个示例实现放在一起。

Option 1 选项1

You can make the href of the links "#" until jQuery is loaded, and then (if appropriate) change it to what it really should be. 您可以将链接的href设置为“#”,直到加载jQuery,然后(如果适用)将其更改为它应该是什么。 You can store what the href should be in a data- attribute, eg: 您可以存储href应该在data-属性中的内容,例如:

<a href='javascript:;' data-href='realtarget.html'>blah</a>

Then: 然后:

jQuery(function($) {
    $("a[data-href]").each(function() {
        var $this = $(this);
        $this.attr("href", $this.attr("data-href"));
    });
});

Again, that last bit only if you really need to make the href an href. 再次,只有当你真的需要使href成为href时才是最后一点。 If you're handling the click via JavaScript, no need to. 如果您通过JavaScript处理点击,则无需。

If validation is a significant part of your development cycle, it's important to note that attributes in the form data-xyz are invalid in HTML4 and before (browsers don't actually care, but again, if you use validation...). 如果验证是开发周期的重要部分,请务必注意, data-xyz形式的属性在HTML4和之前是无效的(浏览器实际上并不关心,但如果使用验证,则再次......)。 They become valid as of HTML5. 它们从HTML5开始有效。

Option 2 选项2

Use inline onclick attributes to intercept the click prior to jQuery loading and basically say "Sorry, one moment". 在jQuery加载之前使用内联onclick属性拦截点击,基本上说“抱歉,一刻”。 So in a script tag at the top of your file: 因此,在文件顶部script标记中:

function sorryLoading() {
    alert("Sorry, the page is still loading, one moment please.");
    return false;
}

...and then on the links: ...然后在链接上:

<a href='realtarget.html' class='sorry' onclick='return sorryLoading();'>blah</a>

...then remove the onclick on jQuery load: ...然后删除jQuery加载上的onclick

jQuery(function($) {
    $("a.sorry").removeClass('sorry').attr("onclick", "").click(yourRealClickHandler);
});

(You can leave the last bit — the click call — off if they don't all have the same click handler.) (如果他们没有相同的点击处理程序,你可以留下最后一点 - click呼叫 - 关闭。)

I've used a class above to differentiate between these links and others that might have an inline onclick (otherwise, surprisingly the selector "a[onclick]" actually works on Chrome, Opera, and Firefox for Linux and IE6 and IE8 on Windows). 我已经使用上面的一个类来区分这些链接和其他可能具有内联onclick (否则,令人惊讶的是选择器“a [onclick]”实际上适用于Chrome,Opera和Firefox for Linux以及Windows上的IE6和IE8) 。

Option 3 选项3

Since it sounds like you want the page to be non-functional until jQuery loads, here's another approach: 因为听起来你希望页面在jQuery加载之前不起作用,所以这是另一种方法:

  1. Make sure that the script tag for jQuery is in the head section of your page (not at the bottom, where I'd normally recommend putting it). 确保jQuery的脚本标记位于页面的head部分(不在底部,我通常建议将其放在底部)。
  2. At the very bottom of your page, just before closing the body tag, hook up your click handlers without wrapping them in a jQuery.ready call (or any of its shortcuts). 在页面的最底部,就在关闭body标签之前,挂钩你的click处理程序而不将它们包装在jQuery.ready调用(或其任何快捷方式)中。

The reason is this: #1 will ensure that jQuery itself is loaded prior to the page being rendered, and #2 will hook up the handlers as soon as possible . 原因是:#1将确保在呈现页面之前加载jQuery本身,而#2将尽快连接处理程序。 Google recommends using a tag at the end of the page like that (rather than a ready function or similar) and says that at that point, the DOM elements will be ready to be discovered. 谷歌建议在页面末尾使用一个标签(而不是一个ready功能或类似的),并说在那时,DOM元素将可以被发现。


Separately, of course, you want to ensure that the time during which the links don't do what the user expects is absolutely as brief as possible by doing all of the page-load optimization stuff you can. 当然,另外,您希望通过执行所有页面加载优化,确保链接不能满足用户期望的时间绝对尽可能简短 Clicking a link and not having it do what it looks like it does makes for a poor user experience. 单击一个链接而不使它看起来像它确实会导致糟糕的用户体验。

You could use event-delegation: the DOM equivalent of jQuery live() and delegate() methods. 您可以使用事件委派:相当于jQuery live()delegate()方法的DOM。

The following might work: 以下可能有效:

<head>

<script>
function linkMatcher(node) { // modify this if not all links are disabled
 if (node.href) return true;
 else return false;
}

document.onclick = function(e) {
 e = e || window.event;
 var target = e.target || e.srcElement;
 for (var node=target; node!=document; node=node.parentNode) {
  if (node.tagName == "A") return !linkMatcher(node);
 }
}
</script>
</head>

EDIT: This disables the links permanently. 编辑:这将永久禁用链接。 They can be re-enabled by removing the event-handler, eg document.onclick = null . 可以通过删除事件处理程序来重新启用它们,例如document.onclick = null


The complete, live example below works on Chrome, Opera, and Firefox for Linux as well as IE6 and IE8 for Windows. 下面的完整实时示例适用于Chrome,Opera和Firefox for Linux以及IE6和IE8 for Windows。 It prevents clicks on links with the class "wait" (you could do all links instead if you liked) and remembers the first link clicked. 它会阻止点击“等待”类的链接(如果您愿意,可以改为完成所有链接),并记住点击的第一个链接。 Then it simulates a long load delay (five seconds) and then hooks up jQuery handlers on the links and removes the document-level handler that was preventing clicks, and then triggers the jQuery handler on the link that was clicked (note that this only triggers the handler, not the underlying default behavior — but as you want to trigger your ajax stuff, I figure that's okay). 然后它模拟一个长的加载延迟(五秒),然后在链接上挂钩jQuery处理程序并删除阻止点击的文档级处理程序,然后在单击的链接上触发jQuery处理程序(请注意,这只会触发处理程序,而不是底层的默认行为 - 但是当你想触发你的ajax时,我认为没关系)。 — TJ Crowder - TJ克劳德

HTML: HTML:

<!DOCTYPE html>
<html>
<head>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<meta charset=utf-8 />
<title>Link Click Delay Test Page</title>
<!--[if IE]>
  <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<style>
  article, aside, figure, footer, header, hgroup, 
  menu, nav, section { display: block; }
  body {
    font-family: sans-serif;
  }
  p {
    margin: 0px;
  }
</style>
<script type='text/javascript'>
  // A scoping function to avoid creating global symbols
  (function() {
    // Figure out what to hook clicks on
    var container =
        document.body ||
        document.documentElement ||
        document;

    // Hook clicks that reach the bottom level
    hookClicks();
    function hookClicks() {
      if (container.attachEvent) {
        container.attachEvent("onclick", handleClick);
      }
      else if (document.addEventListener) {
        container.addEventListener("click", handleClick, false);
      }
    }

    // Set up an unhook function for jQuery to call
    window.unhookClicks = unhookClicks;
    function unhookClicks() {
      if (container.attachEvent) {
        container.detachEvent("onclick", handleClick);
      }
      else if (document.addEventListener) {
        container.removeEventListener("click", handleClick, false);
      }
    }

    // Handle clicks
    function handleClick(event) {
      var target;

      // Handle Microsoft vs. W3C event passing style
      event = event || window.event;

      // Get the target (again handling Microsoft vs. W3C style)
      target = event.target || event.srcElement;

      // Do we have a target that's an A with the class "wait"?
      if (target &&
          target.tagName.toUpperCase() === "A" &&
          (" " + target.className + " ").indexOf(" wait ") >= 0
         ) {
        // It's a link we want to prevent for the moment
        // Remember the element that was clicked if there
        // isn't already one (or replace it, depends on the
        // UX you want to provide
        if (!window.pendingLink) {
          window.pendingLink = target;
        }

        // Prevent it from being processed
        if (event.preventDefault) { // If W3C method...
          event.preventDefault();
        }

        // This should work if preventDefault doesn't
        return false;
      }
    }
  })();
</script>
</head>
<body>
  <p><a href='http://www.google.com' class='wait'>Google</a>
    - This one waits
  <br><a href='http://news.bbc.co.uk' class='wait'>BBC News</a>
    - This one also waits
  <br><a href='http://www.cnn.com'>CNN</a>
    - This one doesn't wait, it goes immediately
    </p>
</body>
</html>​

JavaScript (wherever your jQuery ready handler is): JavaScript(无论你的jQuery ready处理程序在哪里):

jQuery(function($) {

  // Use setTimeout to fake a long delay loading
  setTimeout(function() {

    // Hook up our proper click handling
    // Obviously, replace this with whatever does the ajax
    $("a.wait").click(function(event) {
      alert("The jQuery handler for " + this.href + " link was triggered.");
    });

    // If we have clicks disabled, enable them
    if (window.unhookClicks) {
      window.unhookClicks();
      window.unhookClicks = undefined;
    }

    // Do we have a pending link to follow?
    if (window.pendingLink) {
      // Yes, grab it and clear it
      var $link = $(window.pendingLink);
      window.pendingLink = undefined;

      // Trigger any jQuery event handlers on it.
      // Note that this will NOT follow the link,
      // just trigger jQuery event handlers that
      // are on the link.
      $link.click();
    }

    // We've loaded!
    $("<p>Finally loaded!</p>").appendTo(document.body);

    // End of fake delay function
  }, 5000);

});​

I haven't tried it, but in theory, add an event handler without jquery to all a elements that prevents the default action (opening the link) as long as jquery is undfinied? 我没有尝试过,但理论上,只要jquery未完成,就可以向所有阻止默认操作(打开链接)的元素添加一个没有jquery的事件处理程序?

getElementsByTagNames('a').addEventListener('click',function (event) {
  if (typeof jQuery == 'undefined') { 
    event.preventDeafault();
  }
},false)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM