简体   繁体   English

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

[英]Javascript issue with id and class combination within R shiny

I am working on a project and am stuck with one of my final steps. 我正在做一个项目,并且停留在我的最后一个步骤中。 I am developing a shinyApp and have done stuff like the following within my ui.R file, at the end of my tags$body section: 我正在开发ShinyApp,并在我的tags $ 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");
              }
            }
            }'))...

Note that "sidebar" is the id name given to my shiny element "sidebarPanel()". 请注意,“ sidebar”是赋予我闪亮元素“ sidebarPanel()”的ID名称。 So that when I scroll beyond the title at the top of the page, my sidebar becomes sticky based on the following code in my css file (note the very last element I am pretty sure is from my predecessor's previous code and I believe is some global style options assigned to a class that shiny labels automatically): 因此,当我滚动到页面顶部的标题之外时,基于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; } 

Update: Note the if statements have been updated and now work properly. 更新:请注意if语句已更新,现在可以正常工作。 This is the closest I have gotten the code to working, but the second case in the nested if statement does not adjust the width properly. 这是我得到的最接近的代码,但是嵌套的if语句中的第二种情况不能正确调整宽度。

The following was one solution I used in the past but seems incompatible with the window.onscroll feature: 以下是我过去使用的一种解决方案,但似乎与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;
  }
}

This used to be in my CSS file and adjusted the width the appropriate amount (note the 33% is due to column = 4 for sidebarPanel and the 30px is twice the border of the sidebarPanel, set by default, later I can make this more robust). 这曾经在我的CSS文件中,并调整了适当的宽度(请注意,33%是由于sidebarPanel的column = 4而30px是sidebarPanel边框的两倍,默认情况下已设置,以后我可以使它更健壮)。 So ideally I need to figure out a way to implement this in my javascript section of ui.R (one of my attempts being connected to the commented lines involving "stickyWell" in the first code bluck, which calls a similar looking thing, to the @media above, in the first block of css code). 因此,理想情况下,我需要在ui.R的javascript部分中找到一种实现此方法的方法(我的尝试之一是,连接到第一个代码bluck中涉及“ stickyWell”的注释行,该代码行看起来很相似, @media上方,在CSS代码的第一块中)。


Remaining portions of original post follows and can be ignored 原始帖子的其余部分如下,可以忽略

The issue is that the width of my sidebar becomes too large when scrolling down the page. 问题是,向下滚动页面时,侧边栏的宽度变得太大。 I found a solution to this earlier, but it runs into the issue of the sidebar width changing before and after I scroll beyond the title. 我早些时候找到了解决方案,但是在滚动到标题之前和之后,都会遇到侧边栏宽度更改的问题。

One way I figured out to get around this was to use: 我想解决这个问题的一种方法是使用:

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

in my css file as well (where the class name "well" is assigned automatically by R shiny and specifically using the id-class name combo correctly sizes things). 在我的css文件中也是如此(其中类名“ well”是由R Shiny自动分配的,特别是使用id-class名组合正确地调整了东西的大小)。 But this only fixes the width after scrolling beyond the title (when the sidebar gets the position:fixed property) and screws up the width prior to scrolling beyond the title. 但这仅在滚动到标题之后(边栏获得position:fixed属性时)固定宽度,并在滚动到标题之前固定宽度。

So now what is left to do is to only enable the above css snippet when I scroll beyond the title. 因此,现在要做的就是仅在我滚动到标题上方时启用上述CSS片段。 I have tried such things as: 我已经尝试过诸如:

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

and then within the proper if statement (in the first block of code) I tried adding things like: 然后在适当的if语句中(在第一段代码中),我尝试添加以下内容:

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

or 要么

sidebarWell.classList.add("stickyWell");

After first renaming "#sidebar.well{}" in the css file to "stickyWell{}". 首先将css文件中的“#sidebar.well {}”重命名为“ stickyWell {}”。

I am new to javascript, what am I missing or doing wrong? 我是javascript新手,我缺少什么或做错了什么? Please note that I think I am very limited with id and class names because of how shiny labels things, and I have tried applying the above style changes to just id="sidebar" but it does not work how I think it should. 请注意,我认为id和class名称非常受限制,因为标签的外观如何闪亮,我尝试将上述样式更改仅应用于id =“ sidebar”,但按我的想法行不通。


In response to the first comment: 针对第一个评论:

Firstly, I figured I would include any relevant parts of the code that may create conflicts. 首先,我认为我会在代码中包含任何可能引起冲突的相关部分。 First the way the sidebarPanel is defined: 首先,定义sidebarPanel的方式:

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

with nothing else major in that section of ui.R (mainPanel is defined with width=8. Then in the beginning of ui.R, I have 在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; }"
    ),
    ...

That should be all that is relevant, the rest is minor color styles or similar tweaks. 那应该是所有相关的东西,其余的都是次要的颜色样式或类似的调整。 Note that this last thing is what makes some easier fixes for my solution more difficult, because I need separate cases for different page widths (I am updating the first block of code to reveal the full details of these cases in the function myFunction(), which I removed to shorten my post; note the second case of the nested if statement is the only one not working properly). 请注意,这最后一件事使解决方案更容易修复,因为我需要针对不同页面宽度的单独大小写(我正在更新第一段代码以在函数myFunction()中揭示这些情况的完整细节,删除它是为了缩短我的帖子;请注意嵌套if语句的第二种情况是唯一无法正常工作的情况。

I also updated the second block of code with the rest of my css file as per request. 根据请求,我还用其余的CSS文件更新了第二个代码块。

Found a workaround: 找到了解决方法:

First off, I was able to incorporate my previous css code that fixed the issue but I was previously unable to incorporate with the window.onscroll feature. 首先,我可以合并以前的CSS代码来解决此问题,但以前无法合并window.onscroll功能。 This was one of the main ways to solve my question, and there are likely other solutions which may be better. 这是解决我的问题的主要方法之一,可能还有其他更好的解决方案。

Recall the snippet from my original CSS file that gave the correct sizing: 回忆一下原始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; } } 

Note that the @media... connects to the second case of the nested if statement in my javascript portion of my ui.R. 请注意,@ media ...连接到ui.R的javascript部分中嵌套if语句的第二种情况。 It was hard to tell if I was able to replicate this with things like: 很难说我是否能够通过以下方式复制它:

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

in conjunction with 和这个结合

 var sidebar = document.getElementById("sidebar"); var sidebarWell = sidebar.getElementsByClassName("well")[0]; if(...){ if(...) { ... } else if (...) { ... sidebarWell.classList.add("stickyWell"); }... 

because the "33%" seemed to not work within javascript (perhaps someone knows why). 因为“ 33%”似乎无法在javascript中运行(也许有人知道原因)。 I even found and tried a way to transform the first block of CSS code directly into my javascript section: 我什至找到并尝试了一种将第一段CSS代码直接转换为我的javascript部分的方法:

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

but this did not work (I even inspected the element when running the app and it did not accept the second portion of the style above). 但这是行不通的(我什至在运行应用程序时检查了该元素,并且它不接受上面样式的第二部分)。

However, once learning how to implement css code directly into javascript, I realized I might be able to replace the 33% with a precise number of pixels as that worked in the ".sticky-wide" portion of my original question. 但是,一旦学习了如何直接在JavaScript中实现css代码,我意识到我可以用精确数量的像素替换33%的像素,就像在原始问题的“ .sticky-wide”部分中那样。 Here is the resulting solution: 这是结果解决方案:

 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 

I hope this ends up helping someone else. 我希望这最终可以帮助其他人。

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

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