最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

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

matteradmin6PV0评论

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

Post a comment

comment list (0)

  1. No comments so far