如何检测Slidy中的幻灯片更改?

时间:2017-03-18 01:44:50

标签: knitr r-markdown mutation-observers slidy

我使用rmarkdown使用slidy_presentation制作Slidy幻灯片。我想在显示幻灯片时执行一些Javascript。在ioslides_presentation中,当显示页面时会触发slideenter事件(请参阅Event when slide is displayed in ioslides?),但我在Slidy中看不到类似内容。

我可以检测是否正在显示特定幻灯片(通过查看其div的类),但我不知道如何触发代码来执行此操作。

是否有某种方法可以检测到幻灯片更改正在发生?

1 个答案:

答案 0 :(得分:2)

我稍微研究了一下,发现了如何检测当前显示的幻灯片的简单方法:

使用MutationObserver

在下面的脚本中,我们使用 MutationObserver (请参阅herehere)来观察title元素内容的变化。拥有标题我们可以提取它的整数部分,它代表幻灯片编号。 在此示例中,我们只显示一个警告,其中包含文本“当前幻灯片:”,后跟我们提取的数字。

enter image description here

以下是JavaScript代码段:

<script>
var target = document.querySelector('head > title');
var observer = new window.WebKitMutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        var title   = mutation.target.textContent;
        var current = +title.toString().match(/\d+/g);
        alert('Current Slide: ' + current);
    });
});
observer.observe(target, { subtree: true, characterData: true, childList: true });
</script>

由于我们不希望将代码段解释为幻灯片本身的内容,因此我们通过YAML标头将其包含在内。请查看下面的可重现示例,其中 header.html 仅包含上面的javascript代码段:

MRE:

---
title: "Untitled"
author: "Martin Schmelzer"
date: "18 3 2017"
output: 
  slidy_presentation:
    includes:
      in_header: header.html
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
```

## R Markdown

Slide 2 (Title slide is #1!)

## Slide with Bullets

This is slide 3!

## Slide with R Output

...and number 4!

编辑:ioslides的修改脚本

如果在ioslides中需要某种方式,您可以通过以下方式修改JavaScript代码段:

<script>
$(document).ready(function() {
  var target = document.querySelector('slides');
  var observer = new window.WebKitMutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      if(mutation.target.getAttribute('class').indexOf('current') != -1 ) {
          alert(mutation.target.getAttribute('data-slide-num'));
      }
    });
  });
  observer.observe(target, { subtree: true, attributes: true});
});
</script>

在滑动中,每张幻灯片都包含自己的div容器。 ioslides的方法是不同的。在这里,我们只有过去,当前,下一个和下一个幻灯片的几个<slide>元素。当前的幻灯片元素是具有类current的元素。所以我们只是在forEach循环中搜索该类,并获取它的data-slide-num属性。