R Shiny中ID和类组合的Javascript问题

时间:2018-06-25 22:06:53

标签: javascript css shiny

我正在做一个项目,并且停留在最后一步。我正在开发ShinyApp,并在标签$ body部分的末尾的ui.R文件中完成了以下操作:

tags$script(HTML('

            window.onscroll = function() {myFunction()};

            var sidebar = document.getElementById("sidebar");

            var title = document.getElementById("title");
            var titleHeight = title.offsetHeight;


            function myFunction() {
            if (window.pageYOffset >= titleHeight) {
              if ($(window).width() > 1280) {
                sidebar.classList.add("sticky-wide");
              } else if ($(window).width() > 780) {
                // This is the final issue:
                sidebar.classList.add("sticky");
                //sidebarWell.classList.add("stickyWell");
              } else {
                sidebar.classList.add("sticky-narrow");
              }
            } else {
              if ($(window).width() > 1280) {
                sidebar.classList.remove("sticky-wide");
              } else if ($(window).width() > 780) {
                sidebar.classList.remove("sticky");
                //sidebarWell.classList.remove("stickyWell");
              } else {
                sidebar.classList.remove("sticky-narrow");
              }
            }
            }'))...

请注意,“ sidebar”是赋予我闪亮的元素“ sidebarPanel()”的ID名称。因此,当我滚动到页面顶部的标题之外时,基于css文件中的以下代码,我的侧边栏会变得很粘(请注意,我可以确定的最后一个元素来自我之前的上一个代码,并且我相信这是全局的)样式选项,该选项已分配给可自动使标签发光的类):

.stickyWell {
  box-sizing: border-box;
  width: calc(33% - 30px);
}

.sticky {
  box-sizing: border-box;
  width: calc(33% - 30px);
  /*width: inherit;*/
  position: fixed;
  top: 0;
  height: 100vh;
}

.sticky-narrow {
  width: 100%;
}

.sticky-wide {
  box-sizing: border-box;
  width: calc(426.67px - 30px);
  position: fixed;
  top: 0;
  height: 100vh;
}

/*Change style options of a singular selectInput box by first defining a class for it:*/
.my_class .selectize-input {
  border-top-left-radius: 0px;
  border-top-right-radius: 0px;
}

#ss-connect-dialog {
  opacity: 1 !important;
  padding: 1em;
  position: fixed;
  top: 50px;
  bottom: auto;
  left: 50px;
  padding-left: 45px;
  padding-right: 18px;
  width: 300px;
  height: auto;
  z-index: 99999;
  background-color: #404040;
  color: white;
  border-radius: 3px;
  font-size: 0.9em;
  box-shadow: rgba(0, 0, 0, 0.3) 3px 3px 10px;
}

更新:请注意if语句已更新,现在可以正常工作。这是我得到的最接近的代码,但是嵌套if语句中的第二种情况不能正确调整宽度。

以下是我过去使用的一种解决方案,但似乎与window.onscroll功能不兼容:

@media only screen and (max-width: 1280px) and (min-width: 780px) {
  #sidebar.well {
    box-sizing: border-box;
    width: calc(33% - 30px);
    /*position: fixed;*/
    overflow-y: scroll;
    height: 80vh;
  }
}

这曾经在我的CSS文件中,并调整了适当的宽度(请注意33%是由于sidebarPanel的column = 4而30px是sidebarPanel边框的两倍,默认情况下设置,稍后我可以这个更强大)。因此,理想情况下,我需要在ui.R的javascript部分中找到一种实现此方法的方法(我的尝试之一是,连接到第一个代码bluck中涉及“ stickyWell”的注释行,该代码行看起来很相似, @media上方,在CSS代码的第一段中。


原始帖子的其余部分紧随其后,可以忽略

问题是,向下滚动页面时,侧边栏的宽度变得太大。我早些时候找到了解决方案,但在滚动到标题之前和之后,都会遇到侧边栏宽度更改的问题。

我想解决这个问题的一种方法是使用:

#sidebar.well {
  box-sizing: border-box;
  width: calc(33% - 30px);
}
在我的css文件中也是

(其中类名“ well”是由R Shiny自动分配的,特别是使用id-class名组合正确地调整了东西的大小)。但这只会在滚动到标题之后(边栏获得position:fixed属性时)固定宽度,并且在滚动到标题之前会固定宽度。

所以现在剩下要做的就是,当我滚动到标题上方时,仅启用上面的css片段。我已经尝试过诸如此类的事情:

var sidebarWell = document.getElementById("sidebar").getElementsByClass("well")[0];

,然后在适当的if语句中(在第一段代码中),我尝试添加以下内容:

sidebarWell.setAttribute("style", "box-sizing: border-box;");
sidebarWell.setAttribute("style", "width: calc(33% - 30px);"); 

sidebarWell.classList.add("stickyWell");

首先将css文件中的“#sidebar.well {}”重命名为“ stickyWell {}”。

我是javascript新手,我缺少什么或做错了什么?请注意,我认为id和class名称非常受限制,因为标签的光泽度很高,我尝试将上述样式更改仅应用于id =“ sidebar”,但按我的想法行不通。


针对第一条评论:

首先,我认为我会在代码中包含任何可能引起冲突的相关部分。首先,定义sidebarPanel的方式:

sidebarLayout(
  sidebarPanel(id="sidebar",
               width=4,
               ...

在ui.R的该部分中没有其他主要内容(mainPanel的width = 8定义。然后在ui.R的开头,我有

shinyUI(fluidPage(
  includeCSS("extrahtmlfunc.css"),
  tags$head(
    # 2018-06-19: Fixes issue where a slider that appears at certain zoom levels for figures using splitLayout (only shows up on Chrome):
    tags$style(HTML(".shiny-split-layout > div { overflow: visible; }")),
    # The following makes it so the UI doesn't look to weird in super-wide browsers
    tags$style(type="text/css", 
               ".container-fluid {  max-width: 1280px; }"
    ),
    ...

这应该是所有相关的内容,其余则是次要的颜色样式或类似的调整。请注意,这最后一件事使解决方案更容易修复,因为我需要针对不同页面宽度的单独大小写(我正在更新第一段代码以在函数myFunction()中揭示这些情况的完整细节,我将其删除以缩短我的帖子;请注意嵌套if语句的第二种情况是唯一无法正常工作的情况。

我还根据请求用其余的CSS文件更新了第二段代码。

1 个答案:

答案 0 :(得分:0)

找到了一种解决方法:

首先,我能够合并以前的CSS代码来解决此问题,但以前无法合并window.onscroll功能。这是解决我的问题的主要方法之一,可能还有其他更好的解决方案。

从原始CSS文件中调出正确大小的代码段:

@media only screen and (max-width: 1280px) and (min-width: 780px) {
  #sidebar.well {
    box-sizing: border-box;
    width: calc(33% - 30px);
    /*position: fixed;*/
    overflow-y: scroll;
    height: 80vh;
  }
}

请注意,@ media ...连接到ui.R的javascript部分中嵌套if语句的第二种情况。很难说我是否能够用类似的东西来复制它:

.stickyWell {
  box-sizing: border-box;
  width: calc(33% - 30px);
}

结合

var sidebar = document.getElementById("sidebar");

var sidebarWell = sidebar.getElementsByClassName("well")[0];

if(...){
  if(...) {
    ...
  } else if (...) {
    ...
    sidebarWell.classList.add("stickyWell");
  }...

因为“ 33%”似乎无法在javascript中运行(也许有人知道原因)。我什至找到并尝试了一种将CSS代码的第一块直接转换为我的javascript部分的方法:

$("#sidebar.well").css("box-sizing", "border-box");
$("#sidebar.well").css("width", "calc(33% - 30px)");

但是这不起作用(我甚至在运行应用程序时检查了该元素,并且不接受上面样式的第二部分)。

但是,一旦学习了如何直接在javascript中实现css代码,我意识到我可以用精确数量的像素替换33%的像素,就像在原始问题的“ .sticky-wide”部分中一样。这是产生的解决方案:

shinyUI(fluidPage(
  includeCSS("extrahtmlfunc.css"),
  tags$head(
    ... ,
    tags$script(HTML('
                window.onscroll = function() {myFunction()};
                
                var sidebar = document.getElementById("sidebar");
                
                var title = document.getElementById("title");
                var titleHeight = title.offsetHeight;

                function myFunction() {
                if (window.pageYOffset >= titleHeight) {
                  if ($(window).width() > 1280) {
                    sidebar.classList.add("sticky-wide");
                  } else if ($(window).width() > 780) {
                    sidebar.classList.add("sticky");
                    $("#sidebar.well").css("box-sizing", "border-box");
                    $("#sidebar.well").css("width", "calc(" + $(window).width()/3 + "px - 30px)");
                  } else {
                    sidebar.classList.add("sticky-narrow");
                  }
                } else {
                  if ($(window).width() > 1280) {
                    sidebar.classList.remove("sticky-wide");
                  } else if ($(window).width() > 780) {
                    sidebar.classList.remove("sticky");
                    $("#sidebar.well").css("box-sizing", "");
                    $("#sidebar.well").css("width", "");
                  } else {
                    sidebar.classList.remove("sticky-narrow");
                  }
                }
                }

                    '
  )
  ) # Closes tag$script
  ) # Closes tag$head
  ... # Rest of ui.R
 )
) # Closes shinyUI

我希望这最终可以帮助别人。