【发布时间】:2018-07-27 17:03:05
【问题描述】:
我正在使用来自 tradingview (https://www.tradingview.com/widget/ticker/) 的这个小部件,想知道是否有办法:
- a) 让滚动条滚动(iFrame 滚动=yes)
- b) 重新调整小部件的大小。
我以前没有使用过 iFrame,不知道如何进行自定义,或者是否可以进行自定义。
【问题讨论】:
标签: javascript html css iframe widget
我正在使用来自 tradingview (https://www.tradingview.com/widget/ticker/) 的这个小部件,想知道是否有办法:
我以前没有使用过 iFrame,不知道如何进行自定义,或者是否可以进行自定义。
【问题讨论】:
标签: javascript html css iframe widget
这是一个达到预期效果的答案:https://codepen.io/epsilon42/pen/BPZgjP/
它主要涉及CSS动画的使用,但还需要添加一些jQuery来克隆iframe以消除ticker运行到最后时的间隙。由于无法操作 iframe 跨域的内容,这是我能想到的唯一方法。
我必须删除 TradingView 脚本上的 async 才能正确触发 $( document ).ready。
另外需要注意的是,有必要根据您选择在股票行情中拥有多少项目来更改 CSS 中的宽度:
.ticker-canvas {
width: calc((200px * 15) + 2px);
}
将上述 CSS 中的值 15 更改为您在脚本中调用的项目数。 200px 似乎是小部件决定自动删除项目之前可以使用的最小宽度,但如果需要,使用更高的值似乎没有任何问题。 2px 是考虑到小部件两侧的 1px 边框。
HTML:
<!-- TradingView Widget BEGIN -->
<div class="ticker-container">
<div class="ticker-canvas">
<div class="tradingview-widget-container">
<div class="tradingview-widget-container__widget"></div>
<script type="text/javascript" src="https://s3.tradingview.com/external-embedding/embed-widget-tickers.js">
{
"symbols": [
{
"title": "S&P 500",
"proName": "INDEX:SPX"
},
{
"title": "Nasdaq 100",
"proName": "INDEX:IUXX"
},
{
"title": "EUR/USD",
"proName": "FX_IDC:EURUSD"
},
{
"title": "BTC/USD",
"proName": "BITFINEX:BTCUSD"
},
{
"title": "ETH/USD",
"proName": "BITFINEX:ETHUSD"
},
{
"description": "Apple",
"proName": "NASDAQ:AAPL"
},
{
"description": "Berkshire",
"proName": "NYSE:BRK.A"
},
{
"description": "Microsoft",
"proName": "NASDAQ:MSFT"
},
{
"description": "Google",
"proName": "NASDAQ:GOOG"
},
{
"description": "Tesla",
"proName": "NASDAQ:TSLA"
},
{
"description": "Amazon",
"proName": "NASDAQ:AMZN"
},
{
"description": "AUD/USD",
"proName": "OANDA:AUDUSD"
},
{
"description": "Sony",
"proName": "NYSE:SNE"
},
{
"description": "BHP",
"proName": "BHP"
},
{
"description": "Telstra",
"proName": "TLS"
}
],
"locale": "en"
}
</script>
</div>
</div>
</div>
<!-- TradingView Widget END -->
<div class="content">
<p>Some text.</p>
</div>
CSS:
body {
margin: 0;
}
.content {
padding: 10px 20px;
}
.content p {
font-family: sans-serif;
}
/******/
.ticker-container {
width: 100%;
overflow: hidden;
}
.ticker-canvas {
width: calc((200px * 15) + 2px);
/*
200px = minimum width of ticker item before widget script starts removing ticker codes
15 = number of ticker codes
2px = accounts for 1px external border
*/
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-name: ticker-canvas;
animation-name: ticker-canvas;
-webkit-animation-duration: 20s;
animation-duration: 20s;
}
.ticker-canvas:hover {
animation-play-state: paused
}
@-webkit-keyframes ticker-canvas {
0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
}
@keyframes ticker-canvas {
0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
}
.tradingview-widget-container {
position: relative;
}
.tradingview-widget-container iframe {
position: absolute;
top: 0;
}
.tradingview-widget-container iframe:nth-of-type(2) {
left: 100%;
}
JS:
$( document ).ready(function() {
$( ".tradingview-widget-container iframe" ).clone().appendTo( ".tradingview-widget-container" );
});
【讨论】:
iframe DOM 中操作任何内容,除非iframe 源恰好与加载iframe 的页面位于同一域中。同源政策的Wikipedia article 列出了一些可能的例外情况,但我对所描述的任何选项都没有经验。
iframe 本身作为一个整体进行样式设置,例如对其应用变换和 CSS 过滤器有可能使其更适合您网站的样式。这是一个 OTT 示例:codepen.io/epsilon42/pen/GBvQrq
你有一点错误的问题,因为这个错误的答案。正确的问题应该是这样的:
我...想知道是否有办法:
- 让滚动条滚动 (iFrame scrolling=yes)
- 重新调整小部件的大小。
是的,小部件的滚动条滚动和调整大小是可能的,但我们不需要这个iFrame scrolling=yes。
我们用div 包裹这个iframe 并调整滚动这个div 元素的大小,而不是这个。您可以在the tradingview ticker widget site 上找到换句话说作为提示的这些信息:
描述说我可以使用 Ticker Widget 显示多达 15 个符号。为什么我只看到 5 个?
Ticker 小部件默认使用 Autosize 参数。这意味着它接受父元素的宽度。我们的演示页面足够宽,仅显示 5 个符号。您应该使父元素更宽以查看所有符号。
代码示例
function resizeWidget()
{
var containerTradingview = document.querySelector('#container-tradingview');
containerTradingview.style.maxWidth = '630px';
}
<center>
<div id="container-tradingview" style="max-width:420px;height:90px;overflow-x:auto;overflow-y:hidden">
<div style="width:2100px">
<!-- TradingView Widget BEGIN -->
<div class="tradingview-widget-container">
<div class="tradingview-widget-container__widget"></div>
<div class="tradingview-widget-copyright">
<a href="https://www.tradingview.com" rel="noopener" target="_blank">
<span class="blue-text">Quotes</span>
</a> by TradingView
</div>
<script type="text/javascript" src="https://s3.tradingview.com/external-embedding/embed-widget-tickers.js" async>
{
"symbols":
[
{"title": "S&P 500", "proName": "INDEX:SPX"},
{"title": "Nasdaq 100", "proName": "INDEX:IUXX"},
{"title": "EUR/USD", "proName": "FX_IDC:EURUSD"},
{"title": "BTC/USD", "proName": "BITFINEX:BTCUSD"},
{"title": "ETH/USD", "proName": "BITFINEX:ETHUSD"},
{"title": "Groupon Inc.", "proName": "NASDAQ:GRPN"},
{"title": "Walmart Inc.", "proName": "NYSE:WMT"},
{"title": "Amazon Inc.", "proName": "NASDAQ:AMZN"},
{"title": "Yelp Inc.", "proName": "NYSE:YELP"},
{"title": "eBay Inc", "proName": "NASDAQ:EBAY"}
],
"locale": "en"
}
</script>
</div>
<!-- TradingView Widget END -->
</div></div>
<br>
<input type="button" value="Resize widget" onclick="resizeWidget()">
</center>
您无法在 SO 上执行此小部件,因为此 sn-p 中的 iframe 位于沙箱中。
【讨论】:
据我所知,您无法修改或调整 iframe 的内容(有一个解决方法,但有点棘手);这是由于same-origin policy。 但是,您仍然可以与标签本身进行交互,因为它应该与您自己的代码具有相同的来源/域。我测试了代码并注意到 iframe 是从 tradingview 的 javascript 动态添加的。你可以做的是等待它被加载,然后添加css属性overflow=scroll。
<script type="text/javascript">
setTimeout(function() {document.querySelector("iframe").style.overflow="scroll";}, 500);
</script>
问题在于它甚至无法工作,因为 tradingview 的代码会根据窗口的宽度自动添加/删除交易对,这意味着 iframe 或交易对的容器永远不会溢出。在查看对 html 代码时尝试放大/缩小,您会看到正在发生的事情。
您的最后一个解决方案是再次查看 tradingview 的 api,以确保他们尚未实施任何滚动交易对容器的方法。如果是这样,您应该联系他们的技术支持并向他们解释您的问题。
如果您真的想要调整 iframe 的内容,从而摆脱同源策略限制,您可以使用我之前提到的服务器端解决方案 https://stackoverflow.com/a/35053713/8538711。它是使用 php 编写的,但该解决方案可能适用于其他服务器端语言。
【讨论】:
document.querySelector("iframe").setAttribute("scrolling", "yes"); 但同样,由于自动添加/删除代码以适应文档的宽度,它不应该显示任何滚动条,因为 iframe 不应该永远被它的内容所淹没。我们可能可以解决这个问题,但我们必须销毁 iframe 提供的 javascript。如果 tradingview 本身可以实现滚动代码容器的方法,显然会容易得多。
@McLeodx,afaik 我不认为你可以控制iframe,而是你可以做一些我做过的事情,请看看下面的工作示例或here(codepen link),希望它有所帮助:)
.container-outer {
max-width: 960px;
/* update the width of the display contaier as per your requirement */
}
.container-width {
width: 3000px;
/* Total width of the whole iframe, based on the number of tickers displaying */
}
<!-- -->
.container-outer {
margin: 0 auto;
max-width: 960px;
position: relative;
box-shadow: inset 0 43px 0 0 #eee;
border-bottom: 1px solid #ccc;
height: 71px;
overflow: hidden;
}
.container-outer:before,
.container-outer:after {
top: 0;
width: 1px;
height: 100%;
content: '';
position: absolute;
}
.container-outer:before {
border-left: 1px solid #ccc;
}
.container-outer:after {
right: 0;
border-right: 1px solid #ccc;
}
.container-inner {
overflow-x: auto;
overflow-y: hidden;
height: 100px;
}
.shadow-left:before,
.shadow-right:after {
width: 20px;
}
.shadow-left:before {
background: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.15)), to(transparent));
background: linear-gradient(to right, rgba(0, 0, 0, 0.15) 0%, transparent 100%);
}
.shadow-right:after {
background: -webkit-gradient(linear, right top, left top, from(rgba(0, 0, 0, 0.15)), to(transparent));
background: linear-gradient(to left, rgba(0, 0, 0, 0.15) 0%, transparent 100%);
right: 0;
}
<div class="container-outer">
<div class="container-inner">
<div class="container-width">
<!-- TradingView Widget BEGIN -->
<div class="tradingview-widget-container">
<div class="tradingview-widget-container__widget"></div>
<div class="tradingview-widget-copyright">
<a href="https://www.tradingview.com" rel="noopener" target="_blank">
<span class="blue-text">Quotes</span>
</a> by TradingView
</div>
<script type="text/javascript" src="https://s3.tradingview.com/external-embedding/embed-widget-tickers.js" async>
{
"symbols": [
{
"title": "S&P 500",
"proName": "INDEX:SPX"
},
{
"title": "Nasdaq 100",
"proName": "INDEX:IUXX"
},
{
"title": "EUR/USD",
"proName": "FX_IDC:EURUSD"
},
{
"title": "BTC/USD",
"proName": "BITFINEX:BTCUSD"
},
{
"title": "ETH/USD",
"proName": "BITFINEX:ETHUSD"
},
{
"title": "S&P 500",
"proName": "INDEX:SPX"
},
{
"title": "Nasdaq 100",
"proName": "INDEX:IUXX"
},
{
"title": "EUR/USD",
"proName": "FX_IDC:EURUSD"
},
{
"title": "BTC/USD",
"proName": "BITFINEX:BTCUSD"
},
{
"title": "ETH/USD",
"proName": "BITFINEX:ETHUSD"
},
{
"title": "S&P 500",
"proName": "INDEX:SPX"
},
{
"title": "Nasdaq 100",
"proName": "INDEX:IUXX"
},
{
"title": "EUR/USD",
"proName": "FX_IDC:EURUSD"
},
{
"title": "BTC/USD",
"proName": "BITFINEX:BTCUSD"
},
{
"title": "ETH/USD",
"proName": "BITFINEX:ETHUSD"
}
],
"locale": "en"
}
</script>
</div>
<!-- TradingView Widget END -->
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
// Scroll Shadow
$(document).ready(function() {
$(".container-inner").on("scroll", function () {
var cur = $(this).scrollLeft();
if (cur == 0) {
$('.container-outer').addClass('shadow-right').removeClass('shadow-left');
}
else {
var max = $(this)[0].scrollWidth - $(this).parent().width();
if (cur == max) {
$('.container-outer').addClass('shadow-left').removeClass('shadow-right');
} else {
$('.container-outer').addClass('shadow-right shadow-left');
}
}
});
$(".container-inner").trigger("scroll");
});
</script>
【讨论】:
Run code snippet 没有正确显示结果:(,您可以检查codepen 链接,它工作正常-codepen.io/girish/pen/Epmrba