最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Executing a <script> tag on append after the DOM has loaded - Stack Overflow

programmeradmin2浏览0评论

I'm trying to watch videos onClick in a modal without having to visit the video pages themselves.

I'm using Vue.js and through a series of Ajax calls I am able to get most of the way there.

Codpen:

If you click "vs Suns" at top, you get a listing of all video posts. Then clicking any of the images, the modal ponent pops up and takes in the title of the post dynamically.

I want to run a video in there as well so I try to run this script tag:

 < script class="_nbaVideoPlayerScout" data-team="warriors" data-videoId="/video/{{unique videoId from post ajax call}}" data-width="768" data-height="732" src=".js"></script>

When the modal pops up, I see the correct title of the post/image I clicked on, and I see the script tag exactly as it should be in the inspector, but the script tag never runs.

Is there some different way I should be injecting this script than this? (This is inside the axios response call)

let theVideoId = response.data.content[0].videoID


let s = document.createElement('script')
s.setAttribute('class', '_nbaVideoPlayerScout')
s.setAttribute('data-team', 'warriors') 
s.setAttribute('data-videoId', '/video/' + theVideoId) 
s.setAttribute('data-width', '768') 
s.setAttribute('data-height', '732') 
s.setAttribute('src', '.js')
document.getElementById('popupVideo').appendChild(s);

MODAL COMPONENT -- Fired on the click of one of the post thumbnails

const videoModal = Vueponent('VideoModal', {
props: {
    id: {
    type: String,
    required: true
    }
},
data: function () {
  return {
    post: [],
  }
},
mounted() {
  const singleApi = '.nba/warriors/api/1.1/json?textformat=html&nid='
  axios.get(singleApi + this.id).then((response) => {
    this.post = response.data.content[0]
    console.log('THE RESPONSE', response)

    let theVideoId = response.data.content[0].videoID


let s = document.createElement('script')
s.setAttribute('class', '_nbaVideoPlayerScout')
s.setAttribute('data-team', 'warriors') 
s.setAttribute('data-videoId', '/video/' + theVideoId) 
s.setAttribute('data-width', '768') 
s.setAttribute('data-height', '732') 
s.setAttribute('src', '.js')
document.getElementById('popupVideo').appendChild(s);
  }).catch((error) => {
    console.log(error)
  })

},
methods: {
  goBack: function () {
    router.go(-1)
  }
},
template:`<div>
<div id="video-popup">
  <button class="close-video-popup" @click="goBack">close me</button>
  <div class="video-popup-wrapper">
    <div class="video-popup--title">{{post.title}}</div>
    <div class="video-popup--video" id="popupVideo"></div>
  <div class="video-popup--share"></div>
</div>
</div>
</div>`
})

I'm trying to watch videos onClick in a modal without having to visit the video pages themselves.

I'm using Vue.js and through a series of Ajax calls I am able to get most of the way there.

Codpen: https://codepen.io/nolaandy/pen/BrbBzO

If you click "vs Suns" at top, you get a listing of all video posts. Then clicking any of the images, the modal ponent pops up and takes in the title of the post dynamically.

I want to run a video in there as well so I try to run this script tag:

 < script class="_nbaVideoPlayerScout" data-team="warriors" data-videoId="/video/{{unique videoId from post ajax call}}" data-width="768" data-height="732" src="https://www.nba./scout/team/cvp/videoPlayerScout.js"></script>

When the modal pops up, I see the correct title of the post/image I clicked on, and I see the script tag exactly as it should be in the inspector, but the script tag never runs.

Is there some different way I should be injecting this script than this? (This is inside the axios response call)

let theVideoId = response.data.content[0].videoID


let s = document.createElement('script')
s.setAttribute('class', '_nbaVideoPlayerScout')
s.setAttribute('data-team', 'warriors') 
s.setAttribute('data-videoId', '/video/' + theVideoId) 
s.setAttribute('data-width', '768') 
s.setAttribute('data-height', '732') 
s.setAttribute('src', 'https://www.nba./scout/team/cvp/videoPlayerScout.js')
document.getElementById('popupVideo').appendChild(s);

MODAL COMPONENT -- Fired on the click of one of the post thumbnails

const videoModal = Vue.ponent('VideoModal', {
props: {
    id: {
    type: String,
    required: true
    }
},
data: function () {
  return {
    post: [],
  }
},
mounted() {
  const singleApi = 'https://cors-anywhere.herokuapp./www.nba./warriors/api/1.1/json?textformat=html&nid='
  axios.get(singleApi + this.id).then((response) => {
    this.post = response.data.content[0]
    console.log('THE RESPONSE', response)

    let theVideoId = response.data.content[0].videoID


let s = document.createElement('script')
s.setAttribute('class', '_nbaVideoPlayerScout')
s.setAttribute('data-team', 'warriors') 
s.setAttribute('data-videoId', '/video/' + theVideoId) 
s.setAttribute('data-width', '768') 
s.setAttribute('data-height', '732') 
s.setAttribute('src', 'https://www.nba./scout/team/cvp/videoPlayerScout.js')
document.getElementById('popupVideo').appendChild(s);
  }).catch((error) => {
    console.log(error)
  })

},
methods: {
  goBack: function () {
    router.go(-1)
  }
},
template:`<div>
<div id="video-popup">
  <button class="close-video-popup" @click="goBack">close me</button>
  <div class="video-popup-wrapper">
    <div class="video-popup--title">{{post.title}}</div>
    <div class="video-popup--video" id="popupVideo"></div>
  <div class="video-popup--share"></div>
</div>
</div>
</div>`
})
Share Improve this question asked Apr 10, 2018 at 19:08 4ndy4ndy 4588 silver badges27 bronze badges 6
  • this answer might help you stackoverflow./a/8578840/1309377 – Andrew L Commented Apr 10, 2018 at 19:28
  • I wish that worked but I get the same thing. Script added but nothing is run. – 4ndy Commented Apr 10, 2018 at 19:46
  • It's crazy because if I add a script with an alert in it, I get the alert popup: var s = document.createElement('script') s.type = 'text/javascript' var code = 'alert("'+theVideoId+'");' try { s.appendChild(document.createTextNode(code)); document.getElementById('scriptMe').appendChild(s); } catch (e) { s.text = code; document.getElementById('scriptMe').appendChild(s); } – 4ndy Commented Apr 10, 2018 at 21:16
  • are there any errors in the dev console? What do you expect to happen when you load this script? – Andrew L Commented Apr 10, 2018 at 21:22
  • I'm trying to show a video. No errors at this time. If you add this script tag into a codepen you will see the video popup: <script class="_nbaVideoPlayerScout" data-team="warriors" data-videoId="/video/teams/warriors/2018/04/09/2041192/1523301309011-shorts-phx-2041192" data-width="768" data-height="732" src="nba./scout/team/cvp/videoPlayerScout.js">< / script> I can inject this exact script but I don't get the video. – 4ndy Commented Apr 10, 2018 at 21:33
 |  Show 1 more ment

1 Answer 1

Reset to default 6

On a whim I made this change:

// document.getElementById('scriptMe').appendChild(s);
document.body.appendChild(s);

and boom, script runs and video loads.

Which is super interesting, because "why", right?

Edit: In addition, trying other script injection methods discussed here.

document.write method

document.write(s.outerHTML) // s is a script node

also works. In fact, you can embed that script node in a div and it works as well.

createContextualFragment method

// var $container = document.getElementById('scriptMe'); // does not work
var $container = document.body
var range = document.createRange()
$container.appendChild(range.createContextualFragment(script_str))

works, where script_str is an html string literal. This will work both as "<script>....</script>" or "<div id="myDiv"><script>...</script></div>"

but all the methods I tested ultimately needed injection to be done in body.

codepen

发布评论

评论列表(0)

  1. 暂无评论