【问题标题】:How can I highlight a link on first click; and follow it on second click, unless clicked elsewhere, then reinitialize non-highlighted state?如何在第一次点击时突出显示链接;并在第二次点击时跟随它,除非在其他地方点击,然后重新初始化非突出显示状态?
【发布时间】:2015-04-09 08:43:50
【问题描述】:

一个人(可能使用通常的嫌疑人Javascript)怎么能有几个(起初没有突出显示的链接)然后实现:

打开(永久)和关闭突出显示并区分突出显示和重定向?

  • 点击一个词使高亮显示永久(打开)。
  • 再次点击(打开后)该词会重定向到文章。
  • 点击其他地方会移除高亮显示(关闭)。

编辑(澄清,在问题被搁置后):

切换突出显示

我知道可以使用 .addClass("active");.removeClass("active"); 处理此突出显示,但不知道如何在添加 Class("active") 时包含链接和/或在添加 Class 时如何禁用链接删除。 CSS 然后需要(例如).active{background:green}

切换重定向(链接跟随)

  • 所以,现在发现preventDefault(); 在启用或禁用链接跟踪方面起着核心作用;因为,正如人们在its entry in the jQuery-api 中看到的那样:
  • 如果调用此方法,则不会触发事件的默认动作。
  • 例如,单击的锚点不会将浏览器带到新的 URL。
  • 另一种方法是使用return false;

两者之间的区别与传播(或 “冒泡”) DOM。关于 这种差异,可以阅读 CSS-tricks 或者看看下面的答案 somethinghere, 当他添加event.stopImmediatePropagation(); 来阻止这个 冒泡

两者之间的区别如下:return false; 本身也可以防止这种传播,而preventDefault(); 不会。

CSS-tricks-articlesais:

function() {return false;}

等于:

function(e) {e.preventDefault(); e.stopPropagation();}

更多关于差异的文献可以在 StackExchange 上找到,其中可能包含一些重复的帖子?

var anchors = document.getElementsByTagName('a'),
    length = anchors.length,
    index;

for (index = 0; index < length; index += 1) {
    anchors[index].onclick = function (e) {
        e.preventDefault();
        if (!(/\bhighlight\b/).test(e.target.className)) {
            e.target.className += ' highlight';
        }
    };
}
.blockElement {
    display:block;
    float: left;
    clear: left;
}
.highlight {
    background-color: yellow;
}
<a href="#one" class="blockElement">Jump to One</a>
<a href="#two" class="blockElement">Jump to Two</a>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<div id="one">One</div>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<div id="two">Two</div>

【问题讨论】:

  • 嗯,有一个问题我正在处理,例如highlighting a current link in JS,但我没有第二次点击获得不同操作的经验。我会建议自己尽快参加初学者的 JS 课程。 :) 我需要对这种强大的语言有更多的了解。
  • 好的,但是您尝试了什么?什么不起作用?
  • 我还没有彻底测试过,但是看看,最坏的情况是你可以用它来解决更多问题。 jsfiddle.net/Xotic750/uysk5jpm
  • 使用CSS设置body为整页大小,使用html,更新jsFiddle为例。正如我所说,我没有彻底测试过它。当我无法添加完整答案时,这很困难。 :)
  • 添加了我错过的额外preventDefault。基本上我添加了一些CSS。看看这个问题。 stackoverflow.com/questions/6654958/…

标签: javascript jquery html


【解决方案1】:

这是一个示例,展示了您想要实现的概念。链接和信息已在原始问题下的 cmets 中发布。

var anchors = document.getElementsByTagName('a');

document.body.addEventListener('click', function (e) {
    [].forEach.call(anchors, function (anchor) {
        if (e.target !== anchor) {
            anchor.classList.remove('highlight');
            anchor.classList.remove('follow');
        }
    });
}, false);

[].forEach.call(anchors, function (anchor) {
    anchor.addEventListener('click', (function (e) {
        var clicked = false;

        return function (e) {
            if (!clicked) {
                e.preventDefault();
                e.target.classList.add('highlight');
                clicked = true;
            } else {
                clicked = e.target.classList.contains('highlight');
                if (clicked) {
                    e.target.classList.add('follow');
                    e.target.classList.remove('highlight');
                } else {
                    e.preventDefault();
                    e.target.classList.add('highlight')
                    clicked = true;
                }
            }
        };
    }()), false);
});
body {
    position:absolute;
    top:0;
    bottom:0;
    right:0;
    left:0;
}
html {
    height:100%;
}
.blockElement {
    display:block;
    float: left;
    clear: left;
}
.highlight {
    background-color: yellow;
}
.follow {
    background-color: red;
}
<a href="#one" class="blockElement">Jump to One</a>
<a href="#two" class="blockElement">Jump to Two</a>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<div id="one">One</div>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<div id="two">Two</div>

【讨论】:

  • 非常感谢。非常好的工作。最近我忙于许多项目,但我已经想对你的美好实现表示感谢。祝您度过愉快的一周。
【解决方案2】:

当您单击任何链接时,将highlight 类添加到其中,并防止默认停止跟踪该链接,如果它没有此类..

/* Take each "a" in your DOM and apply a click handler. */
$("a").click(function(event){
    /* Check if the highlight class is already applied. */
    if(!$(this).hasClass("highlight")){
        /* If not, use preventDefault to stop following the link. */
        event.preventDefault();
        /* Also stop the event from bubbling up to the document as a click. */
        event.stopImmediatePropagation();
        /* Then apply it. */
        $(this).addClass("highlight");
    }
});

当您单击其他任何位置时,请检查您是否单击了具有唯一 highlighted 类的那个。如果不是,请从页面上的任何现有链接中删除该课程。如果要防止在突出显示其他内容时发生任何突出显示,请在 if 语句中使用 preventDefault()。 Answer 使用 jQuery,但也可以只用 javascript 完成。

$(document).click(function(event){
    /* Check if the clicked target has the highlighted class. */
    if(!$(event.target).hasClass("highlight")){
        /* If not, remove the class from any element on the page. */
        $(".highlight").removeClass("highlight");
    }
});

更新

我最初使用一个全局变量来存储当前单击的,但除非您想突出显示多个,否则这是不必要的。在这种情况下,创建一个全局变量并使用 jQuery add() 函数将其添加到突出显示。

更新 2

我已经稍微缩短了代码,清理了它。此外,您必须将整个内容包装在 $(document).ready(function(){}) 中,否则您必须将其添加到页面末尾(因为尚未初始化 a 元素)。

更新 3

这是踢球者(感谢 cmets) - 当您点击链接时,您也点击了文档。这是因为一个叫做冒泡的效果 - 气泡从被点击的元素开始,但它会冒泡 DOM,直到它碰到窗口对象。我之前在代码中对其进行了修改,添加了event.stopImmediatePropagation(); - 就像它在锡上所说的那样 - 它是stops immediate propagationbubbling

这是一个 sn-p:

$(document).ready(function(){
  $(document).click(function(event){
    if(!$(event.target).hasClass("highlight")){
      $(".highlight").removeClass("highlight");
    }
  });
  $("a").each(function(){
    $(this).click(function(event){
      if(!$(this).hasClass("highlight")){
        event.preventDefault();
        event.stopImmediatePropagation();
        $(this).addClass("highlight");
      }
    });
  });
});
.highlight { 
  background: red; 
  color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<a href="http://www.stackoverflow.com">Stack Overflow Highlighting</a>

【讨论】:

  • 对于删除类,我想你想使用if(current != null &amp;&amp; current.hasClass("highlighted")),而不是使用事件的目标。为此,我还将 current 初始化为 null。我认为 null 比 0 长度数组更容易检查。
  • 这就是为什么我将 current 初始化为 [] (这是一个数组,或者一个空的 jquery 对象)。但是我已经修改了,因为无论如何我都不需要全局。
  • @somethinghere - 非常感谢您的回复。我很欣赏你的知识分享。你的代码让我学到了很多东西,当我在 JSFiddle 中将它与 jQuery 一起使用时,对于重定向 after addClass("highlight"); 的结果很好。我从您的代码中了解到,此后.removeClass("highlight"); 被执行,因此event.preventDefault(); 被删除?但是,这与 CSS 的可见布局无关,突出显示不会被删除。单击其他地方或其他链接会累积突出显示。 --- 关于我在那里缺少什么的任何建议?
  • @somethinghere - 所以,基本上我不明白为什么 CSS .highlight{background-color:green; 没有随着 .removeClass("highlight"); 的执行而被删除。 --- 此外,如果我可能会问:为什么在 1 个实例中选择 higlighted,而代码中的所有其他实例都使用 higlight
  • @VincentVerheyen 我知道为什么,抱歉,我忘记了一个名为 bubbling 的属性。当您单击某物时,该事件会通过 DOM 树触发,直到到达window。您需要stopImmediatePropagation() 以确保当您单击链接时 DOM 事件不会获得冒泡的单击事件。我的帖子已经过修改和测试。对此感到抱歉。
【解决方案3】:

使用锚点的 onclick 来运行 javascript 函数。如果之前没有点击过,通过更改 css 突出显示它,并返回 false 以便不跟随链接。如果之前被点击过,则返回true,因此链接被点击。

为了检查链接是否被“点击关闭”,您可以为锚点使用 onblur 事件。

【讨论】:

  • 非常感谢您的回答。这似乎是一个不错的策略,我将通过做一些 JS 研究来深入研究。 - 看来我需要弄清楚如何使用return falsetrue,正如你所描述的那样。
  • 强烈建议不要在 DOM 中使用 javascript 属性,因为一旦您想更改某些内容,它会显着降低可重用性。但是,您总是需要创建某种内存来存储第一次点击,而类很容易做到这一点。
猜你喜欢
  • 2014-06-04
  • 2019-04-13
  • 2010-10-23
  • 2013-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-27
  • 1970-01-01
相关资源
最近更新 更多